calc-alg.el 71 KB

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