calc-alg.el 71 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921
  1. ;;; calc-alg.el --- algebraic functions for Calc
  2. ;; Copyright (C) 1990-1993, 2001-2015 Free Software Foundation, Inc.
  3. ;; Author: David Gillespie <daveg@synaptics.com>
  4. ;; Maintainer: Jay Belanger <jay.p.belanger@gmail.com>
  5. ;; This file is part of GNU Emacs.
  6. ;; GNU Emacs is free software: you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation, either version 3 of the License, or
  9. ;; (at your option) any later version.
  10. ;; GNU Emacs is distributed in the hope that it will be useful,
  11. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ;; GNU General Public License for more details.
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  16. ;;; Commentary:
  17. ;;; Code:
  18. ;; This file is autoloaded from calc-ext.el.
  19. (require 'calc-ext)
  20. (require 'calc-macs)
  21. ;;; Algebra commands.
  22. (defun calc-alg-evaluate (arg)
  23. (interactive "p")
  24. (calc-slow-wrapper
  25. (calc-with-default-simplification
  26. (let ((math-simplify-only nil))
  27. (calc-modify-simplify-mode arg)
  28. (calc-enter-result 1 "dsmp" (calc-top 1))))))
  29. (defun calc-modify-simplify-mode (arg)
  30. (if (= (math-abs arg) 2)
  31. (setq calc-simplify-mode 'alg)
  32. (if (>= (math-abs arg) 3)
  33. (setq calc-simplify-mode 'ext)))
  34. (if (< arg 0)
  35. (setq calc-simplify-mode (list calc-simplify-mode))))
  36. (defun calc-simplify ()
  37. (interactive)
  38. (calc-slow-wrapper
  39. (let ((top (calc-top-n 1)))
  40. (if (calc-is-inverse)
  41. (setq top
  42. (let ((calc-simplify-mode nil))
  43. (math-normalize (math-trig-rewrite top)))))
  44. (if (calc-is-hyperbolic)
  45. (setq top
  46. (let ((calc-simplify-mode nil))
  47. (math-normalize (math-hyperbolic-trig-rewrite top)))))
  48. (calc-with-default-simplification
  49. (calc-enter-result 1 "simp" (math-simplify top))))))
  50. (defun calc-simplify-extended ()
  51. (interactive)
  52. (calc-slow-wrapper
  53. (calc-with-default-simplification
  54. (calc-enter-result 1 "esmp" (math-simplify-extended (calc-top-n 1))))))
  55. (defun calc-expand-formula (arg)
  56. (interactive "p")
  57. (calc-slow-wrapper
  58. (calc-with-default-simplification
  59. (let ((math-simplify-only nil))
  60. (calc-modify-simplify-mode arg)
  61. (calc-enter-result 1 "expf"
  62. (if (> arg 0)
  63. (let ((math-expand-formulas t))
  64. (calc-top-n 1))
  65. (let ((top (calc-top-n 1)))
  66. (or (math-expand-formula top)
  67. top))))))))
  68. (defun calc-factor (arg)
  69. (interactive "P")
  70. (calc-slow-wrapper
  71. (calc-unary-op "fctr" (if (calc-is-hyperbolic)
  72. 'calcFunc-factors 'calcFunc-factor)
  73. arg)))
  74. (defun calc-expand (n)
  75. (interactive "P")
  76. (calc-slow-wrapper
  77. (calc-enter-result 1 "expa"
  78. (append (list 'calcFunc-expand
  79. (calc-top-n 1))
  80. (and n (list (prefix-numeric-value n)))))))
  81. ;;; Write out powers (a*b*...)^n as a*b*...*a*b*...
  82. (defun calcFunc-powerexpand (expr)
  83. (math-normalize (math-map-tree 'math-powerexpand expr)))
  84. (defun math-powerexpand (expr)
  85. (if (eq (car-safe expr) '^)
  86. (let ((n (nth 2 expr)))
  87. (cond ((and (integerp n)
  88. (> n 0))
  89. (let ((i 1)
  90. (a (nth 1 expr))
  91. (prod (nth 1 expr)))
  92. (while (< i n)
  93. (setq prod (math-mul prod a))
  94. (setq i (1+ i)))
  95. prod))
  96. ((and (integerp n)
  97. (< n 0))
  98. (let ((i -1)
  99. (a (math-pow (nth 1 expr) -1))
  100. (prod (math-pow (nth 1 expr) -1)))
  101. (while (> i n)
  102. (setq prod (math-mul a prod))
  103. (setq i (1- i)))
  104. prod))
  105. (t
  106. expr)))
  107. expr))
  108. (defun calc-powerexpand ()
  109. (interactive)
  110. (calc-slow-wrapper
  111. (calc-enter-result 1 "pexp"
  112. (calcFunc-powerexpand (calc-top-n 1)))))
  113. (defun calc-collect (&optional var)
  114. (interactive "sCollect terms involving: ")
  115. (calc-slow-wrapper
  116. (if (or (equal var "") (equal var "$") (null var))
  117. (calc-enter-result 2 "clct" (cons 'calcFunc-collect
  118. (calc-top-list-n 2)))
  119. (let ((var (math-read-expr var)))
  120. (if (eq (car-safe var) 'error)
  121. (error "Bad format in expression: %s" (nth 1 var)))
  122. (calc-enter-result 1 "clct" (list 'calcFunc-collect
  123. (calc-top-n 1)
  124. var))))))
  125. (defun calc-apart (arg)
  126. (interactive "P")
  127. (calc-slow-wrapper
  128. (calc-unary-op "aprt" 'calcFunc-apart arg)))
  129. (defun calc-normalize-rat (arg)
  130. (interactive "P")
  131. (calc-slow-wrapper
  132. (calc-unary-op "nrat" 'calcFunc-nrat arg)))
  133. (defun calc-poly-gcd (arg)
  134. (interactive "P")
  135. (calc-slow-wrapper
  136. (calc-binary-op "pgcd" 'calcFunc-pgcd arg)))
  137. (defun calc-poly-div (arg)
  138. (interactive "P")
  139. (calc-slow-wrapper
  140. (let ((calc-poly-div-remainder nil))
  141. (calc-binary-op "pdiv" 'calcFunc-pdiv arg)
  142. (if (and calc-poly-div-remainder (null arg))
  143. (progn
  144. (calc-clear-command-flag 'clear-message)
  145. (calc-record calc-poly-div-remainder "prem")
  146. (if (not (Math-zerop calc-poly-div-remainder))
  147. (message "(Remainder was %s)"
  148. (math-format-flat-expr calc-poly-div-remainder 0))
  149. (message "(No remainder)")))))))
  150. (defun calc-poly-rem (arg)
  151. (interactive "P")
  152. (calc-slow-wrapper
  153. (calc-binary-op "prem" 'calcFunc-prem arg)))
  154. (defun calc-poly-div-rem (arg)
  155. (interactive "P")
  156. (calc-slow-wrapper
  157. (if (calc-is-hyperbolic)
  158. (calc-binary-op "pdvr" 'calcFunc-pdivide arg)
  159. (calc-binary-op "pdvr" 'calcFunc-pdivrem arg))))
  160. (defun calc-substitute (&optional oldname newname)
  161. (interactive "sSubstitute old: ")
  162. (calc-slow-wrapper
  163. (let (old new (num 1) expr)
  164. (if (or (equal oldname "") (equal oldname "$") (null oldname))
  165. (setq new (calc-top-n 1)
  166. old (calc-top-n 2)
  167. expr (calc-top-n 3)
  168. num 3)
  169. (or newname
  170. (progn (calc-unread-command ?\C-a)
  171. (setq newname (read-string (concat "Substitute old: "
  172. oldname
  173. ", new: ")
  174. oldname))))
  175. (if (or (equal newname "") (equal newname "$") (null newname))
  176. (setq new (calc-top-n 1)
  177. expr (calc-top-n 2)
  178. num 2)
  179. (setq new (if (stringp newname) (math-read-expr newname) newname))
  180. (if (eq (car-safe new) 'error)
  181. (error "Bad format in expression: %s" (nth 1 new)))
  182. (setq expr (calc-top-n 1)))
  183. (setq old (if (stringp oldname) (math-read-expr oldname) oldname))
  184. (if (eq (car-safe old) 'error)
  185. (error "Bad format in expression: %s" (nth 1 old)))
  186. (or (math-expr-contains expr old)
  187. (error "No occurrences found")))
  188. (calc-enter-result num "sbst" (math-expr-subst expr old new)))))
  189. (defun calc-has-rules (name)
  190. (setq name (calc-var-value name))
  191. (and (consp name)
  192. (memq (car name) '(vec calcFunc-assign calcFunc-condition))
  193. name))
  194. ;; math-eval-rules-cache and math-eval-rules-cache-other are
  195. ;; declared in calc.el, but are used here by math-recompile-eval-rules.
  196. (defvar math-eval-rules-cache)
  197. (defvar math-eval-rules-cache-other)
  198. (defun math-recompile-eval-rules ()
  199. (setq math-eval-rules-cache (and (calc-has-rules 'var-EvalRules)
  200. (math-compile-rewrites
  201. '(var EvalRules var-EvalRules)))
  202. math-eval-rules-cache-other (assq nil math-eval-rules-cache)
  203. math-eval-rules-cache-tag (calc-var-value 'var-EvalRules)))
  204. ;;; Try to expand a formula according to its definition.
  205. (defun math-expand-formula (expr)
  206. (and (consp expr)
  207. (symbolp (car expr))
  208. (or (get (car expr) 'calc-user-defn)
  209. (get (car expr) 'math-expandable))
  210. (let ((res (let ((math-expand-formulas t))
  211. (apply (car expr) (cdr expr)))))
  212. (and (not (eq (car-safe res) (car expr)))
  213. res))))
  214. ;;; True if A comes before B in a canonical ordering of expressions. [P X X]
  215. (defun math-beforep (a b) ; [Public]
  216. (cond ((and (Math-realp a) (Math-realp b))
  217. (let ((comp (math-compare a b)))
  218. (or (eq comp -1)
  219. (and (eq comp 0)
  220. (not (equal a b))
  221. (> (length (memq (car-safe a)
  222. '(bigneg nil bigpos frac float)))
  223. (length (memq (car-safe b)
  224. '(bigneg nil bigpos frac float))))))))
  225. ((equal b '(neg (var inf var-inf))) nil)
  226. ((equal a '(neg (var inf var-inf))) t)
  227. ((equal a '(var inf var-inf)) nil)
  228. ((equal b '(var inf var-inf)) t)
  229. ((Math-realp a)
  230. (if (and (eq (car-safe b) 'intv) (math-intv-constp b))
  231. (if (or (math-beforep a (nth 2 b)) (Math-equal a (nth 2 b)))
  232. t
  233. nil)
  234. t))
  235. ((Math-realp b)
  236. (if (and (eq (car-safe a) 'intv) (math-intv-constp a))
  237. (if (math-beforep (nth 2 a) b)
  238. t
  239. nil)
  240. nil))
  241. ((and (eq (car a) 'intv) (eq (car b) 'intv)
  242. (math-intv-constp a) (math-intv-constp b))
  243. (let ((comp (math-compare (nth 2 a) (nth 2 b))))
  244. (cond ((eq comp -1) t)
  245. ((eq comp 1) nil)
  246. ((and (memq (nth 1 a) '(2 3)) (memq (nth 1 b) '(0 1))) t)
  247. ((and (memq (nth 1 a) '(0 1)) (memq (nth 1 b) '(2 3))) nil)
  248. ((eq (setq comp (math-compare (nth 3 a) (nth 3 b))) -1) t)
  249. ((eq comp 1) nil)
  250. ((and (memq (nth 1 a) '(0 2)) (memq (nth 1 b) '(1 3))) t)
  251. (t nil))))
  252. ((not (eq (not (Math-objectp a)) (not (Math-objectp b))))
  253. (Math-objectp a))
  254. ((eq (car a) 'var)
  255. (if (eq (car b) 'var)
  256. (string-lessp (nth 1 a) (nth 1 b))
  257. (not (Math-numberp b))))
  258. ((eq (car b) 'var) (Math-numberp a))
  259. ((eq (car a) (car b))
  260. (while (and (setq a (cdr a) b (cdr b)) a
  261. (equal (car a) (car b))))
  262. (and b
  263. (or (null a)
  264. (math-beforep (car a) (car b)))))
  265. (t (string-lessp (car a) (car b)))))
  266. (defsubst math-simplify-extended (a)
  267. (let ((math-living-dangerously t))
  268. (math-simplify a)))
  269. (defalias 'calcFunc-esimplify 'math-simplify-extended)
  270. ;;; Rewrite the trig functions in a form easier to simplify.
  271. (defun math-trig-rewrite (fn)
  272. "Rewrite trigonometric functions in terms of sines and cosines."
  273. (cond
  274. ((not (consp fn))
  275. fn)
  276. ((eq (car-safe fn) 'calcFunc-sec)
  277. (list '/ 1 (cons 'calcFunc-cos (math-trig-rewrite (cdr fn)))))
  278. ((eq (car-safe fn) 'calcFunc-csc)
  279. (list '/ 1 (cons 'calcFunc-sin (math-trig-rewrite (cdr fn)))))
  280. ((eq (car-safe fn) 'calcFunc-tan)
  281. (let ((newfn (math-trig-rewrite (cdr fn))))
  282. (list '/ (cons 'calcFunc-sin newfn)
  283. (cons 'calcFunc-cos newfn))))
  284. ((eq (car-safe fn) 'calcFunc-cot)
  285. (let ((newfn (math-trig-rewrite (cdr fn))))
  286. (list '/ (cons 'calcFunc-cos newfn)
  287. (cons 'calcFunc-sin newfn))))
  288. (t
  289. (mapcar 'math-trig-rewrite fn))))
  290. (defun math-hyperbolic-trig-rewrite (fn)
  291. "Rewrite hyperbolic functions in terms of sinhs and coshs."
  292. (cond
  293. ((not (consp fn))
  294. fn)
  295. ((eq (car-safe fn) 'calcFunc-sech)
  296. (list '/ 1 (cons 'calcFunc-cosh (math-hyperbolic-trig-rewrite (cdr fn)))))
  297. ((eq (car-safe fn) 'calcFunc-csch)
  298. (list '/ 1 (cons 'calcFunc-sinh (math-hyperbolic-trig-rewrite (cdr fn)))))
  299. ((eq (car-safe fn) 'calcFunc-tanh)
  300. (let ((newfn (math-hyperbolic-trig-rewrite (cdr fn))))
  301. (list '/ (cons 'calcFunc-sinh newfn)
  302. (cons 'calcFunc-cosh newfn))))
  303. ((eq (car-safe fn) 'calcFunc-coth)
  304. (let ((newfn (math-hyperbolic-trig-rewrite (cdr fn))))
  305. (list '/ (cons 'calcFunc-cosh newfn)
  306. (cons 'calcFunc-sinh newfn))))
  307. (t
  308. (mapcar 'math-hyperbolic-trig-rewrite fn))))
  309. ;; math-top-only is local to math-simplify, but is used by
  310. ;; math-simplify-step, which is called by math-simplify.
  311. (defvar math-top-only)
  312. ;; math-normalize-error is declared in calc.el.
  313. (defvar math-normalize-error)
  314. (defun math-simplify (top-expr)
  315. (let ((math-simplifying t)
  316. (math-top-only (consp calc-simplify-mode))
  317. (simp-rules (append (and (calc-has-rules 'var-AlgSimpRules)
  318. '((var AlgSimpRules var-AlgSimpRules)))
  319. (and math-living-dangerously
  320. (calc-has-rules 'var-ExtSimpRules)
  321. '((var ExtSimpRules var-ExtSimpRules)))
  322. (and math-simplifying-units
  323. (calc-has-rules 'var-UnitSimpRules)
  324. '((var UnitSimpRules var-UnitSimpRules)))
  325. (and math-integrating
  326. (calc-has-rules 'var-IntegSimpRules)
  327. '((var IntegSimpRules var-IntegSimpRules)))))
  328. res)
  329. (if math-top-only
  330. (let ((r simp-rules))
  331. (setq res (math-simplify-step (math-normalize top-expr))
  332. calc-simplify-mode '(nil)
  333. top-expr (math-normalize res))
  334. (while r
  335. (setq top-expr (math-rewrite top-expr (car r)
  336. '(neg (var inf var-inf)))
  337. r (cdr r))))
  338. (calc-with-default-simplification
  339. (while (let ((r simp-rules))
  340. (setq res (math-normalize top-expr))
  341. (if (not math-normalize-error)
  342. (progn
  343. (while r
  344. (setq res (math-rewrite res (car r))
  345. r (cdr r)))
  346. (not (equal top-expr (setq res (math-simplify-step res)))))))
  347. (setq top-expr res)))))
  348. top-expr)
  349. (defalias 'calcFunc-simplify 'math-simplify)
  350. ;;; The following has a "bug" in that if any recursive simplifications
  351. ;;; occur only the first handler will be tried; this doesn't really
  352. ;;; matter, since math-simplify-step is iterated to a fixed point anyway.
  353. (defun math-simplify-step (a)
  354. (if (Math-primp a)
  355. a
  356. (let ((aa (if (or math-top-only
  357. (memq (car a) '(calcFunc-quote calcFunc-condition
  358. calcFunc-evalto)))
  359. a
  360. (cons (car a) (mapcar 'math-simplify-step (cdr a))))))
  361. (and (symbolp (car aa))
  362. (let ((handler (get (car aa) 'math-simplify)))
  363. (and handler
  364. (while (and handler
  365. (equal (setq aa (or (funcall (car handler) aa)
  366. aa))
  367. a))
  368. (setq handler (cdr handler))))))
  369. aa)))
  370. (defmacro math-defsimplify (funcs &rest code)
  371. (cons 'progn
  372. (mapcar #'(lambda (func)
  373. `(put ',func 'math-simplify
  374. (nconc
  375. (get ',func 'math-simplify)
  376. (list
  377. #'(lambda (math-simplify-expr) ,@code)))))
  378. (if (symbolp funcs) (list funcs) funcs))))
  379. (put 'math-defsimplify 'lisp-indent-hook 1)
  380. ;; The function created by math-defsimplify uses the variable
  381. ;; math-simplify-expr, and so is used by functions in math-defsimplify
  382. (defvar math-simplify-expr)
  383. (math-defsimplify (+ -)
  384. (math-simplify-plus))
  385. (defun math-simplify-plus ()
  386. (cond ((and (memq (car-safe (nth 1 math-simplify-expr)) '(+ -))
  387. (Math-numberp (nth 2 (nth 1 math-simplify-expr)))
  388. (not (Math-numberp (nth 2 math-simplify-expr))))
  389. (let ((x (nth 2 math-simplify-expr))
  390. (op (car math-simplify-expr)))
  391. (setcar (cdr (cdr math-simplify-expr)) (nth 2 (nth 1 math-simplify-expr)))
  392. (setcar math-simplify-expr (car (nth 1 math-simplify-expr)))
  393. (setcar (cdr (cdr (nth 1 math-simplify-expr))) x)
  394. (setcar (nth 1 math-simplify-expr) op)))
  395. ((and (eq (car math-simplify-expr) '+)
  396. (Math-numberp (nth 1 math-simplify-expr))
  397. (not (Math-numberp (nth 2 math-simplify-expr))))
  398. (let ((x (nth 2 math-simplify-expr)))
  399. (setcar (cdr (cdr math-simplify-expr)) (nth 1 math-simplify-expr))
  400. (setcar (cdr math-simplify-expr) x))))
  401. (let ((aa math-simplify-expr)
  402. aaa temp)
  403. (while (memq (car-safe (setq aaa (nth 1 aa))) '(+ -))
  404. (if (setq temp (math-combine-sum (nth 2 aaa) (nth 2 math-simplify-expr)
  405. (eq (car aaa) '-)
  406. (eq (car math-simplify-expr) '-) t))
  407. (progn
  408. (setcar (cdr (cdr math-simplify-expr)) temp)
  409. (setcar math-simplify-expr '+)
  410. (setcar (cdr (cdr aaa)) 0)))
  411. (setq aa (nth 1 aa)))
  412. (if (setq temp (math-combine-sum aaa (nth 2 math-simplify-expr)
  413. nil (eq (car math-simplify-expr) '-) t))
  414. (progn
  415. (setcar (cdr (cdr math-simplify-expr)) temp)
  416. (setcar math-simplify-expr '+)
  417. (setcar (cdr aa) 0)))
  418. math-simplify-expr))
  419. (math-defsimplify *
  420. (math-simplify-times))
  421. (defun math-simplify-times ()
  422. (if (eq (car-safe (nth 2 math-simplify-expr)) '*)
  423. (and (math-beforep (nth 1 (nth 2 math-simplify-expr)) (nth 1 math-simplify-expr))
  424. (or (math-known-scalarp (nth 1 math-simplify-expr) t)
  425. (math-known-scalarp (nth 1 (nth 2 math-simplify-expr)) t))
  426. (let ((x (nth 1 math-simplify-expr)))
  427. (setcar (cdr math-simplify-expr) (nth 1 (nth 2 math-simplify-expr)))
  428. (setcar (cdr (nth 2 math-simplify-expr)) x)))
  429. (and (math-beforep (nth 2 math-simplify-expr) (nth 1 math-simplify-expr))
  430. (or (math-known-scalarp (nth 1 math-simplify-expr) t)
  431. (math-known-scalarp (nth 2 math-simplify-expr) t))
  432. (let ((x (nth 2 math-simplify-expr)))
  433. (setcar (cdr (cdr math-simplify-expr)) (nth 1 math-simplify-expr))
  434. (setcar (cdr math-simplify-expr) x))))
  435. (let ((aa math-simplify-expr)
  436. aaa temp
  437. (safe t) (scalar (math-known-scalarp (nth 1 math-simplify-expr))))
  438. (if (and (Math-ratp (nth 1 math-simplify-expr))
  439. (setq temp (math-common-constant-factor (nth 2 math-simplify-expr))))
  440. (progn
  441. (setcar (cdr (cdr math-simplify-expr))
  442. (math-cancel-common-factor (nth 2 math-simplify-expr) temp))
  443. (setcar (cdr math-simplify-expr) (math-mul (nth 1 math-simplify-expr) temp))))
  444. (while (and (eq (car-safe (setq aaa (nth 2 aa))) '*)
  445. safe)
  446. (if (setq temp (math-combine-prod (nth 1 math-simplify-expr)
  447. (nth 1 aaa) nil nil t))
  448. (progn
  449. (setcar (cdr math-simplify-expr) temp)
  450. (setcar (cdr aaa) 1)))
  451. (setq safe (or scalar (math-known-scalarp (nth 1 aaa) t))
  452. aa (nth 2 aa)))
  453. (if (and (setq temp (math-combine-prod aaa (nth 1 math-simplify-expr) nil nil t))
  454. safe)
  455. (progn
  456. (setcar (cdr math-simplify-expr) temp)
  457. (setcar (cdr (cdr aa)) 1)))
  458. (if (and (eq (car-safe (nth 1 math-simplify-expr)) 'frac)
  459. (memq (nth 1 (nth 1 math-simplify-expr)) '(1 -1)))
  460. (math-div (math-mul (nth 2 math-simplify-expr)
  461. (nth 1 (nth 1 math-simplify-expr)))
  462. (nth 2 (nth 1 math-simplify-expr)))
  463. math-simplify-expr)))
  464. (math-defsimplify /
  465. (math-simplify-divide))
  466. (defun math-simplify-divide ()
  467. (let ((np (cdr math-simplify-expr))
  468. (nover nil)
  469. (nn (and (or (eq (car math-simplify-expr) '/)
  470. (not (Math-realp (nth 2 math-simplify-expr))))
  471. (math-common-constant-factor (nth 2 math-simplify-expr))))
  472. n op)
  473. (if nn
  474. (progn
  475. (setq n (and (or (eq (car math-simplify-expr) '/)
  476. (not (Math-realp (nth 1 math-simplify-expr))))
  477. (math-common-constant-factor (nth 1 math-simplify-expr))))
  478. (if (and (eq (car-safe nn) 'frac) (eq (nth 1 nn) 1) (not n))
  479. (unless (and (eq (car-safe math-simplify-expr) 'calcFunc-eq)
  480. (eq (car-safe (nth 1 math-simplify-expr)) 'var)
  481. (not (math-expr-contains (nth 2 math-simplify-expr)
  482. (nth 1 math-simplify-expr))))
  483. (setcar (cdr math-simplify-expr)
  484. (math-mul (nth 2 nn) (nth 1 math-simplify-expr)))
  485. (setcar (cdr (cdr math-simplify-expr))
  486. (math-cancel-common-factor (nth 2 math-simplify-expr) nn))
  487. (if (and (math-negp nn)
  488. (setq op (assq (car math-simplify-expr) calc-tweak-eqn-table)))
  489. (setcar math-simplify-expr (nth 1 op))))
  490. (if (and n (not (eq (setq n (math-frac-gcd n nn)) 1)))
  491. (progn
  492. (setcar (cdr math-simplify-expr)
  493. (math-cancel-common-factor (nth 1 math-simplify-expr) n))
  494. (setcar (cdr (cdr math-simplify-expr))
  495. (math-cancel-common-factor (nth 2 math-simplify-expr) n))
  496. (if (and (math-negp n)
  497. (setq op (assq (car math-simplify-expr)
  498. calc-tweak-eqn-table)))
  499. (setcar math-simplify-expr (nth 1 op))))))))
  500. (if (and (eq (car-safe (car np)) '/)
  501. (math-known-scalarp (nth 2 math-simplify-expr) t))
  502. (progn
  503. (setq np (cdr (nth 1 math-simplify-expr)))
  504. (while (eq (car-safe (setq n (car np))) '*)
  505. (and (math-known-scalarp (nth 2 n) t)
  506. (math-simplify-divisor (cdr n) (cdr (cdr math-simplify-expr)) nil t))
  507. (setq np (cdr (cdr n))))
  508. (math-simplify-divisor np (cdr (cdr math-simplify-expr)) nil t)
  509. (setq nover t
  510. np (cdr (cdr (nth 1 math-simplify-expr))))))
  511. (while (eq (car-safe (setq n (car np))) '*)
  512. (and (math-known-scalarp (nth 2 n) t)
  513. (math-simplify-divisor (cdr n) (cdr (cdr math-simplify-expr)) nover t))
  514. (setq np (cdr (cdr n))))
  515. (math-simplify-divisor np (cdr (cdr math-simplify-expr)) nover t)
  516. math-simplify-expr))
  517. ;; The variables math-simplify-divisor-nover and math-simplify-divisor-dover
  518. ;; are local variables for math-simplify-divisor, but are used by
  519. ;; math-simplify-one-divisor.
  520. (defvar math-simplify-divisor-nover)
  521. (defvar math-simplify-divisor-dover)
  522. (defun math-simplify-divisor (np dp math-simplify-divisor-nover
  523. math-simplify-divisor-dover)
  524. (cond ((eq (car-safe (car dp)) '/)
  525. (math-simplify-divisor np (cdr (car dp))
  526. math-simplify-divisor-nover
  527. math-simplify-divisor-dover)
  528. (and (math-known-scalarp (nth 1 (car dp)) t)
  529. (math-simplify-divisor np (cdr (cdr (car dp)))
  530. math-simplify-divisor-nover
  531. (not math-simplify-divisor-dover))))
  532. ((or (or (eq (car math-simplify-expr) '/)
  533. (let ((signs (math-possible-signs (car np))))
  534. (or (memq signs '(1 4))
  535. (and (memq (car math-simplify-expr) '(calcFunc-eq calcFunc-neq))
  536. (eq signs 5))
  537. math-living-dangerously)))
  538. (math-numberp (car np)))
  539. (let (d
  540. (safe t)
  541. (scalar (math-known-scalarp (car np))))
  542. (while (and (eq (car-safe (setq d (car dp))) '*)
  543. safe)
  544. (math-simplify-one-divisor np (cdr d))
  545. (setq safe (or scalar (math-known-scalarp (nth 1 d) t))
  546. dp (cdr (cdr d))))
  547. (if safe
  548. (math-simplify-one-divisor np dp))))))
  549. (defun math-simplify-one-divisor (np dp)
  550. (let ((temp (math-combine-prod (car np) (car dp) math-simplify-divisor-nover
  551. math-simplify-divisor-dover t))
  552. op)
  553. (if temp
  554. (progn
  555. (and (not (memq (car math-simplify-expr) '(/ calcFunc-eq calcFunc-neq)))
  556. (math-known-negp (car dp))
  557. (setq op (assq (car math-simplify-expr) calc-tweak-eqn-table))
  558. (setcar math-simplify-expr (nth 1 op)))
  559. (setcar np (if math-simplify-divisor-nover (math-div 1 temp) temp))
  560. (setcar dp 1))
  561. (and math-simplify-divisor-dover (not math-simplify-divisor-nover)
  562. (eq (car math-simplify-expr) '/)
  563. (eq (car-safe (car dp)) 'calcFunc-sqrt)
  564. (Math-integerp (nth 1 (car dp)))
  565. (progn
  566. (setcar np (math-mul (car np)
  567. (list 'calcFunc-sqrt (nth 1 (car dp)))))
  568. (setcar dp (nth 1 (car dp))))))))
  569. (defun math-common-constant-factor (expr)
  570. (if (Math-realp expr)
  571. (if (Math-ratp expr)
  572. (and (not (memq expr '(0 1 -1)))
  573. (math-abs expr))
  574. (if (math-ratp (setq expr (math-to-simple-fraction expr)))
  575. (math-common-constant-factor expr)))
  576. (if (memq (car expr) '(+ - cplx sdev))
  577. (let ((f1 (math-common-constant-factor (nth 1 expr)))
  578. (f2 (math-common-constant-factor (nth 2 expr))))
  579. (and f1 f2
  580. (not (eq (setq f1 (math-frac-gcd f1 f2)) 1))
  581. f1))
  582. (if (memq (car expr) '(* polar))
  583. (math-common-constant-factor (nth 1 expr))
  584. (if (eq (car expr) '/)
  585. (or (math-common-constant-factor (nth 1 expr))
  586. (and (Math-integerp (nth 2 expr))
  587. (list 'frac 1 (math-abs (nth 2 expr))))))))))
  588. (defun math-cancel-common-factor (expr val)
  589. (if (memq (car-safe expr) '(+ - cplx sdev))
  590. (progn
  591. (setcar (cdr expr) (math-cancel-common-factor (nth 1 expr) val))
  592. (setcar (cdr (cdr expr)) (math-cancel-common-factor (nth 2 expr) val))
  593. expr)
  594. (if (eq (car-safe expr) '*)
  595. (math-mul (math-cancel-common-factor (nth 1 expr) val) (nth 2 expr))
  596. (math-div expr val))))
  597. (defun math-frac-gcd (a b)
  598. (if (Math-zerop a)
  599. b
  600. (if (Math-zerop b)
  601. a
  602. (if (and (Math-integerp a)
  603. (Math-integerp b))
  604. (math-gcd a b)
  605. (and (Math-integerp a) (setq a (list 'frac a 1)))
  606. (and (Math-integerp b) (setq b (list 'frac b 1)))
  607. (math-make-frac (math-gcd (nth 1 a) (nth 1 b))
  608. (math-gcd (nth 2 a) (nth 2 b)))))))
  609. (math-defsimplify %
  610. (math-simplify-mod))
  611. (defun math-simplify-mod ()
  612. (and (Math-realp (nth 2 math-simplify-expr))
  613. (Math-posp (nth 2 math-simplify-expr))
  614. (let ((lin (math-is-linear (nth 1 math-simplify-expr)))
  615. t1 t2 t3)
  616. (or (and lin
  617. (or (math-negp (car lin))
  618. (not (Math-lessp (car lin) (nth 2 math-simplify-expr))))
  619. (list '%
  620. (list '+
  621. (math-mul (nth 1 lin) (nth 2 lin))
  622. (math-mod (car lin) (nth 2 math-simplify-expr)))
  623. (nth 2 math-simplify-expr)))
  624. (and lin
  625. (not (math-equal-int (nth 1 lin) 1))
  626. (math-num-integerp (nth 1 lin))
  627. (math-num-integerp (nth 2 math-simplify-expr))
  628. (setq t1 (calcFunc-gcd (nth 1 lin) (nth 2 math-simplify-expr)))
  629. (not (math-equal-int t1 1))
  630. (list '*
  631. t1
  632. (list '%
  633. (list '+
  634. (math-mul (math-div (nth 1 lin) t1)
  635. (nth 2 lin))
  636. (let ((calc-prefer-frac t))
  637. (math-div (car lin) t1)))
  638. (math-div (nth 2 math-simplify-expr) t1))))
  639. (and (math-equal-int (nth 2 math-simplify-expr) 1)
  640. (math-known-integerp (if lin
  641. (math-mul (nth 1 lin) (nth 2 lin))
  642. (nth 1 math-simplify-expr)))
  643. (if lin (math-mod (car lin) 1) 0))))))
  644. (math-defsimplify (calcFunc-eq calcFunc-neq calcFunc-lt
  645. calcFunc-gt calcFunc-leq calcFunc-geq)
  646. (if (= (length math-simplify-expr) 3)
  647. (math-simplify-ineq)))
  648. (defun math-simplify-ineq ()
  649. (let ((np (cdr math-simplify-expr))
  650. n)
  651. (while (memq (car-safe (setq n (car np))) '(+ -))
  652. (math-simplify-add-term (cdr (cdr n)) (cdr (cdr math-simplify-expr))
  653. (eq (car n) '-) nil)
  654. (setq np (cdr n)))
  655. (math-simplify-add-term np (cdr (cdr math-simplify-expr)) nil
  656. (eq np (cdr math-simplify-expr)))
  657. (math-simplify-divide)
  658. (let ((signs (math-possible-signs (cons '- (cdr math-simplify-expr)))))
  659. (or (cond ((eq (car math-simplify-expr) 'calcFunc-eq)
  660. (or (and (eq signs 2) 1)
  661. (and (memq signs '(1 4 5)) 0)))
  662. ((eq (car math-simplify-expr) 'calcFunc-neq)
  663. (or (and (eq signs 2) 0)
  664. (and (memq signs '(1 4 5)) 1)))
  665. ((eq (car math-simplify-expr) 'calcFunc-lt)
  666. (or (and (eq signs 1) 1)
  667. (and (memq signs '(2 4 6)) 0)))
  668. ((eq (car math-simplify-expr) 'calcFunc-gt)
  669. (or (and (eq signs 4) 1)
  670. (and (memq signs '(1 2 3)) 0)))
  671. ((eq (car math-simplify-expr) 'calcFunc-leq)
  672. (or (and (eq signs 4) 0)
  673. (and (memq signs '(1 2 3)) 1)))
  674. ((eq (car math-simplify-expr) 'calcFunc-geq)
  675. (or (and (eq signs 1) 0)
  676. (and (memq signs '(2 4 6)) 1))))
  677. math-simplify-expr))))
  678. (defun math-simplify-add-term (np dp minus lplain)
  679. (or (math-vectorp (car np))
  680. (let ((rplain t)
  681. n d dd temp)
  682. (while (memq (car-safe (setq n (car np) d (car dp))) '(+ -))
  683. (setq rplain nil)
  684. (if (setq temp (math-combine-sum n (nth 2 d)
  685. minus (eq (car d) '+) t))
  686. (if (or lplain (eq (math-looks-negp temp) minus))
  687. (progn
  688. (setcar np (setq n (if minus (math-neg temp) temp)))
  689. (setcar (cdr (cdr d)) 0))
  690. (progn
  691. (setcar np 0)
  692. (setcar (cdr (cdr d)) (setq n (if (eq (car d) '+)
  693. (math-neg temp)
  694. temp))))))
  695. (setq dp (cdr d)))
  696. (if (setq temp (math-combine-sum n d minus t t))
  697. (if (or lplain
  698. (and (not rplain)
  699. (eq (math-looks-negp temp) minus)))
  700. (progn
  701. (setcar np (setq n (if minus (math-neg temp) temp)))
  702. (setcar dp 0))
  703. (progn
  704. (setcar np 0)
  705. (setcar dp (setq n (math-neg temp)))))))))
  706. (math-defsimplify calcFunc-sin
  707. (or (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsin)
  708. (nth 1 (nth 1 math-simplify-expr)))
  709. (and (math-looks-negp (nth 1 math-simplify-expr))
  710. (math-neg (list 'calcFunc-sin (math-neg (nth 1 math-simplify-expr)))))
  711. (and (eq calc-angle-mode 'rad)
  712. (let ((n (math-linear-in (nth 1 math-simplify-expr) '(var pi var-pi))))
  713. (and n
  714. (math-known-sin (car n) (nth 1 n) 120 0))))
  715. (and (eq calc-angle-mode 'deg)
  716. (let ((n (math-integer-plus (nth 1 math-simplify-expr))))
  717. (and n
  718. (math-known-sin (car n) (nth 1 n) '(frac 2 3) 0))))
  719. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccos)
  720. (list 'calcFunc-sqrt (math-sub 1 (math-sqr
  721. (nth 1 (nth 1 math-simplify-expr))))))
  722. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctan)
  723. (math-div (nth 1 (nth 1 math-simplify-expr))
  724. (list 'calcFunc-sqrt
  725. (math-add 1 (math-sqr
  726. (nth 1 (nth 1 math-simplify-expr)))))))
  727. (let ((m (math-should-expand-trig (nth 1 math-simplify-expr))))
  728. (and m (integerp (car m))
  729. (let ((n (car m)) (a (nth 1 m)))
  730. (list '+
  731. (list '* (list 'calcFunc-sin (list '* (1- n) a))
  732. (list 'calcFunc-cos a))
  733. (list '* (list 'calcFunc-cos (list '* (1- n) a))
  734. (list 'calcFunc-sin a))))))))
  735. (math-defsimplify calcFunc-cos
  736. (or (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccos)
  737. (nth 1 (nth 1 math-simplify-expr)))
  738. (and (math-looks-negp (nth 1 math-simplify-expr))
  739. (list 'calcFunc-cos (math-neg (nth 1 math-simplify-expr))))
  740. (and (eq calc-angle-mode 'rad)
  741. (let ((n (math-linear-in (nth 1 math-simplify-expr) '(var pi var-pi))))
  742. (and n
  743. (math-known-sin (car n) (nth 1 n) 120 300))))
  744. (and (eq calc-angle-mode 'deg)
  745. (let ((n (math-integer-plus (nth 1 math-simplify-expr))))
  746. (and n
  747. (math-known-sin (car n) (nth 1 n) '(frac 2 3) 300))))
  748. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsin)
  749. (list 'calcFunc-sqrt
  750. (math-sub 1 (math-sqr (nth 1 (nth 1 math-simplify-expr))))))
  751. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctan)
  752. (math-div 1
  753. (list 'calcFunc-sqrt
  754. (math-add 1
  755. (math-sqr (nth 1 (nth 1 math-simplify-expr)))))))
  756. (let ((m (math-should-expand-trig (nth 1 math-simplify-expr))))
  757. (and m (integerp (car m))
  758. (let ((n (car m)) (a (nth 1 m)))
  759. (list '-
  760. (list '* (list 'calcFunc-cos (list '* (1- n) a))
  761. (list 'calcFunc-cos a))
  762. (list '* (list 'calcFunc-sin (list '* (1- n) a))
  763. (list 'calcFunc-sin a))))))))
  764. (math-defsimplify calcFunc-sec
  765. (or (and (math-looks-negp (nth 1 math-simplify-expr))
  766. (list 'calcFunc-sec (math-neg (nth 1 math-simplify-expr))))
  767. (and (eq calc-angle-mode 'rad)
  768. (let ((n (math-linear-in (nth 1 math-simplify-expr) '(var pi var-pi))))
  769. (and n
  770. (math-div 1 (math-known-sin (car n) (nth 1 n) 120 300)))))
  771. (and (eq calc-angle-mode 'deg)
  772. (let ((n (math-integer-plus (nth 1 math-simplify-expr))))
  773. (and n
  774. (math-div 1 (math-known-sin (car n) (nth 1 n) '(frac 2 3) 300)))))
  775. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsin)
  776. (math-div
  777. 1
  778. (list 'calcFunc-sqrt
  779. (math-sub 1 (math-sqr (nth 1 (nth 1 math-simplify-expr)))))))
  780. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccos)
  781. (math-div
  782. 1
  783. (nth 1 (nth 1 math-simplify-expr))))
  784. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctan)
  785. (list 'calcFunc-sqrt
  786. (math-add 1
  787. (math-sqr (nth 1 (nth 1 math-simplify-expr))))))))
  788. (math-defsimplify calcFunc-csc
  789. (or (and (math-looks-negp (nth 1 math-simplify-expr))
  790. (math-neg (list 'calcFunc-csc (math-neg (nth 1 math-simplify-expr)))))
  791. (and (eq calc-angle-mode 'rad)
  792. (let ((n (math-linear-in (nth 1 math-simplify-expr) '(var pi var-pi))))
  793. (and n
  794. (math-div 1 (math-known-sin (car n) (nth 1 n) 120 0)))))
  795. (and (eq calc-angle-mode 'deg)
  796. (let ((n (math-integer-plus (nth 1 math-simplify-expr))))
  797. (and n
  798. (math-div 1 (math-known-sin (car n) (nth 1 n) '(frac 2 3) 0)))))
  799. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsin)
  800. (math-div 1 (nth 1 (nth 1 math-simplify-expr))))
  801. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccos)
  802. (math-div
  803. 1
  804. (list 'calcFunc-sqrt (math-sub 1 (math-sqr
  805. (nth 1 (nth 1 math-simplify-expr)))))))
  806. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctan)
  807. (math-div (list 'calcFunc-sqrt
  808. (math-add 1 (math-sqr
  809. (nth 1 (nth 1 math-simplify-expr)))))
  810. (nth 1 (nth 1 math-simplify-expr))))))
  811. (defun math-should-expand-trig (x &optional hyperbolic)
  812. (let ((m (math-is-multiple x)))
  813. (and math-living-dangerously
  814. m (or (and (integerp (car m)) (> (car m) 1))
  815. (equal (car m) '(frac 1 2)))
  816. (or math-integrating
  817. (memq (car-safe (nth 1 m))
  818. (if hyperbolic
  819. '(calcFunc-arcsinh calcFunc-arccosh calcFunc-arctanh)
  820. '(calcFunc-arcsin calcFunc-arccos calcFunc-arctan)))
  821. (and (eq (car-safe (nth 1 m)) 'calcFunc-ln)
  822. (eq hyperbolic 'exp)))
  823. m)))
  824. (defun math-known-sin (plus n mul off)
  825. (setq n (math-mul n mul))
  826. (and (math-num-integerp n)
  827. (setq n (math-mod (math-add (math-trunc n) off) 240))
  828. (if (>= n 120)
  829. (and (setq n (math-known-sin plus (- n 120) 1 0))
  830. (math-neg n))
  831. (if (> n 60)
  832. (setq n (- 120 n)))
  833. (if (math-zerop plus)
  834. (and (or calc-symbolic-mode
  835. (memq n '(0 20 60)))
  836. (cdr (assq n
  837. '( (0 . 0)
  838. (10 . (/ (calcFunc-sqrt
  839. (- 2 (calcFunc-sqrt 3))) 2))
  840. (12 . (/ (- (calcFunc-sqrt 5) 1) 4))
  841. (15 . (/ (calcFunc-sqrt
  842. (- 2 (calcFunc-sqrt 2))) 2))
  843. (20 . (/ 1 2))
  844. (24 . (* (^ (/ 1 2) (/ 3 2))
  845. (calcFunc-sqrt
  846. (- 5 (calcFunc-sqrt 5)))))
  847. (30 . (/ (calcFunc-sqrt 2) 2))
  848. (36 . (/ (+ (calcFunc-sqrt 5) 1) 4))
  849. (40 . (/ (calcFunc-sqrt 3) 2))
  850. (45 . (/ (calcFunc-sqrt
  851. (+ 2 (calcFunc-sqrt 2))) 2))
  852. (48 . (* (^ (/ 1 2) (/ 3 2))
  853. (calcFunc-sqrt
  854. (+ 5 (calcFunc-sqrt 5)))))
  855. (50 . (/ (calcFunc-sqrt
  856. (+ 2 (calcFunc-sqrt 3))) 2))
  857. (60 . 1)))))
  858. (cond ((eq n 0) (math-normalize (list 'calcFunc-sin plus)))
  859. ((eq n 60) (math-normalize (list 'calcFunc-cos plus)))
  860. (t nil))))))
  861. (math-defsimplify calcFunc-tan
  862. (or (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctan)
  863. (nth 1 (nth 1 math-simplify-expr)))
  864. (and (math-looks-negp (nth 1 math-simplify-expr))
  865. (math-neg (list 'calcFunc-tan (math-neg (nth 1 math-simplify-expr)))))
  866. (and (eq calc-angle-mode 'rad)
  867. (let ((n (math-linear-in (nth 1 math-simplify-expr) '(var pi var-pi))))
  868. (and n
  869. (math-known-tan (car n) (nth 1 n) 120))))
  870. (and (eq calc-angle-mode 'deg)
  871. (let ((n (math-integer-plus (nth 1 math-simplify-expr))))
  872. (and n
  873. (math-known-tan (car n) (nth 1 n) '(frac 2 3)))))
  874. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsin)
  875. (math-div (nth 1 (nth 1 math-simplify-expr))
  876. (list 'calcFunc-sqrt
  877. (math-sub 1 (math-sqr (nth 1 (nth 1 math-simplify-expr)))))))
  878. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccos)
  879. (math-div (list 'calcFunc-sqrt
  880. (math-sub 1 (math-sqr (nth 1 (nth 1 math-simplify-expr)))))
  881. (nth 1 (nth 1 math-simplify-expr))))
  882. (let ((m (math-should-expand-trig (nth 1 math-simplify-expr))))
  883. (and m
  884. (if (equal (car m) '(frac 1 2))
  885. (math-div (math-sub 1 (list 'calcFunc-cos (nth 1 m)))
  886. (list 'calcFunc-sin (nth 1 m)))
  887. (math-div (list 'calcFunc-sin (nth 1 math-simplify-expr))
  888. (list 'calcFunc-cos (nth 1 math-simplify-expr))))))))
  889. (math-defsimplify calcFunc-cot
  890. (or (and (math-looks-negp (nth 1 math-simplify-expr))
  891. (math-neg (list 'calcFunc-cot (math-neg (nth 1 math-simplify-expr)))))
  892. (and (eq calc-angle-mode 'rad)
  893. (let ((n (math-linear-in (nth 1 math-simplify-expr) '(var pi var-pi))))
  894. (and n
  895. (math-div 1 (math-known-tan (car n) (nth 1 n) 120)))))
  896. (and (eq calc-angle-mode 'deg)
  897. (let ((n (math-integer-plus (nth 1 math-simplify-expr))))
  898. (and n
  899. (math-div 1 (math-known-tan (car n) (nth 1 n) '(frac 2 3))))))
  900. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsin)
  901. (math-div (list 'calcFunc-sqrt
  902. (math-sub 1 (math-sqr (nth 1 (nth 1 math-simplify-expr)))))
  903. (nth 1 (nth 1 math-simplify-expr))))
  904. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccos)
  905. (math-div (nth 1 (nth 1 math-simplify-expr))
  906. (list 'calcFunc-sqrt
  907. (math-sub 1 (math-sqr (nth 1 (nth 1 math-simplify-expr)))))))
  908. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctan)
  909. (math-div 1 (nth 1 (nth 1 math-simplify-expr))))))
  910. (defun math-known-tan (plus n mul)
  911. (setq n (math-mul n mul))
  912. (and (math-num-integerp n)
  913. (setq n (math-mod (math-trunc n) 120))
  914. (if (> n 60)
  915. (and (setq n (math-known-tan plus (- 120 n) 1))
  916. (math-neg n))
  917. (if (math-zerop plus)
  918. (and (or calc-symbolic-mode
  919. (memq n '(0 30 60)))
  920. (cdr (assq n '( (0 . 0)
  921. (10 . (- 2 (calcFunc-sqrt 3)))
  922. (12 . (calcFunc-sqrt
  923. (- 1 (* (/ 2 5) (calcFunc-sqrt 5)))))
  924. (15 . (- (calcFunc-sqrt 2) 1))
  925. (20 . (/ (calcFunc-sqrt 3) 3))
  926. (24 . (calcFunc-sqrt
  927. (- 5 (* 2 (calcFunc-sqrt 5)))))
  928. (30 . 1)
  929. (36 . (calcFunc-sqrt
  930. (+ 1 (* (/ 2 5) (calcFunc-sqrt 5)))))
  931. (40 . (calcFunc-sqrt 3))
  932. (45 . (+ (calcFunc-sqrt 2) 1))
  933. (48 . (calcFunc-sqrt
  934. (+ 5 (* 2 (calcFunc-sqrt 5)))))
  935. (50 . (+ 2 (calcFunc-sqrt 3)))
  936. (60 . (var uinf var-uinf))))))
  937. (cond ((eq n 0) (math-normalize (list 'calcFunc-tan plus)))
  938. ((eq n 60) (math-normalize (list '/ -1
  939. (list 'calcFunc-tan plus))))
  940. (t nil))))))
  941. (math-defsimplify calcFunc-sinh
  942. (or (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsinh)
  943. (nth 1 (nth 1 math-simplify-expr)))
  944. (and (math-looks-negp (nth 1 math-simplify-expr))
  945. (math-neg (list 'calcFunc-sinh (math-neg (nth 1 math-simplify-expr)))))
  946. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccosh)
  947. math-living-dangerously
  948. (list 'calcFunc-sqrt
  949. (math-sub (math-sqr (nth 1 (nth 1 math-simplify-expr))) 1)))
  950. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctanh)
  951. math-living-dangerously
  952. (math-div (nth 1 (nth 1 math-simplify-expr))
  953. (list 'calcFunc-sqrt
  954. (math-sub 1 (math-sqr (nth 1 (nth 1 math-simplify-expr)))))))
  955. (let ((m (math-should-expand-trig (nth 1 math-simplify-expr) t)))
  956. (and m (integerp (car m))
  957. (let ((n (car m)) (a (nth 1 m)))
  958. (if (> n 1)
  959. (list '+
  960. (list '* (list 'calcFunc-sinh (list '* (1- n) a))
  961. (list 'calcFunc-cosh a))
  962. (list '* (list 'calcFunc-cosh (list '* (1- n) a))
  963. (list 'calcFunc-sinh a)))))))))
  964. (math-defsimplify calcFunc-cosh
  965. (or (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccosh)
  966. (nth 1 (nth 1 math-simplify-expr)))
  967. (and (math-looks-negp (nth 1 math-simplify-expr))
  968. (list 'calcFunc-cosh (math-neg (nth 1 math-simplify-expr))))
  969. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsinh)
  970. math-living-dangerously
  971. (list 'calcFunc-sqrt
  972. (math-add (math-sqr (nth 1 (nth 1 math-simplify-expr))) 1)))
  973. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctanh)
  974. math-living-dangerously
  975. (math-div 1
  976. (list 'calcFunc-sqrt
  977. (math-sub 1 (math-sqr (nth 1 (nth 1 math-simplify-expr)))))))
  978. (let ((m (math-should-expand-trig (nth 1 math-simplify-expr) t)))
  979. (and m (integerp (car m))
  980. (let ((n (car m)) (a (nth 1 m)))
  981. (if (> n 1)
  982. (list '+
  983. (list '* (list 'calcFunc-cosh (list '* (1- n) a))
  984. (list 'calcFunc-cosh a))
  985. (list '* (list 'calcFunc-sinh (list '* (1- n) a))
  986. (list 'calcFunc-sinh a)))))))))
  987. (math-defsimplify calcFunc-tanh
  988. (or (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctanh)
  989. (nth 1 (nth 1 math-simplify-expr)))
  990. (and (math-looks-negp (nth 1 math-simplify-expr))
  991. (math-neg (list 'calcFunc-tanh (math-neg (nth 1 math-simplify-expr)))))
  992. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsinh)
  993. math-living-dangerously
  994. (math-div (nth 1 (nth 1 math-simplify-expr))
  995. (list 'calcFunc-sqrt
  996. (math-add (math-sqr (nth 1 (nth 1 math-simplify-expr))) 1))))
  997. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccosh)
  998. math-living-dangerously
  999. (math-div (list 'calcFunc-sqrt
  1000. (math-sub (math-sqr (nth 1 (nth 1 math-simplify-expr))) 1))
  1001. (nth 1 (nth 1 math-simplify-expr))))
  1002. (let ((m (math-should-expand-trig (nth 1 math-simplify-expr) t)))
  1003. (and m
  1004. (if (equal (car m) '(frac 1 2))
  1005. (math-div (math-sub (list 'calcFunc-cosh (nth 1 m)) 1)
  1006. (list 'calcFunc-sinh (nth 1 m)))
  1007. (math-div (list 'calcFunc-sinh (nth 1 math-simplify-expr))
  1008. (list 'calcFunc-cosh (nth 1 math-simplify-expr))))))))
  1009. (math-defsimplify calcFunc-sech
  1010. (or (and (math-looks-negp (nth 1 math-simplify-expr))
  1011. (list 'calcFunc-sech (math-neg (nth 1 math-simplify-expr))))
  1012. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsinh)
  1013. math-living-dangerously
  1014. (math-div
  1015. 1
  1016. (list 'calcFunc-sqrt
  1017. (math-add (math-sqr (nth 1 (nth 1 math-simplify-expr))) 1))))
  1018. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccosh)
  1019. math-living-dangerously
  1020. (math-div 1 (nth 1 (nth 1 math-simplify-expr))) 1)
  1021. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctanh)
  1022. math-living-dangerously
  1023. (list 'calcFunc-sqrt
  1024. (math-sub 1 (math-sqr (nth 1 (nth 1 math-simplify-expr))))))))
  1025. (math-defsimplify calcFunc-csch
  1026. (or (and (math-looks-negp (nth 1 math-simplify-expr))
  1027. (math-neg (list 'calcFunc-csch (math-neg (nth 1 math-simplify-expr)))))
  1028. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsinh)
  1029. math-living-dangerously
  1030. (math-div 1 (nth 1 (nth 1 math-simplify-expr))))
  1031. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccosh)
  1032. math-living-dangerously
  1033. (math-div
  1034. 1
  1035. (list 'calcFunc-sqrt
  1036. (math-sub (math-sqr (nth 1 (nth 1 math-simplify-expr))) 1))))
  1037. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctanh)
  1038. math-living-dangerously
  1039. (math-div (list 'calcFunc-sqrt
  1040. (math-sub 1 (math-sqr (nth 1 (nth 1 math-simplify-expr)))))
  1041. (nth 1 (nth 1 math-simplify-expr))))))
  1042. (math-defsimplify calcFunc-coth
  1043. (or (and (math-looks-negp (nth 1 math-simplify-expr))
  1044. (math-neg (list 'calcFunc-coth (math-neg (nth 1 math-simplify-expr)))))
  1045. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsinh)
  1046. math-living-dangerously
  1047. (math-div (list 'calcFunc-sqrt
  1048. (math-add (math-sqr (nth 1 (nth 1 math-simplify-expr))) 1))
  1049. (nth 1 (nth 1 math-simplify-expr))))
  1050. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccosh)
  1051. math-living-dangerously
  1052. (math-div (nth 1 (nth 1 math-simplify-expr))
  1053. (list 'calcFunc-sqrt
  1054. (math-sub (math-sqr (nth 1 (nth 1 math-simplify-expr))) 1))))
  1055. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctanh)
  1056. math-living-dangerously
  1057. (math-div 1 (nth 1 (nth 1 math-simplify-expr))))))
  1058. (math-defsimplify calcFunc-arcsin
  1059. (or (and (math-looks-negp (nth 1 math-simplify-expr))
  1060. (math-neg (list 'calcFunc-arcsin (math-neg (nth 1 math-simplify-expr)))))
  1061. (and (eq (nth 1 math-simplify-expr) 1)
  1062. (math-quarter-circle t))
  1063. (and (equal (nth 1 math-simplify-expr) '(frac 1 2))
  1064. (math-div (math-half-circle t) 6))
  1065. (and math-living-dangerously
  1066. (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-sin)
  1067. (nth 1 (nth 1 math-simplify-expr)))
  1068. (and math-living-dangerously
  1069. (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-cos)
  1070. (math-sub (math-quarter-circle t)
  1071. (nth 1 (nth 1 math-simplify-expr))))))
  1072. (math-defsimplify calcFunc-arccos
  1073. (or (and (eq (nth 1 math-simplify-expr) 0)
  1074. (math-quarter-circle t))
  1075. (and (eq (nth 1 math-simplify-expr) -1)
  1076. (math-half-circle t))
  1077. (and (equal (nth 1 math-simplify-expr) '(frac 1 2))
  1078. (math-div (math-half-circle t) 3))
  1079. (and (equal (nth 1 math-simplify-expr) '(frac -1 2))
  1080. (math-div (math-mul (math-half-circle t) 2) 3))
  1081. (and math-living-dangerously
  1082. (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-cos)
  1083. (nth 1 (nth 1 math-simplify-expr)))
  1084. (and math-living-dangerously
  1085. (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-sin)
  1086. (math-sub (math-quarter-circle t)
  1087. (nth 1 (nth 1 math-simplify-expr))))))
  1088. (math-defsimplify calcFunc-arctan
  1089. (or (and (math-looks-negp (nth 1 math-simplify-expr))
  1090. (math-neg (list 'calcFunc-arctan (math-neg (nth 1 math-simplify-expr)))))
  1091. (and (eq (nth 1 math-simplify-expr) 1)
  1092. (math-div (math-half-circle t) 4))
  1093. (and math-living-dangerously
  1094. (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-tan)
  1095. (nth 1 (nth 1 math-simplify-expr)))))
  1096. (math-defsimplify calcFunc-arcsinh
  1097. (or (and (math-looks-negp (nth 1 math-simplify-expr))
  1098. (math-neg (list 'calcFunc-arcsinh (math-neg (nth 1 math-simplify-expr)))))
  1099. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-sinh)
  1100. (or math-living-dangerously
  1101. (math-known-realp (nth 1 (nth 1 math-simplify-expr))))
  1102. (nth 1 (nth 1 math-simplify-expr)))))
  1103. (math-defsimplify calcFunc-arccosh
  1104. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-cosh)
  1105. (or math-living-dangerously
  1106. (math-known-realp (nth 1 (nth 1 math-simplify-expr))))
  1107. (nth 1 (nth 1 math-simplify-expr))))
  1108. (math-defsimplify calcFunc-arctanh
  1109. (or (and (math-looks-negp (nth 1 math-simplify-expr))
  1110. (math-neg (list 'calcFunc-arctanh (math-neg (nth 1 math-simplify-expr)))))
  1111. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-tanh)
  1112. (or math-living-dangerously
  1113. (math-known-realp (nth 1 (nth 1 math-simplify-expr))))
  1114. (nth 1 (nth 1 math-simplify-expr)))))
  1115. (math-defsimplify calcFunc-sqrt
  1116. (math-simplify-sqrt))
  1117. (defun math-simplify-sqrt ()
  1118. (or (and (eq (car-safe (nth 1 math-simplify-expr)) 'frac)
  1119. (math-div (list 'calcFunc-sqrt
  1120. (math-mul (nth 1 (nth 1 math-simplify-expr))
  1121. (nth 2 (nth 1 math-simplify-expr))))
  1122. (nth 2 (nth 1 math-simplify-expr))))
  1123. (let ((fac (if (math-objectp (nth 1 math-simplify-expr))
  1124. (math-squared-factor (nth 1 math-simplify-expr))
  1125. (math-common-constant-factor (nth 1 math-simplify-expr)))))
  1126. (and fac (not (eq fac 1))
  1127. (math-mul (math-normalize (list 'calcFunc-sqrt fac))
  1128. (math-normalize
  1129. (list 'calcFunc-sqrt
  1130. (math-cancel-common-factor
  1131. (nth 1 math-simplify-expr) fac))))))
  1132. (and math-living-dangerously
  1133. (or (and (eq (car-safe (nth 1 math-simplify-expr)) '-)
  1134. (math-equal-int (nth 1 (nth 1 math-simplify-expr)) 1)
  1135. (eq (car-safe (nth 2 (nth 1 math-simplify-expr))) '^)
  1136. (math-equal-int (nth 2 (nth 2 (nth 1 math-simplify-expr))) 2)
  1137. (or (and (eq (car-safe (nth 1 (nth 2 (nth 1 math-simplify-expr))))
  1138. 'calcFunc-sin)
  1139. (list 'calcFunc-cos
  1140. (nth 1 (nth 1 (nth 2 (nth 1 math-simplify-expr))))))
  1141. (and (eq (car-safe (nth 1 (nth 2 (nth 1 math-simplify-expr))))
  1142. 'calcFunc-cos)
  1143. (list 'calcFunc-sin
  1144. (nth 1 (nth 1 (nth 2
  1145. (nth 1 math-simplify-expr))))))))
  1146. (and (eq (car-safe (nth 1 math-simplify-expr)) '-)
  1147. (math-equal-int (nth 2 (nth 1 math-simplify-expr)) 1)
  1148. (eq (car-safe (nth 1 (nth 1 math-simplify-expr))) '^)
  1149. (math-equal-int (nth 2 (nth 1 (nth 1 math-simplify-expr))) 2)
  1150. (and (eq (car-safe (nth 1 (nth 1 (nth 1 math-simplify-expr))))
  1151. 'calcFunc-cosh)
  1152. (list 'calcFunc-sinh
  1153. (nth 1 (nth 1 (nth 1 (nth 1 math-simplify-expr)))))))
  1154. (and (eq (car-safe (nth 1 math-simplify-expr)) '+)
  1155. (let ((a (nth 1 (nth 1 math-simplify-expr)))
  1156. (b (nth 2 (nth 1 math-simplify-expr))))
  1157. (and (or (and (math-equal-int a 1)
  1158. (setq a b b (nth 1 (nth 1 math-simplify-expr))))
  1159. (math-equal-int b 1))
  1160. (eq (car-safe a) '^)
  1161. (math-equal-int (nth 2 a) 2)
  1162. (or (and (eq (car-safe (nth 1 a)) 'calcFunc-sinh)
  1163. (list 'calcFunc-cosh (nth 1 (nth 1 a))))
  1164. (and (eq (car-safe (nth 1 a)) 'calcFunc-csch)
  1165. (list 'calcFunc-coth (nth 1 (nth 1 a))))
  1166. (and (eq (car-safe (nth 1 a)) 'calcFunc-tan)
  1167. (list '/ 1 (list 'calcFunc-cos
  1168. (nth 1 (nth 1 a)))))
  1169. (and (eq (car-safe (nth 1 a)) 'calcFunc-cot)
  1170. (list '/ 1 (list 'calcFunc-sin
  1171. (nth 1 (nth 1 a)))))))))
  1172. (and (eq (car-safe (nth 1 math-simplify-expr)) '^)
  1173. (list '^
  1174. (nth 1 (nth 1 math-simplify-expr))
  1175. (math-div (nth 2 (nth 1 math-simplify-expr)) 2)))
  1176. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-sqrt)
  1177. (list '^ (nth 1 (nth 1 math-simplify-expr)) (math-div 1 4)))
  1178. (and (memq (car-safe (nth 1 math-simplify-expr)) '(* /))
  1179. (list (car (nth 1 math-simplify-expr))
  1180. (list 'calcFunc-sqrt (nth 1 (nth 1 math-simplify-expr)))
  1181. (list 'calcFunc-sqrt (nth 2 (nth 1 math-simplify-expr)))))
  1182. (and (memq (car-safe (nth 1 math-simplify-expr)) '(+ -))
  1183. (not (math-any-floats (nth 1 math-simplify-expr)))
  1184. (let ((f (calcFunc-factors (calcFunc-expand
  1185. (nth 1 math-simplify-expr)))))
  1186. (and (math-vectorp f)
  1187. (or (> (length f) 2)
  1188. (> (nth 2 (nth 1 f)) 1))
  1189. (let ((out 1) (rest 1) (sums 1) fac pow)
  1190. (while (setq f (cdr f))
  1191. (setq fac (nth 1 (car f))
  1192. pow (nth 2 (car f)))
  1193. (if (> pow 1)
  1194. (setq out (math-mul out (math-pow
  1195. fac (/ pow 2)))
  1196. pow (% pow 2)))
  1197. (if (> pow 0)
  1198. (if (memq (car-safe fac) '(+ -))
  1199. (setq sums (math-mul-thru sums fac))
  1200. (setq rest (math-mul rest fac)))))
  1201. (and (not (and (eq out 1) (memq rest '(1 -1))))
  1202. (math-mul
  1203. out
  1204. (list 'calcFunc-sqrt
  1205. (math-mul sums rest))))))))))))
  1206. ;;; Rather than factoring x into primes, just check for the first ten primes.
  1207. (defun math-squared-factor (x)
  1208. (if (Math-integerp x)
  1209. (let ((prsqr '(4 9 25 49 121 169 289 361 529 841))
  1210. (fac 1)
  1211. res)
  1212. (while prsqr
  1213. (if (eq (cdr (setq res (math-idivmod x (car prsqr)))) 0)
  1214. (setq x (car res)
  1215. fac (math-mul fac (car prsqr)))
  1216. (setq prsqr (cdr prsqr))))
  1217. fac)))
  1218. (math-defsimplify calcFunc-exp
  1219. (math-simplify-exp (nth 1 math-simplify-expr)))
  1220. (defun math-simplify-exp (x)
  1221. (or (and (eq (car-safe x) 'calcFunc-ln)
  1222. (nth 1 x))
  1223. (and math-living-dangerously
  1224. (or (and (eq (car-safe x) 'calcFunc-arcsinh)
  1225. (math-add (nth 1 x)
  1226. (list 'calcFunc-sqrt
  1227. (math-add (math-sqr (nth 1 x)) 1))))
  1228. (and (eq (car-safe x) 'calcFunc-arccosh)
  1229. (math-add (nth 1 x)
  1230. (list 'calcFunc-sqrt
  1231. (math-sub (math-sqr (nth 1 x)) 1))))
  1232. (and (eq (car-safe x) 'calcFunc-arctanh)
  1233. (math-div (list 'calcFunc-sqrt (math-add 1 (nth 1 x)))
  1234. (list 'calcFunc-sqrt (math-sub 1 (nth 1 x)))))
  1235. (let ((m (math-should-expand-trig x 'exp)))
  1236. (and m (integerp (car m))
  1237. (list '^ (list 'calcFunc-exp (nth 1 m)) (car m))))))
  1238. (and calc-symbolic-mode
  1239. (math-known-imagp x)
  1240. (let* ((ip (calcFunc-im x))
  1241. (n (math-linear-in ip '(var pi var-pi)))
  1242. s c)
  1243. (and n
  1244. (setq s (math-known-sin (car n) (nth 1 n) 120 0))
  1245. (setq c (math-known-sin (car n) (nth 1 n) 120 300))
  1246. (list '+ c (list '* s '(var i var-i))))))))
  1247. (math-defsimplify calcFunc-ln
  1248. (or (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-exp)
  1249. (or math-living-dangerously
  1250. (math-known-realp (nth 1 (nth 1 math-simplify-expr))))
  1251. (nth 1 (nth 1 math-simplify-expr)))
  1252. (and (eq (car-safe (nth 1 math-simplify-expr)) '^)
  1253. (equal (nth 1 (nth 1 math-simplify-expr)) '(var e var-e))
  1254. (or math-living-dangerously
  1255. (math-known-realp (nth 2 (nth 1 math-simplify-expr))))
  1256. (nth 2 (nth 1 math-simplify-expr)))
  1257. (and calc-symbolic-mode
  1258. (math-known-negp (nth 1 math-simplify-expr))
  1259. (math-add (list 'calcFunc-ln (math-neg (nth 1 math-simplify-expr)))
  1260. '(* (var pi var-pi) (var i var-i))))
  1261. (and calc-symbolic-mode
  1262. (math-known-imagp (nth 1 math-simplify-expr))
  1263. (let* ((ip (calcFunc-im (nth 1 math-simplify-expr)))
  1264. (ips (math-possible-signs ip)))
  1265. (or (and (memq ips '(4 6))
  1266. (math-add (list 'calcFunc-ln ip)
  1267. '(/ (* (var pi var-pi) (var i var-i)) 2)))
  1268. (and (memq ips '(1 3))
  1269. (math-sub (list 'calcFunc-ln (math-neg ip))
  1270. '(/ (* (var pi var-pi) (var i var-i)) 2))))))))
  1271. (math-defsimplify ^
  1272. (math-simplify-pow))
  1273. (defun math-simplify-pow ()
  1274. (or (and math-living-dangerously
  1275. (or (and (eq (car-safe (nth 1 math-simplify-expr)) '^)
  1276. (list '^
  1277. (nth 1 (nth 1 math-simplify-expr))
  1278. (math-mul (nth 2 math-simplify-expr)
  1279. (nth 2 (nth 1 math-simplify-expr)))))
  1280. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-sqrt)
  1281. (list '^
  1282. (nth 1 (nth 1 math-simplify-expr))
  1283. (math-div (nth 2 math-simplify-expr) 2)))
  1284. (and (memq (car-safe (nth 1 math-simplify-expr)) '(* /))
  1285. (list (car (nth 1 math-simplify-expr))
  1286. (list '^ (nth 1 (nth 1 math-simplify-expr))
  1287. (nth 2 math-simplify-expr))
  1288. (list '^ (nth 2 (nth 1 math-simplify-expr))
  1289. (nth 2 math-simplify-expr))))))
  1290. (and (math-equal-int (nth 1 math-simplify-expr) 10)
  1291. (eq (car-safe (nth 2 math-simplify-expr)) 'calcFunc-log10)
  1292. (nth 1 (nth 2 math-simplify-expr)))
  1293. (and (equal (nth 1 math-simplify-expr) '(var e var-e))
  1294. (math-simplify-exp (nth 2 math-simplify-expr)))
  1295. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-exp)
  1296. (not math-integrating)
  1297. (list 'calcFunc-exp (math-mul (nth 1 (nth 1 math-simplify-expr))
  1298. (nth 2 math-simplify-expr))))
  1299. (and (equal (nth 1 math-simplify-expr) '(var i var-i))
  1300. (math-imaginary-i)
  1301. (math-num-integerp (nth 2 math-simplify-expr))
  1302. (let ((x (math-mod (math-trunc (nth 2 math-simplify-expr)) 4)))
  1303. (cond ((eq x 0) 1)
  1304. ((eq x 1) (nth 1 math-simplify-expr))
  1305. ((eq x 2) -1)
  1306. ((eq x 3) (math-neg (nth 1 math-simplify-expr))))))
  1307. (and math-integrating
  1308. (integerp (nth 2 math-simplify-expr))
  1309. (>= (nth 2 math-simplify-expr) 2)
  1310. (or (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-cos)
  1311. (math-mul (math-pow (nth 1 math-simplify-expr)
  1312. (- (nth 2 math-simplify-expr) 2))
  1313. (math-sub 1
  1314. (math-sqr
  1315. (list 'calcFunc-sin
  1316. (nth 1 (nth 1 math-simplify-expr)))))))
  1317. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-cosh)
  1318. (math-mul (math-pow (nth 1 math-simplify-expr)
  1319. (- (nth 2 math-simplify-expr) 2))
  1320. (math-add 1
  1321. (math-sqr
  1322. (list 'calcFunc-sinh
  1323. (nth 1 (nth 1 math-simplify-expr)))))))))
  1324. (and (eq (car-safe (nth 2 math-simplify-expr)) 'frac)
  1325. (Math-ratp (nth 1 math-simplify-expr))
  1326. (Math-posp (nth 1 math-simplify-expr))
  1327. (if (equal (nth 2 math-simplify-expr) '(frac 1 2))
  1328. (list 'calcFunc-sqrt (nth 1 math-simplify-expr))
  1329. (let ((flr (math-floor (nth 2 math-simplify-expr))))
  1330. (and (not (Math-zerop flr))
  1331. (list '* (list '^ (nth 1 math-simplify-expr) flr)
  1332. (list '^ (nth 1 math-simplify-expr)
  1333. (math-sub (nth 2 math-simplify-expr) flr)))))))
  1334. (and (eq (math-quarter-integer (nth 2 math-simplify-expr)) 2)
  1335. (let ((temp (math-simplify-sqrt)))
  1336. (and temp
  1337. (list '^ temp (math-mul (nth 2 math-simplify-expr) 2)))))))
  1338. (math-defsimplify calcFunc-log10
  1339. (and (eq (car-safe (nth 1 math-simplify-expr)) '^)
  1340. (math-equal-int (nth 1 (nth 1 math-simplify-expr)) 10)
  1341. (or math-living-dangerously
  1342. (math-known-realp (nth 2 (nth 1 math-simplify-expr))))
  1343. (nth 2 (nth 1 math-simplify-expr))))
  1344. (math-defsimplify calcFunc-erf
  1345. (or (and (math-looks-negp (nth 1 math-simplify-expr))
  1346. (math-neg (list 'calcFunc-erf (math-neg (nth 1 math-simplify-expr)))))
  1347. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-conj)
  1348. (list 'calcFunc-conj
  1349. (list 'calcFunc-erf (nth 1 (nth 1 math-simplify-expr)))))))
  1350. (math-defsimplify calcFunc-erfc
  1351. (or (and (math-looks-negp (nth 1 math-simplify-expr))
  1352. (math-sub 2 (list 'calcFunc-erfc (math-neg (nth 1 math-simplify-expr)))))
  1353. (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-conj)
  1354. (list 'calcFunc-conj
  1355. (list 'calcFunc-erfc (nth 1 (nth 1 math-simplify-expr)))))))
  1356. (defun math-linear-in (expr term &optional always)
  1357. (if (math-expr-contains expr term)
  1358. (let* ((calc-prefer-frac t)
  1359. (p (math-is-polynomial expr term 1)))
  1360. (and (cdr p)
  1361. p))
  1362. (and always (list expr 0))))
  1363. (defun math-multiple-of (expr term)
  1364. (let ((p (math-linear-in expr term)))
  1365. (and p
  1366. (math-zerop (car p))
  1367. (nth 1 p))))
  1368. ; not perfect, but it'll do
  1369. (defun math-integer-plus (expr)
  1370. (cond ((Math-integerp expr)
  1371. (list 0 expr))
  1372. ((and (memq (car expr) '(+ -))
  1373. (Math-integerp (nth 1 expr)))
  1374. (list (if (eq (car expr) '+) (nth 2 expr) (math-neg (nth 2 expr)))
  1375. (nth 1 expr)))
  1376. ((and (memq (car expr) '(+ -))
  1377. (Math-integerp (nth 2 expr)))
  1378. (list (nth 1 expr)
  1379. (if (eq (car expr) '+) (nth 2 expr) (math-neg (nth 2 expr)))))
  1380. (t nil)))
  1381. (defun math-is-linear (expr &optional always)
  1382. (let ((offset nil)
  1383. (coef nil))
  1384. (if (eq (car-safe expr) '+)
  1385. (if (Math-objectp (nth 1 expr))
  1386. (setq offset (nth 1 expr)
  1387. expr (nth 2 expr))
  1388. (if (Math-objectp (nth 2 expr))
  1389. (setq offset (nth 2 expr)
  1390. expr (nth 1 expr))))
  1391. (if (eq (car-safe expr) '-)
  1392. (if (Math-objectp (nth 1 expr))
  1393. (setq offset (nth 1 expr)
  1394. expr (math-neg (nth 2 expr)))
  1395. (if (Math-objectp (nth 2 expr))
  1396. (setq offset (math-neg (nth 2 expr))
  1397. expr (nth 1 expr))))))
  1398. (setq coef (math-is-multiple expr always))
  1399. (if offset
  1400. (list offset (or (car coef) 1) (or (nth 1 coef) expr))
  1401. (if coef
  1402. (cons 0 coef)))))
  1403. (defun math-is-multiple (expr &optional always)
  1404. (or (if (eq (car-safe expr) '*)
  1405. (if (Math-objectp (nth 1 expr))
  1406. (list (nth 1 expr) (nth 2 expr)))
  1407. (if (eq (car-safe expr) '/)
  1408. (if (and (Math-objectp (nth 1 expr))
  1409. (not (math-equal-int (nth 1 expr) 1)))
  1410. (list (nth 1 expr) (math-div 1 (nth 2 expr)))
  1411. (if (Math-objectp (nth 2 expr))
  1412. (list (math-div 1 (nth 2 expr)) (nth 1 expr))
  1413. (let ((res (math-is-multiple (nth 1 expr))))
  1414. (if res
  1415. (list (car res)
  1416. (math-div (nth 2 (nth 1 expr)) (nth 2 expr)))
  1417. (setq res (math-is-multiple (nth 2 expr)))
  1418. (if res
  1419. (list (math-div 1 (car res))
  1420. (math-div (nth 1 expr)
  1421. (nth 2 (nth 2 expr)))))))))
  1422. (if (eq (car-safe expr) 'neg)
  1423. (list -1 (nth 1 expr)))))
  1424. (if (Math-objvecp expr)
  1425. (and (eq always 1)
  1426. (list expr 1))
  1427. (and always
  1428. (list 1 expr)))))
  1429. (defun calcFunc-lin (expr &optional var)
  1430. (if var
  1431. (let ((res (math-linear-in expr var t)))
  1432. (or res (math-reject-arg expr "Linear term expected"))
  1433. (list 'vec (car res) (nth 1 res) var))
  1434. (let ((res (math-is-linear expr t)))
  1435. (or res (math-reject-arg expr "Linear term expected"))
  1436. (cons 'vec res))))
  1437. (defun calcFunc-linnt (expr &optional var)
  1438. (if var
  1439. (let ((res (math-linear-in expr var)))
  1440. (or res (math-reject-arg expr "Linear term expected"))
  1441. (list 'vec (car res) (nth 1 res) var))
  1442. (let ((res (math-is-linear expr)))
  1443. (or res (math-reject-arg expr "Linear term expected"))
  1444. (cons 'vec res))))
  1445. (defun calcFunc-islin (expr &optional var)
  1446. (if (and (Math-objvecp expr) (not var))
  1447. 0
  1448. (calcFunc-lin expr var)
  1449. 1))
  1450. (defun calcFunc-islinnt (expr &optional var)
  1451. (if (Math-objvecp expr)
  1452. 0
  1453. (calcFunc-linnt expr var)
  1454. 1))
  1455. ;;; Simple operations on expressions.
  1456. ;;; Return number of occurrences of thing in expr, or nil if none.
  1457. (defun math-expr-contains-count (expr thing)
  1458. (cond ((equal expr thing) 1)
  1459. ((Math-primp expr) nil)
  1460. (t
  1461. (let ((num 0))
  1462. (while (setq expr (cdr expr))
  1463. (setq num (+ num (or (math-expr-contains-count
  1464. (car expr) thing) 0))))
  1465. (and (> num 0)
  1466. num)))))
  1467. (defun math-expr-contains (expr thing)
  1468. (cond ((equal expr thing) 1)
  1469. ((Math-primp expr) nil)
  1470. (t
  1471. (while (and (setq expr (cdr expr))
  1472. (not (math-expr-contains (car expr) thing))))
  1473. expr)))
  1474. ;;; Return non-nil if any variable of thing occurs in expr.
  1475. (defun math-expr-depends (expr thing)
  1476. (if (Math-primp thing)
  1477. (and (eq (car-safe thing) 'var)
  1478. (math-expr-contains expr thing))
  1479. (while (and (setq thing (cdr thing))
  1480. (not (math-expr-depends expr (car thing)))))
  1481. thing))
  1482. ;;; Substitute all occurrences of old for new in expr (non-destructive).
  1483. ;; The variables math-expr-subst-old and math-expr-subst-new are local
  1484. ;; for math-expr-subst, but used by math-expr-subst-rec.
  1485. (defvar math-expr-subst-old)
  1486. (defvar math-expr-subst-new)
  1487. (defun math-expr-subst (expr math-expr-subst-old math-expr-subst-new)
  1488. (math-expr-subst-rec expr))
  1489. (defalias 'calcFunc-subst 'math-expr-subst)
  1490. (defun math-expr-subst-rec (expr)
  1491. (cond ((equal expr math-expr-subst-old) math-expr-subst-new)
  1492. ((Math-primp expr) expr)
  1493. ((memq (car expr) '(calcFunc-deriv
  1494. calcFunc-tderiv))
  1495. (if (= (length expr) 2)
  1496. (if (equal (nth 1 expr) math-expr-subst-old)
  1497. (append expr (list math-expr-subst-new))
  1498. expr)
  1499. (list (car expr) (nth 1 expr)
  1500. (math-expr-subst-rec (nth 2 expr)))))
  1501. (t
  1502. (cons (car expr)
  1503. (mapcar 'math-expr-subst-rec (cdr expr))))))
  1504. ;;; Various measures of the size of an expression.
  1505. (defun math-expr-weight (expr)
  1506. (if (Math-primp expr)
  1507. 1
  1508. (let ((w 1))
  1509. (while (setq expr (cdr expr))
  1510. (setq w (+ w (math-expr-weight (car expr)))))
  1511. w)))
  1512. (defun math-expr-height (expr)
  1513. (if (Math-primp expr)
  1514. 0
  1515. (let ((h 0))
  1516. (while (setq expr (cdr expr))
  1517. (setq h (max h (math-expr-height (car expr)))))
  1518. (1+ h))))
  1519. ;;; Polynomial operations (to support the integrator and solve-for).
  1520. (defun calcFunc-collect (expr base)
  1521. (let ((p (math-is-polynomial expr base 50 t)))
  1522. (if (cdr p)
  1523. (math-build-polynomial-expr (mapcar 'math-normalize p) base)
  1524. (car p))))
  1525. ;;; If expr is of the form "a + bx + cx^2 + ...", return the list (a b c ...),
  1526. ;;; else return nil if not in polynomial form. If "loose" (math-is-poly-loose),
  1527. ;;; coefficients may contain x, e.g., sin(x) + cos(x) x^2 is a loose polynomial in x.
  1528. ;; These variables are local to math-is-polynomial, but are used by
  1529. ;; math-is-poly-rec.
  1530. (defvar math-is-poly-degree)
  1531. (defvar math-is-poly-loose)
  1532. (defvar math-var)
  1533. (defun math-is-polynomial (expr math-var &optional math-is-poly-degree math-is-poly-loose)
  1534. (let* ((math-poly-base-variable (if math-is-poly-loose
  1535. (if (eq math-is-poly-loose 'gen) math-var '(var XXX XXX))
  1536. math-poly-base-variable))
  1537. (poly (math-is-poly-rec expr math-poly-neg-powers)))
  1538. (and (or (null math-is-poly-degree)
  1539. (<= (length poly) (1+ math-is-poly-degree)))
  1540. poly)))
  1541. (defun math-is-poly-rec (expr negpow)
  1542. (math-poly-simplify
  1543. (or (cond ((or (equal expr math-var)
  1544. (eq (car-safe expr) '^))
  1545. (let ((pow 1)
  1546. (expr expr))
  1547. (or (equal expr math-var)
  1548. (setq pow (nth 2 expr)
  1549. expr (nth 1 expr)))
  1550. (or (eq math-poly-mult-powers 1)
  1551. (setq pow (let ((m (math-is-multiple pow 1)))
  1552. (and (eq (car-safe (car m)) 'cplx)
  1553. (Math-zerop (nth 1 (car m)))
  1554. (setq m (list (nth 2 (car m))
  1555. (math-mul (nth 1 m)
  1556. '(var i var-i)))))
  1557. (and (if math-poly-mult-powers
  1558. (equal math-poly-mult-powers
  1559. (nth 1 m))
  1560. (setq math-poly-mult-powers (nth 1 m)))
  1561. (or (equal expr math-var)
  1562. (eq math-poly-mult-powers 1))
  1563. (car m)))))
  1564. (if (consp pow)
  1565. (progn
  1566. (setq pow (math-to-simple-fraction pow))
  1567. (and (eq (car-safe pow) 'frac)
  1568. math-poly-frac-powers
  1569. (equal expr math-var)
  1570. (setq math-poly-frac-powers
  1571. (calcFunc-lcm math-poly-frac-powers
  1572. (nth 2 pow))))))
  1573. (or (memq math-poly-frac-powers '(1 nil))
  1574. (setq pow (math-mul pow math-poly-frac-powers)))
  1575. (if (integerp pow)
  1576. (if (and (= pow 1)
  1577. (equal expr math-var))
  1578. (list 0 1)
  1579. (if (natnump pow)
  1580. (let ((p1 (if (equal expr math-var)
  1581. (list 0 1)
  1582. (math-is-poly-rec expr nil)))
  1583. (n pow)
  1584. (accum (list 1)))
  1585. (and p1
  1586. (or (null math-is-poly-degree)
  1587. (<= (* (1- (length p1)) n) math-is-poly-degree))
  1588. (progn
  1589. (while (>= n 1)
  1590. (setq accum (math-poly-mul accum p1)
  1591. n (1- n)))
  1592. accum)))
  1593. (and negpow
  1594. (math-is-poly-rec expr nil)
  1595. (setq math-poly-neg-powers
  1596. (cons (math-pow expr (- pow))
  1597. math-poly-neg-powers))
  1598. (list (list '^ expr pow))))))))
  1599. ((Math-objectp expr)
  1600. (list expr))
  1601. ((memq (car expr) '(+ -))
  1602. (let ((p1 (math-is-poly-rec (nth 1 expr) negpow)))
  1603. (and p1
  1604. (let ((p2 (math-is-poly-rec (nth 2 expr) negpow)))
  1605. (and p2
  1606. (math-poly-mix p1 1 p2
  1607. (if (eq (car expr) '+) 1 -1)))))))
  1608. ((eq (car expr) 'neg)
  1609. (mapcar 'math-neg (math-is-poly-rec (nth 1 expr) negpow)))
  1610. ((eq (car expr) '*)
  1611. (let ((p1 (math-is-poly-rec (nth 1 expr) negpow)))
  1612. (and p1
  1613. (let ((p2 (math-is-poly-rec (nth 2 expr) negpow)))
  1614. (and p2
  1615. (or (null math-is-poly-degree)
  1616. (<= (- (+ (length p1) (length p2)) 2)
  1617. math-is-poly-degree))
  1618. (math-poly-mul p1 p2))))))
  1619. ((eq (car expr) '/)
  1620. (and (or (not (math-poly-depends (nth 2 expr) math-var))
  1621. (and negpow
  1622. (math-is-poly-rec (nth 2 expr) nil)
  1623. (setq math-poly-neg-powers
  1624. (cons (nth 2 expr) math-poly-neg-powers))))
  1625. (not (Math-zerop (nth 2 expr)))
  1626. (let ((p1 (math-is-poly-rec (nth 1 expr) negpow)))
  1627. (mapcar (function (lambda (x) (math-div x (nth 2 expr))))
  1628. p1))))
  1629. ((and (eq (car expr) 'calcFunc-exp)
  1630. (equal math-var '(var e var-e)))
  1631. (math-is-poly-rec (list '^ math-var (nth 1 expr)) negpow))
  1632. ((and (eq (car expr) 'calcFunc-sqrt)
  1633. math-poly-frac-powers)
  1634. (math-is-poly-rec (list '^ (nth 1 expr) '(frac 1 2)) negpow))
  1635. (t nil))
  1636. (and (or (not (math-poly-depends expr math-var))
  1637. math-is-poly-loose)
  1638. (not (eq (car expr) 'vec))
  1639. (list expr)))))
  1640. ;;; Check if expr is a polynomial in var; if so, return its degree.
  1641. (defun math-polynomial-p (expr var)
  1642. (cond ((equal expr var) 1)
  1643. ((Math-primp expr) 0)
  1644. ((memq (car expr) '(+ -))
  1645. (let ((p1 (math-polynomial-p (nth 1 expr) var))
  1646. p2)
  1647. (and p1 (setq p2 (math-polynomial-p (nth 2 expr) var))
  1648. (max p1 p2))))
  1649. ((eq (car expr) '*)
  1650. (let ((p1 (math-polynomial-p (nth 1 expr) var))
  1651. p2)
  1652. (and p1 (setq p2 (math-polynomial-p (nth 2 expr) var))
  1653. (+ p1 p2))))
  1654. ((eq (car expr) 'neg)
  1655. (math-polynomial-p (nth 1 expr) var))
  1656. ((and (eq (car expr) '/)
  1657. (not (math-poly-depends (nth 2 expr) var)))
  1658. (math-polynomial-p (nth 1 expr) var))
  1659. ((and (eq (car expr) '^)
  1660. (natnump (nth 2 expr)))
  1661. (let ((p1 (math-polynomial-p (nth 1 expr) var)))
  1662. (and p1 (* p1 (nth 2 expr)))))
  1663. ((math-poly-depends expr var) nil)
  1664. (t 0)))
  1665. (defun math-poly-depends (expr var)
  1666. (if math-poly-base-variable
  1667. (math-expr-contains expr math-poly-base-variable)
  1668. (math-expr-depends expr var)))
  1669. ;;; Find the variable (or sub-expression) which is the base of polynomial expr.
  1670. ;; The variables math-poly-base-const-ok and math-poly-base-pred are
  1671. ;; local to math-polynomial-base, but are used by math-polynomial-base-rec.
  1672. (defvar math-poly-base-const-ok)
  1673. (defvar math-poly-base-pred)
  1674. ;; The variable math-poly-base-top-expr is local to math-polynomial-base,
  1675. ;; but is used by math-polynomial-p1 in calc-poly.el, which is called
  1676. ;; by math-polynomial-base.
  1677. (defun math-polynomial-base (math-poly-base-top-expr &optional math-poly-base-pred)
  1678. (or math-poly-base-pred
  1679. (setq math-poly-base-pred (function (lambda (base) (math-polynomial-p
  1680. math-poly-base-top-expr base)))))
  1681. (or (let ((math-poly-base-const-ok nil))
  1682. (math-polynomial-base-rec math-poly-base-top-expr))
  1683. (let ((math-poly-base-const-ok t))
  1684. (math-polynomial-base-rec math-poly-base-top-expr))))
  1685. (defun math-polynomial-base-rec (mpb-expr)
  1686. (and (not (Math-objvecp mpb-expr))
  1687. (or (and (memq (car mpb-expr) '(+ - *))
  1688. (or (math-polynomial-base-rec (nth 1 mpb-expr))
  1689. (math-polynomial-base-rec (nth 2 mpb-expr))))
  1690. (and (memq (car mpb-expr) '(/ neg))
  1691. (math-polynomial-base-rec (nth 1 mpb-expr)))
  1692. (and (eq (car mpb-expr) '^)
  1693. (math-polynomial-base-rec (nth 1 mpb-expr)))
  1694. (and (eq (car mpb-expr) 'calcFunc-exp)
  1695. (math-polynomial-base-rec '(var e var-e)))
  1696. (and (or math-poly-base-const-ok (math-expr-contains-vars mpb-expr))
  1697. (funcall math-poly-base-pred mpb-expr)
  1698. mpb-expr))))
  1699. ;;; Return non-nil if expr refers to any variables.
  1700. (defun math-expr-contains-vars (expr)
  1701. (or (eq (car-safe expr) 'var)
  1702. (and (not (Math-primp expr))
  1703. (progn
  1704. (while (and (setq expr (cdr expr))
  1705. (not (math-expr-contains-vars (car expr)))))
  1706. expr))))
  1707. ;;; Simplify a polynomial in list form by stripping off high-end zeros.
  1708. ;;; This always leaves the constant part, i.e., nil->nil and non-nil->non-nil.
  1709. (defun math-poly-simplify (p)
  1710. (and p
  1711. (if (Math-zerop (nth (1- (length p)) p))
  1712. (let ((pp (copy-sequence p)))
  1713. (while (and (cdr pp)
  1714. (Math-zerop (nth (1- (length pp)) pp)))
  1715. (setcdr (nthcdr (- (length pp) 2) pp) nil))
  1716. pp)
  1717. p)))
  1718. ;;; Compute ac*a + bc*b for polynomials in list form a, b and
  1719. ;;; coefficients ac, bc. Result may be unsimplified.
  1720. (defun math-poly-mix (a ac b bc)
  1721. (and (or a b)
  1722. (cons (math-add (math-mul (or (car a) 0) ac)
  1723. (math-mul (or (car b) 0) bc))
  1724. (math-poly-mix (cdr a) ac (cdr b) bc))))
  1725. (defun math-poly-zerop (a)
  1726. (or (null a)
  1727. (and (null (cdr a)) (Math-zerop (car a)))))
  1728. ;;; Multiply two polynomials in list form.
  1729. (defun math-poly-mul (a b)
  1730. (and a b
  1731. (math-poly-mix b (car a)
  1732. (math-poly-mul (cdr a) (cons 0 b)) 1)))
  1733. ;;; Build an expression from a polynomial list.
  1734. (defun math-build-polynomial-expr (p var)
  1735. (if p
  1736. (if (Math-numberp var)
  1737. (math-with-extra-prec 1
  1738. (let* ((rp (reverse p))
  1739. (accum (car rp)))
  1740. (while (setq rp (cdr rp))
  1741. (setq accum (math-add (car rp) (math-mul accum var))))
  1742. accum))
  1743. (let* ((rp (reverse p))
  1744. (n (1- (length rp)))
  1745. (accum (math-mul (car rp) (math-pow var n)))
  1746. term)
  1747. (while (setq rp (cdr rp))
  1748. (setq n (1- n))
  1749. (or (math-zerop (car rp))
  1750. (setq accum (list (if (math-looks-negp (car rp)) '- '+)
  1751. accum
  1752. (math-mul (if (math-looks-negp (car rp))
  1753. (math-neg (car rp))
  1754. (car rp))
  1755. (math-pow var n))))))
  1756. accum))
  1757. 0))
  1758. (defun math-to-simple-fraction (f)
  1759. (or (and (eq (car-safe f) 'float)
  1760. (or (and (>= (nth 2 f) 0)
  1761. (math-scale-int (nth 1 f) (nth 2 f)))
  1762. (and (integerp (nth 1 f))
  1763. (> (nth 1 f) -1000)
  1764. (< (nth 1 f) 1000)
  1765. (math-make-frac (nth 1 f)
  1766. (math-scale-int 1 (- (nth 2 f)))))))
  1767. f))
  1768. (provide 'calc-alg)
  1769. ;;; calc-alg.el ends here