calcalg2.el 123 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672
  1. ;;; calcalg2.el --- more algebraic functions for Calc
  2. ;; Copyright (C) 1990-1993, 2001-2012 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. (defun calc-derivative (var num)
  22. (interactive "sDifferentiate with respect to: \np")
  23. (calc-slow-wrapper
  24. (when (< num 0)
  25. (error "Order of derivative must be positive"))
  26. (let ((func (if (calc-is-hyperbolic) 'calcFunc-tderiv 'calcFunc-deriv))
  27. n expr)
  28. (if (or (equal var "") (equal var "$"))
  29. (setq n 2
  30. expr (calc-top-n 2)
  31. var (calc-top-n 1))
  32. (setq var (math-read-expr var))
  33. (when (eq (car-safe var) 'error)
  34. (error "Bad format in expression: %s" (nth 1 var)))
  35. (setq n 1
  36. expr (calc-top-n 1)))
  37. (while (>= (setq num (1- num)) 0)
  38. (setq expr (list func expr var)))
  39. (calc-enter-result n "derv" expr))))
  40. (defun calc-integral (var &optional arg)
  41. (interactive "sIntegration variable: \nP")
  42. (if arg
  43. (calc-tabular-command 'calcFunc-integ "Integration" "intg" nil var nil nil)
  44. (calc-slow-wrapper
  45. (if (or (equal var "") (equal var "$"))
  46. (calc-enter-result 2 "intg" (list 'calcFunc-integ
  47. (calc-top-n 2)
  48. (calc-top-n 1)))
  49. (let ((var (math-read-expr var)))
  50. (if (eq (car-safe var) 'error)
  51. (error "Bad format in expression: %s" (nth 1 var)))
  52. (calc-enter-result 1 "intg" (list 'calcFunc-integ
  53. (calc-top-n 1)
  54. var)))))))
  55. (defun calc-num-integral (&optional varname lowname highname)
  56. (interactive "sIntegration variable: ")
  57. (calc-tabular-command 'calcFunc-ninteg "Integration" "nint"
  58. nil varname lowname highname))
  59. (defun calc-summation (arg &optional varname lowname highname)
  60. (interactive "P\nsSummation variable: ")
  61. (calc-tabular-command 'calcFunc-sum "Summation" "sum"
  62. arg varname lowname highname))
  63. (defun calc-alt-summation (arg &optional varname lowname highname)
  64. (interactive "P\nsSummation variable: ")
  65. (calc-tabular-command 'calcFunc-asum "Summation" "asum"
  66. arg varname lowname highname))
  67. (defun calc-product (arg &optional varname lowname highname)
  68. (interactive "P\nsIndex variable: ")
  69. (calc-tabular-command 'calcFunc-prod "Index" "prod"
  70. arg varname lowname highname))
  71. (defun calc-tabulate (arg &optional varname lowname highname)
  72. (interactive "P\nsIndex variable: ")
  73. (calc-tabular-command 'calcFunc-table "Index" "tabl"
  74. arg varname lowname highname))
  75. (defun calc-tabular-command (func prompt prefix arg varname lowname highname)
  76. (calc-slow-wrapper
  77. (let (var (low nil) (high nil) (step nil) stepname stepnum (num 1) expr)
  78. (if (consp arg)
  79. (setq stepnum 1)
  80. (setq stepnum 0))
  81. (if (or (equal varname "") (equal varname "$") (null varname))
  82. (setq high (calc-top-n (+ stepnum 1))
  83. low (calc-top-n (+ stepnum 2))
  84. var (calc-top-n (+ stepnum 3))
  85. num (+ stepnum 4))
  86. (setq var (if (stringp varname) (math-read-expr varname) varname))
  87. (if (eq (car-safe var) 'error)
  88. (error "Bad format in expression: %s" (nth 1 var)))
  89. (or lowname
  90. (setq lowname (read-string (concat prompt " variable: " varname
  91. ", from: "))))
  92. (if (or (equal lowname "") (equal lowname "$"))
  93. (setq high (calc-top-n (+ stepnum 1))
  94. low (calc-top-n (+ stepnum 2))
  95. num (+ stepnum 3))
  96. (setq low (if (stringp lowname) (math-read-expr lowname) lowname))
  97. (if (eq (car-safe low) 'error)
  98. (error "Bad format in expression: %s" (nth 1 low)))
  99. (or highname
  100. (setq highname (read-string (concat prompt " variable: " varname
  101. ", from: " lowname
  102. ", to: "))))
  103. (if (or (equal highname "") (equal highname "$"))
  104. (setq high (calc-top-n (+ stepnum 1))
  105. num (+ stepnum 2))
  106. (setq high (if (stringp highname) (math-read-expr highname)
  107. highname))
  108. (if (eq (car-safe high) 'error)
  109. (error "Bad format in expression: %s" (nth 1 high)))
  110. (if (consp arg)
  111. (progn
  112. (setq stepname (read-string (concat prompt " variable: "
  113. varname
  114. ", from: " lowname
  115. ", to: " highname
  116. ", step: ")))
  117. (if (or (equal stepname "") (equal stepname "$"))
  118. (setq step (calc-top-n 1)
  119. num 2)
  120. (setq step (math-read-expr stepname))
  121. (if (eq (car-safe step) 'error)
  122. (error "Bad format in expression: %s"
  123. (nth 1 step)))))))))
  124. (or step
  125. (if (consp arg)
  126. (setq step (calc-top-n 1))
  127. (if arg
  128. (setq step (prefix-numeric-value arg)))))
  129. (setq expr (calc-top-n num))
  130. (calc-enter-result num prefix (append (list func expr var low high)
  131. (and step (list step)))))))
  132. (defun calc-solve-for (var)
  133. (interactive "sVariable(s) to solve for: ")
  134. (calc-slow-wrapper
  135. (let ((func (if (calc-is-inverse)
  136. (if (calc-is-hyperbolic) 'calcFunc-ffinv 'calcFunc-finv)
  137. (if (calc-is-hyperbolic) 'calcFunc-fsolve 'calcFunc-solve))))
  138. (if (or (equal var "") (equal var "$"))
  139. (calc-enter-result 2 "solv" (list func
  140. (calc-top-n 2)
  141. (calc-top-n 1)))
  142. (let ((var (if (and (string-match ",\\|[^ ] +[^ ]" var)
  143. (not (string-match "\\[" var)))
  144. (math-read-expr (concat "[" var "]"))
  145. (math-read-expr var))))
  146. (if (eq (car-safe var) 'error)
  147. (error "Bad format in expression: %s" (nth 1 var)))
  148. (calc-enter-result 1 "solv" (list func
  149. (calc-top-n 1)
  150. var)))))))
  151. (defun calc-poly-roots (var)
  152. (interactive "sVariable to solve for: ")
  153. (calc-slow-wrapper
  154. (if (or (equal var "") (equal var "$"))
  155. (calc-enter-result 2 "prts" (list 'calcFunc-roots
  156. (calc-top-n 2)
  157. (calc-top-n 1)))
  158. (let ((var (if (and (string-match ",\\|[^ ] +[^ ]" var)
  159. (not (string-match "\\[" var)))
  160. (math-read-expr (concat "[" var "]"))
  161. (math-read-expr var))))
  162. (if (eq (car-safe var) 'error)
  163. (error "Bad format in expression: %s" (nth 1 var)))
  164. (calc-enter-result 1 "prts" (list 'calcFunc-roots
  165. (calc-top-n 1)
  166. var))))))
  167. (defun calc-taylor (var nterms)
  168. (interactive "sTaylor expansion variable: \nNNumber of terms: ")
  169. (calc-slow-wrapper
  170. (let ((var (math-read-expr var)))
  171. (if (eq (car-safe var) 'error)
  172. (error "Bad format in expression: %s" (nth 1 var)))
  173. (calc-enter-result 1 "tylr" (list 'calcFunc-taylor
  174. (calc-top-n 1)
  175. var
  176. (prefix-numeric-value nterms))))))
  177. ;; The following are global variables used by math-derivative and some
  178. ;; related functions
  179. (defvar math-deriv-var)
  180. (defvar math-deriv-total)
  181. (defvar math-deriv-symb)
  182. (defvar math-decls-cache)
  183. (defvar math-decls-all)
  184. (defun math-derivative (expr)
  185. (cond ((equal expr math-deriv-var)
  186. 1)
  187. ((or (Math-scalarp expr)
  188. (eq (car expr) 'sdev)
  189. (and (eq (car expr) 'var)
  190. (or (not math-deriv-total)
  191. (math-const-var expr)
  192. (progn
  193. (math-setup-declarations)
  194. (memq 'const (nth 1 (or (assq (nth 2 expr)
  195. math-decls-cache)
  196. math-decls-all)))))))
  197. 0)
  198. ((eq (car expr) '+)
  199. (math-add (math-derivative (nth 1 expr))
  200. (math-derivative (nth 2 expr))))
  201. ((eq (car expr) '-)
  202. (math-sub (math-derivative (nth 1 expr))
  203. (math-derivative (nth 2 expr))))
  204. ((memq (car expr) '(calcFunc-eq calcFunc-neq calcFunc-lt
  205. calcFunc-gt calcFunc-leq calcFunc-geq))
  206. (list (car expr)
  207. (math-derivative (nth 1 expr))
  208. (math-derivative (nth 2 expr))))
  209. ((eq (car expr) 'neg)
  210. (math-neg (math-derivative (nth 1 expr))))
  211. ((eq (car expr) '*)
  212. (math-add (math-mul (nth 2 expr)
  213. (math-derivative (nth 1 expr)))
  214. (math-mul (nth 1 expr)
  215. (math-derivative (nth 2 expr)))))
  216. ((eq (car expr) '/)
  217. (math-sub (math-div (math-derivative (nth 1 expr))
  218. (nth 2 expr))
  219. (math-div (math-mul (nth 1 expr)
  220. (math-derivative (nth 2 expr)))
  221. (math-sqr (nth 2 expr)))))
  222. ((eq (car expr) '^)
  223. (let ((du (math-derivative (nth 1 expr)))
  224. (dv (math-derivative (nth 2 expr))))
  225. (or (Math-zerop du)
  226. (setq du (math-mul (nth 2 expr)
  227. (math-mul (math-normalize
  228. (list '^
  229. (nth 1 expr)
  230. (math-add (nth 2 expr) -1)))
  231. du))))
  232. (or (Math-zerop dv)
  233. (setq dv (math-mul (math-normalize
  234. (list 'calcFunc-ln (nth 1 expr)))
  235. (math-mul expr dv))))
  236. (math-add du dv)))
  237. ((eq (car expr) '%)
  238. (math-derivative (nth 1 expr))) ; a reasonable definition
  239. ((eq (car expr) 'vec)
  240. (math-map-vec 'math-derivative expr))
  241. ((and (memq (car expr) '(calcFunc-conj calcFunc-re calcFunc-im))
  242. (= (length expr) 2))
  243. (list (car expr) (math-derivative (nth 1 expr))))
  244. ((and (memq (car expr) '(calcFunc-subscr calcFunc-mrow calcFunc-mcol))
  245. (= (length expr) 3))
  246. (let ((d (math-derivative (nth 1 expr))))
  247. (if (math-numberp d)
  248. 0 ; assume x and x_1 are independent vars
  249. (list (car expr) d (nth 2 expr)))))
  250. (t (or (and (symbolp (car expr))
  251. (if (= (length expr) 2)
  252. (let ((handler (get (car expr) 'math-derivative)))
  253. (and handler
  254. (let ((deriv (math-derivative (nth 1 expr))))
  255. (if (Math-zerop deriv)
  256. deriv
  257. (math-mul (funcall handler (nth 1 expr))
  258. deriv)))))
  259. (let ((handler (get (car expr) 'math-derivative-n)))
  260. (and handler
  261. (funcall handler expr)))))
  262. (and (not (eq math-deriv-symb 'pre-expand))
  263. (let ((exp (math-expand-formula expr)))
  264. (and exp
  265. (or (let ((math-deriv-symb 'pre-expand))
  266. (catch 'math-deriv (math-derivative expr)))
  267. (math-derivative exp)))))
  268. (if (or (Math-objvecp expr)
  269. (eq (car expr) 'var)
  270. (not (symbolp (car expr))))
  271. (if math-deriv-symb
  272. (throw 'math-deriv nil)
  273. (list (if math-deriv-total 'calcFunc-tderiv 'calcFunc-deriv)
  274. expr
  275. math-deriv-var))
  276. (let ((accum 0)
  277. (arg expr)
  278. (n 1)
  279. derv)
  280. (while (setq arg (cdr arg))
  281. (or (Math-zerop (setq derv (math-derivative (car arg))))
  282. (let ((func (intern (concat (symbol-name (car expr))
  283. "'"
  284. (if (> n 1)
  285. (int-to-string n)
  286. ""))))
  287. (prop (cond ((= (length expr) 2)
  288. 'math-derivative-1)
  289. ((= (length expr) 3)
  290. 'math-derivative-2)
  291. ((= (length expr) 4)
  292. 'math-derivative-3)
  293. ((= (length expr) 5)
  294. 'math-derivative-4)
  295. ((= (length expr) 6)
  296. 'math-derivative-5))))
  297. (setq accum
  298. (math-add
  299. accum
  300. (math-mul
  301. derv
  302. (let ((handler (get func prop)))
  303. (or (and prop handler
  304. (apply handler (cdr expr)))
  305. (if (and math-deriv-symb
  306. (not (get func
  307. 'calc-user-defn)))
  308. (throw 'math-deriv nil)
  309. (cons func (cdr expr))))))))))
  310. (setq n (1+ n)))
  311. accum))))))
  312. (defun calcFunc-deriv (expr math-deriv-var &optional deriv-value math-deriv-symb)
  313. (let* ((math-deriv-total nil)
  314. (res (catch 'math-deriv (math-derivative expr))))
  315. (or (eq (car-safe res) 'calcFunc-deriv)
  316. (null res)
  317. (setq res (math-normalize res)))
  318. (and res
  319. (if deriv-value
  320. (math-expr-subst res math-deriv-var deriv-value)
  321. res))))
  322. (defun calcFunc-tderiv (expr math-deriv-var &optional deriv-value math-deriv-symb)
  323. (math-setup-declarations)
  324. (let* ((math-deriv-total t)
  325. (res (catch 'math-deriv (math-derivative expr))))
  326. (or (eq (car-safe res) 'calcFunc-tderiv)
  327. (null res)
  328. (setq res (math-normalize res)))
  329. (and res
  330. (if deriv-value
  331. (math-expr-subst res math-deriv-var deriv-value)
  332. res))))
  333. (put 'calcFunc-inv\' 'math-derivative-1
  334. (function (lambda (u) (math-neg (math-div 1 (math-sqr u))))))
  335. (put 'calcFunc-sqrt\' 'math-derivative-1
  336. (function (lambda (u) (math-div 1 (math-mul 2 (list 'calcFunc-sqrt u))))))
  337. (put 'calcFunc-deg\' 'math-derivative-1
  338. (function (lambda (u) (math-div-float '(float 18 1) (math-pi)))))
  339. (put 'calcFunc-rad\' 'math-derivative-1
  340. (function (lambda (u) (math-pi-over-180))))
  341. (put 'calcFunc-ln\' 'math-derivative-1
  342. (function (lambda (u) (math-div 1 u))))
  343. (put 'calcFunc-log10\' 'math-derivative-1
  344. (function (lambda (u)
  345. (math-div (math-div 1 (math-normalize '(calcFunc-ln 10)))
  346. u))))
  347. (put 'calcFunc-lnp1\' 'math-derivative-1
  348. (function (lambda (u) (math-div 1 (math-add u 1)))))
  349. (put 'calcFunc-log\' 'math-derivative-2
  350. (function (lambda (x b)
  351. (and (not (Math-zerop b))
  352. (let ((lnv (math-normalize
  353. (list 'calcFunc-ln b))))
  354. (math-div 1 (math-mul lnv x)))))))
  355. (put 'calcFunc-log\'2 'math-derivative-2
  356. (function (lambda (x b)
  357. (let ((lnv (list 'calcFunc-ln b)))
  358. (math-neg (math-div (list 'calcFunc-log x b)
  359. (math-mul lnv b)))))))
  360. (put 'calcFunc-exp\' 'math-derivative-1
  361. (function (lambda (u) (math-normalize (list 'calcFunc-exp u)))))
  362. (put 'calcFunc-expm1\' 'math-derivative-1
  363. (function (lambda (u) (math-normalize (list 'calcFunc-expm1 u)))))
  364. (put 'calcFunc-sin\' 'math-derivative-1
  365. (function (lambda (u) (math-to-radians-2 (math-normalize
  366. (list 'calcFunc-cos u))))))
  367. (put 'calcFunc-cos\' 'math-derivative-1
  368. (function (lambda (u) (math-neg (math-to-radians-2
  369. (math-normalize
  370. (list 'calcFunc-sin u)))))))
  371. (put 'calcFunc-tan\' 'math-derivative-1
  372. (function (lambda (u) (math-to-radians-2
  373. (math-sqr
  374. (math-normalize
  375. (list 'calcFunc-sec u)))))))
  376. (put 'calcFunc-sec\' 'math-derivative-1
  377. (function (lambda (u) (math-to-radians-2
  378. (math-mul
  379. (math-normalize
  380. (list 'calcFunc-sec u))
  381. (math-normalize
  382. (list 'calcFunc-tan u)))))))
  383. (put 'calcFunc-csc\' 'math-derivative-1
  384. (function (lambda (u) (math-neg
  385. (math-to-radians-2
  386. (math-mul
  387. (math-normalize
  388. (list 'calcFunc-csc u))
  389. (math-normalize
  390. (list 'calcFunc-cot u))))))))
  391. (put 'calcFunc-cot\' 'math-derivative-1
  392. (function (lambda (u) (math-neg
  393. (math-to-radians-2
  394. (math-sqr
  395. (math-normalize
  396. (list 'calcFunc-csc u))))))))
  397. (put 'calcFunc-arcsin\' 'math-derivative-1
  398. (function (lambda (u)
  399. (math-from-radians-2
  400. (math-div 1 (math-normalize
  401. (list 'calcFunc-sqrt
  402. (math-sub 1 (math-sqr u)))))))))
  403. (put 'calcFunc-arccos\' 'math-derivative-1
  404. (function (lambda (u)
  405. (math-from-radians-2
  406. (math-div -1 (math-normalize
  407. (list 'calcFunc-sqrt
  408. (math-sub 1 (math-sqr u)))))))))
  409. (put 'calcFunc-arctan\' 'math-derivative-1
  410. (function (lambda (u) (math-from-radians-2
  411. (math-div 1 (math-add 1 (math-sqr u)))))))
  412. (put 'calcFunc-sinh\' 'math-derivative-1
  413. (function (lambda (u) (math-normalize (list 'calcFunc-cosh u)))))
  414. (put 'calcFunc-cosh\' 'math-derivative-1
  415. (function (lambda (u) (math-normalize (list 'calcFunc-sinh u)))))
  416. (put 'calcFunc-tanh\' 'math-derivative-1
  417. (function (lambda (u) (math-sqr
  418. (math-normalize
  419. (list 'calcFunc-sech u))))))
  420. (put 'calcFunc-sech\' 'math-derivative-1
  421. (function (lambda (u) (math-neg
  422. (math-mul
  423. (math-normalize (list 'calcFunc-sech u))
  424. (math-normalize (list 'calcFunc-tanh u)))))))
  425. (put 'calcFunc-csch\' 'math-derivative-1
  426. (function (lambda (u) (math-neg
  427. (math-mul
  428. (math-normalize (list 'calcFunc-csch u))
  429. (math-normalize (list 'calcFunc-coth u)))))))
  430. (put 'calcFunc-coth\' 'math-derivative-1
  431. (function (lambda (u) (math-neg
  432. (math-sqr
  433. (math-normalize
  434. (list 'calcFunc-csch u)))))))
  435. (put 'calcFunc-arcsinh\' 'math-derivative-1
  436. (function (lambda (u)
  437. (math-div 1 (math-normalize
  438. (list 'calcFunc-sqrt
  439. (math-add (math-sqr u) 1)))))))
  440. (put 'calcFunc-arccosh\' 'math-derivative-1
  441. (function (lambda (u)
  442. (math-div 1 (math-normalize
  443. (list 'calcFunc-sqrt
  444. (math-add (math-sqr u) -1)))))))
  445. (put 'calcFunc-arctanh\' 'math-derivative-1
  446. (function (lambda (u) (math-div 1 (math-sub 1 (math-sqr u))))))
  447. (put 'calcFunc-bern\'2 'math-derivative-2
  448. (function (lambda (n x)
  449. (math-mul n (list 'calcFunc-bern (math-add n -1) x)))))
  450. (put 'calcFunc-euler\'2 'math-derivative-2
  451. (function (lambda (n x)
  452. (math-mul n (list 'calcFunc-euler (math-add n -1) x)))))
  453. (put 'calcFunc-gammag\'2 'math-derivative-2
  454. (function (lambda (a x) (math-deriv-gamma a x 1))))
  455. (put 'calcFunc-gammaG\'2 'math-derivative-2
  456. (function (lambda (a x) (math-deriv-gamma a x -1))))
  457. (put 'calcFunc-gammaP\'2 'math-derivative-2
  458. (function (lambda (a x) (math-deriv-gamma a x
  459. (math-div
  460. 1 (math-normalize
  461. (list 'calcFunc-gamma
  462. a)))))))
  463. (put 'calcFunc-gammaQ\'2 'math-derivative-2
  464. (function (lambda (a x) (math-deriv-gamma a x
  465. (math-div
  466. -1 (math-normalize
  467. (list 'calcFunc-gamma
  468. a)))))))
  469. (defun math-deriv-gamma (a x scale)
  470. (math-mul scale
  471. (math-mul (math-pow x (math-add a -1))
  472. (list 'calcFunc-exp (math-neg x)))))
  473. (put 'calcFunc-betaB\' 'math-derivative-3
  474. (function (lambda (x a b) (math-deriv-beta x a b 1))))
  475. (put 'calcFunc-betaI\' 'math-derivative-3
  476. (function (lambda (x a b) (math-deriv-beta x a b
  477. (math-div
  478. 1 (list 'calcFunc-beta
  479. a b))))))
  480. (defun math-deriv-beta (x a b scale)
  481. (math-mul (math-mul (math-pow x (math-add a -1))
  482. (math-pow (math-sub 1 x) (math-add b -1)))
  483. scale))
  484. (put 'calcFunc-erf\' 'math-derivative-1
  485. (function (lambda (x) (math-div 2
  486. (math-mul (list 'calcFunc-exp
  487. (math-sqr x))
  488. (if calc-symbolic-mode
  489. '(calcFunc-sqrt
  490. (var pi var-pi))
  491. (math-sqrt-pi)))))))
  492. (put 'calcFunc-erfc\' 'math-derivative-1
  493. (function (lambda (x) (math-div -2
  494. (math-mul (list 'calcFunc-exp
  495. (math-sqr x))
  496. (if calc-symbolic-mode
  497. '(calcFunc-sqrt
  498. (var pi var-pi))
  499. (math-sqrt-pi)))))))
  500. (put 'calcFunc-besJ\'2 'math-derivative-2
  501. (function (lambda (v z) (math-div (math-sub (list 'calcFunc-besJ
  502. (math-add v -1)
  503. z)
  504. (list 'calcFunc-besJ
  505. (math-add v 1)
  506. z))
  507. 2))))
  508. (put 'calcFunc-besY\'2 'math-derivative-2
  509. (function (lambda (v z) (math-div (math-sub (list 'calcFunc-besY
  510. (math-add v -1)
  511. z)
  512. (list 'calcFunc-besY
  513. (math-add v 1)
  514. z))
  515. 2))))
  516. (put 'calcFunc-sum 'math-derivative-n
  517. (function
  518. (lambda (expr)
  519. (if (math-expr-contains (cons 'vec (cdr (cdr expr))) math-deriv-var)
  520. (throw 'math-deriv nil)
  521. (cons 'calcFunc-sum
  522. (cons (math-derivative (nth 1 expr))
  523. (cdr (cdr expr))))))))
  524. (put 'calcFunc-prod 'math-derivative-n
  525. (function
  526. (lambda (expr)
  527. (if (math-expr-contains (cons 'vec (cdr (cdr expr))) math-deriv-var)
  528. (throw 'math-deriv nil)
  529. (math-mul expr
  530. (cons 'calcFunc-sum
  531. (cons (math-div (math-derivative (nth 1 expr))
  532. (nth 1 expr))
  533. (cdr (cdr expr)))))))))
  534. (put 'calcFunc-integ 'math-derivative-n
  535. (function
  536. (lambda (expr)
  537. (if (= (length expr) 3)
  538. (if (equal (nth 2 expr) math-deriv-var)
  539. (nth 1 expr)
  540. (math-normalize
  541. (list 'calcFunc-integ
  542. (math-derivative (nth 1 expr))
  543. (nth 2 expr))))
  544. (if (= (length expr) 5)
  545. (let ((lower (math-expr-subst (nth 1 expr) (nth 2 expr)
  546. (nth 3 expr)))
  547. (upper (math-expr-subst (nth 1 expr) (nth 2 expr)
  548. (nth 4 expr))))
  549. (math-add (math-sub (math-mul upper
  550. (math-derivative (nth 4 expr)))
  551. (math-mul lower
  552. (math-derivative (nth 3 expr))))
  553. (if (equal (nth 2 expr) math-deriv-var)
  554. 0
  555. (math-normalize
  556. (list 'calcFunc-integ
  557. (math-derivative (nth 1 expr)) (nth 2 expr)
  558. (nth 3 expr) (nth 4 expr)))))))))))
  559. (put 'calcFunc-if 'math-derivative-n
  560. (function
  561. (lambda (expr)
  562. (and (= (length expr) 4)
  563. (list 'calcFunc-if (nth 1 expr)
  564. (math-derivative (nth 2 expr))
  565. (math-derivative (nth 3 expr)))))))
  566. (put 'calcFunc-subscr 'math-derivative-n
  567. (function
  568. (lambda (expr)
  569. (and (= (length expr) 3)
  570. (list 'calcFunc-subscr (nth 1 expr)
  571. (math-derivative (nth 2 expr)))))))
  572. (defvar math-integ-var '(var X ---))
  573. (defvar math-integ-var-2 '(var Y ---))
  574. (defvar math-integ-vars (list 'f math-integ-var math-integ-var-2))
  575. (defvar math-integ-var-list (list math-integ-var))
  576. (defvar math-integ-var-list-list (list math-integ-var-list))
  577. ;; math-integ-depth is a local variable for math-try-integral, but is used
  578. ;; by math-integral and math-tracing-integral
  579. ;; which are called (directly or indirectly) by math-try-integral.
  580. (defvar math-integ-depth)
  581. ;; math-integ-level is a local variable for math-try-integral, but is used
  582. ;; by math-integral, math-do-integral, math-tracing-integral,
  583. ;; math-sub-integration, math-integrate-by-parts and
  584. ;; math-integrate-by-substitution, which are called (directly or
  585. ;; indirectly) by math-try-integral.
  586. (defvar math-integ-level)
  587. ;; math-integral-limit is a local variable for calcFunc-integ, but is
  588. ;; used by math-tracing-integral, math-sub-integration and
  589. ;; math-try-integration.
  590. (defvar math-integral-limit)
  591. (defmacro math-tracing-integral (&rest parts)
  592. (list 'and
  593. 'trace-buffer
  594. (list 'with-current-buffer
  595. 'trace-buffer
  596. '(goto-char (point-max))
  597. (list 'and
  598. '(bolp)
  599. '(insert (make-string (- math-integral-limit
  600. math-integ-level) 32)
  601. (format "%2d " math-integ-depth)
  602. (make-string math-integ-level 32)))
  603. ;;(list 'condition-case 'err
  604. (cons 'insert parts)
  605. ;; '(error (insert (prin1-to-string err))))
  606. '(sit-for 0))))
  607. ;;; The following wrapper caches results and avoids infinite recursion.
  608. ;;; Each cache entry is: ( A B ) Integral of A is B;
  609. ;;; ( A N ) Integral of A failed at level N;
  610. ;;; ( A busy ) Currently working on integral of A;
  611. ;;; ( A parts ) Currently working, integ-by-parts;
  612. ;;; ( A parts2 ) Currently working, integ-by-parts;
  613. ;;; ( A cancelled ) Ignore this cache entry;
  614. ;;; ( A [B] ) Same result as for math-cur-record = B.
  615. ;; math-cur-record is a local variable for math-try-integral, but is used
  616. ;; by math-integral, math-replace-integral-parts and math-integrate-by-parts
  617. ;; which are called (directly or indirectly) by math-try-integral, as well as
  618. ;; by calc-dump-integral-cache
  619. (defvar math-cur-record)
  620. ;; math-enable-subst and math-any-substs are local variables for
  621. ;; calcFunc-integ, but are used by math-integral and math-try-integral.
  622. (defvar math-enable-subst)
  623. (defvar math-any-substs)
  624. ;; math-integ-msg is a local variable for math-try-integral, but is
  625. ;; used (both locally and non-locally) by math-integral.
  626. (defvar math-integ-msg)
  627. (defvar math-integral-cache nil)
  628. (defvar math-integral-cache-state nil)
  629. (defun math-integral (expr &optional simplify same-as-above)
  630. (let* ((simp math-cur-record)
  631. (math-cur-record (assoc expr math-integral-cache))
  632. (math-integ-depth (1+ math-integ-depth))
  633. (val 'cancelled))
  634. (math-tracing-integral "Integrating "
  635. (math-format-value expr 1000)
  636. "...\n")
  637. (and math-cur-record
  638. (progn
  639. (math-tracing-integral "Found "
  640. (math-format-value (nth 1 math-cur-record) 1000))
  641. (and (consp (nth 1 math-cur-record))
  642. (math-replace-integral-parts math-cur-record))
  643. (math-tracing-integral " => "
  644. (math-format-value (nth 1 math-cur-record) 1000)
  645. "\n")))
  646. (or (and math-cur-record
  647. (not (eq (nth 1 math-cur-record) 'cancelled))
  648. (or (not (integerp (nth 1 math-cur-record)))
  649. (>= (nth 1 math-cur-record) math-integ-level)))
  650. (and (math-integral-contains-parts expr)
  651. (progn
  652. (setq val nil)
  653. t))
  654. (unwind-protect
  655. (progn
  656. (let (math-integ-msg)
  657. (if (eq calc-display-working-message 'lots)
  658. (progn
  659. (calc-set-command-flag 'clear-message)
  660. (setq math-integ-msg (format
  661. "Working... Integrating %s"
  662. (math-format-flat-expr expr 0)))
  663. (message "%s" math-integ-msg)))
  664. (if math-cur-record
  665. (setcar (cdr math-cur-record)
  666. (if same-as-above (vector simp) 'busy))
  667. (setq math-cur-record
  668. (list expr (if same-as-above (vector simp) 'busy))
  669. math-integral-cache (cons math-cur-record
  670. math-integral-cache)))
  671. (if (eq simplify 'yes)
  672. (progn
  673. (math-tracing-integral "Simplifying...")
  674. (setq simp (math-simplify expr))
  675. (setq val (if (equal simp expr)
  676. (progn
  677. (math-tracing-integral " no change\n")
  678. (math-do-integral expr))
  679. (math-tracing-integral " simplified\n")
  680. (math-integral simp 'no t))))
  681. (or (setq val (math-do-integral expr))
  682. (eq simplify 'no)
  683. (let ((simp (math-simplify expr)))
  684. (or (equal simp expr)
  685. (progn
  686. (math-tracing-integral "Trying again after "
  687. "simplification...\n")
  688. (setq val (math-integral simp 'no t))))))))
  689. (if (eq calc-display-working-message 'lots)
  690. (message "%s" math-integ-msg)))
  691. (setcar (cdr math-cur-record) (or val
  692. (if (or math-enable-subst
  693. (not math-any-substs))
  694. math-integ-level
  695. 'cancelled)))))
  696. (setq val math-cur-record)
  697. (while (vectorp (nth 1 val))
  698. (setq val (aref (nth 1 val) 0)))
  699. (setq val (if (memq (nth 1 val) '(parts parts2))
  700. (progn
  701. (setcar (cdr val) 'parts2)
  702. (list 'var 'PARTS val))
  703. (and (consp (nth 1 val))
  704. (nth 1 val))))
  705. (math-tracing-integral "Integral of "
  706. (math-format-value expr 1000)
  707. " is "
  708. (math-format-value val 1000)
  709. "\n")
  710. val))
  711. (defun math-integral-contains-parts (expr)
  712. (if (Math-primp expr)
  713. (and (eq (car-safe expr) 'var)
  714. (eq (nth 1 expr) 'PARTS)
  715. (listp (nth 2 expr)))
  716. (while (and (setq expr (cdr expr))
  717. (not (math-integral-contains-parts (car expr)))))
  718. expr))
  719. (defun math-replace-integral-parts (expr)
  720. (or (Math-primp expr)
  721. (while (setq expr (cdr expr))
  722. (and (consp (car expr))
  723. (if (eq (car (car expr)) 'var)
  724. (and (eq (nth 1 (car expr)) 'PARTS)
  725. (consp (nth 2 (car expr)))
  726. (if (listp (nth 1 (nth 2 (car expr))))
  727. (progn
  728. (setcar expr (nth 1 (nth 2 (car expr))))
  729. (math-replace-integral-parts (cons 'foo expr)))
  730. (setcar (cdr math-cur-record) 'cancelled)))
  731. (math-replace-integral-parts (car expr)))))))
  732. (defvar math-linear-subst-tried t
  733. "Non-nil means that a linear substitution has been tried.")
  734. ;; The variable math-has-rules is a local variable for math-try-integral,
  735. ;; but is used by math-do-integral, which is called (non-directly) by
  736. ;; math-try-integral.
  737. (defvar math-has-rules)
  738. ;; math-old-integ is a local variable for math-do-integral, but is
  739. ;; used by math-sub-integration.
  740. (defvar math-old-integ)
  741. ;; The variables math-t1, math-t2 and math-t3 are local to
  742. ;; math-do-integral, math-try-solve-for and math-decompose-poly, but
  743. ;; are used by functions they call (directly or indirectly);
  744. ;; math-do-integral calls math-do-integral-methods;
  745. ;; math-try-solve-for calls math-try-solve-prod,
  746. ;; math-solve-find-root-term and math-solve-find-root-in-prod;
  747. ;; math-decompose-poly calls math-solve-poly-funny-powers and
  748. ;; math-solve-crunch-poly.
  749. (defvar math-t1)
  750. (defvar math-t2)
  751. (defvar math-t3)
  752. (defun math-do-integral (expr)
  753. (let ((math-linear-subst-tried nil)
  754. math-t1 math-t2)
  755. (or (cond ((not (math-expr-contains expr math-integ-var))
  756. (math-mul expr math-integ-var))
  757. ((equal expr math-integ-var)
  758. (math-div (math-sqr expr) 2))
  759. ((eq (car expr) '+)
  760. (and (setq math-t1 (math-integral (nth 1 expr)))
  761. (setq math-t2 (math-integral (nth 2 expr)))
  762. (math-add math-t1 math-t2)))
  763. ((eq (car expr) '-)
  764. (and (setq math-t1 (math-integral (nth 1 expr)))
  765. (setq math-t2 (math-integral (nth 2 expr)))
  766. (math-sub math-t1 math-t2)))
  767. ((eq (car expr) 'neg)
  768. (and (setq math-t1 (math-integral (nth 1 expr)))
  769. (math-neg math-t1)))
  770. ((eq (car expr) '*)
  771. (cond ((not (math-expr-contains (nth 1 expr) math-integ-var))
  772. (and (setq math-t1 (math-integral (nth 2 expr)))
  773. (math-mul (nth 1 expr) math-t1)))
  774. ((not (math-expr-contains (nth 2 expr) math-integ-var))
  775. (and (setq math-t1 (math-integral (nth 1 expr)))
  776. (math-mul math-t1 (nth 2 expr))))
  777. ((memq (car-safe (nth 1 expr)) '(+ -))
  778. (math-integral (list (car (nth 1 expr))
  779. (math-mul (nth 1 (nth 1 expr))
  780. (nth 2 expr))
  781. (math-mul (nth 2 (nth 1 expr))
  782. (nth 2 expr)))
  783. 'yes t))
  784. ((memq (car-safe (nth 2 expr)) '(+ -))
  785. (math-integral (list (car (nth 2 expr))
  786. (math-mul (nth 1 (nth 2 expr))
  787. (nth 1 expr))
  788. (math-mul (nth 2 (nth 2 expr))
  789. (nth 1 expr)))
  790. 'yes t))))
  791. ((eq (car expr) '/)
  792. (cond ((and (not (math-expr-contains (nth 1 expr)
  793. math-integ-var))
  794. (not (math-equal-int (nth 1 expr) 1)))
  795. (and (setq math-t1 (math-integral (math-div 1 (nth 2 expr))))
  796. (math-mul (nth 1 expr) math-t1)))
  797. ((not (math-expr-contains (nth 2 expr) math-integ-var))
  798. (and (setq math-t1 (math-integral (nth 1 expr)))
  799. (math-div math-t1 (nth 2 expr))))
  800. ((and (eq (car-safe (nth 1 expr)) '*)
  801. (not (math-expr-contains (nth 1 (nth 1 expr))
  802. math-integ-var)))
  803. (and (setq math-t1 (math-integral
  804. (math-div (nth 2 (nth 1 expr))
  805. (nth 2 expr))))
  806. (math-mul math-t1 (nth 1 (nth 1 expr)))))
  807. ((and (eq (car-safe (nth 1 expr)) '*)
  808. (not (math-expr-contains (nth 2 (nth 1 expr))
  809. math-integ-var)))
  810. (and (setq math-t1 (math-integral
  811. (math-div (nth 1 (nth 1 expr))
  812. (nth 2 expr))))
  813. (math-mul math-t1 (nth 2 (nth 1 expr)))))
  814. ((and (eq (car-safe (nth 2 expr)) '*)
  815. (not (math-expr-contains (nth 1 (nth 2 expr))
  816. math-integ-var)))
  817. (and (setq math-t1 (math-integral
  818. (math-div (nth 1 expr)
  819. (nth 2 (nth 2 expr)))))
  820. (math-div math-t1 (nth 1 (nth 2 expr)))))
  821. ((and (eq (car-safe (nth 2 expr)) '*)
  822. (not (math-expr-contains (nth 2 (nth 2 expr))
  823. math-integ-var)))
  824. (and (setq math-t1 (math-integral
  825. (math-div (nth 1 expr)
  826. (nth 1 (nth 2 expr)))))
  827. (math-div math-t1 (nth 2 (nth 2 expr)))))
  828. ((eq (car-safe (nth 2 expr)) 'calcFunc-exp)
  829. (math-integral
  830. (math-mul (nth 1 expr)
  831. (list 'calcFunc-exp
  832. (math-neg (nth 1 (nth 2 expr)))))))))
  833. ((eq (car expr) '^)
  834. (cond ((not (math-expr-contains (nth 1 expr) math-integ-var))
  835. (or (and (setq math-t1 (math-is-polynomial (nth 2 expr)
  836. math-integ-var 1))
  837. (math-div expr
  838. (math-mul (nth 1 math-t1)
  839. (math-normalize
  840. (list 'calcFunc-ln
  841. (nth 1 expr))))))
  842. (math-integral
  843. (list 'calcFunc-exp
  844. (math-mul (nth 2 expr)
  845. (math-normalize
  846. (list 'calcFunc-ln
  847. (nth 1 expr)))))
  848. 'yes t)))
  849. ((not (math-expr-contains (nth 2 expr) math-integ-var))
  850. (if (and (integerp (nth 2 expr)) (< (nth 2 expr) 0))
  851. (math-integral
  852. (list '/ 1 (math-pow (nth 1 expr) (- (nth 2 expr))))
  853. nil t)
  854. (or (and (setq math-t1 (math-is-polynomial (nth 1 expr)
  855. math-integ-var
  856. 1))
  857. (setq math-t2 (math-add (nth 2 expr) 1))
  858. (math-div (math-pow (nth 1 expr) math-t2)
  859. (math-mul math-t2 (nth 1 math-t1))))
  860. (and (Math-negp (nth 2 expr))
  861. (math-integral
  862. (math-div 1
  863. (math-pow (nth 1 expr)
  864. (math-neg
  865. (nth 2 expr))))
  866. nil t))
  867. nil))))))
  868. ;; Integral of a polynomial.
  869. (and (setq math-t1 (math-is-polynomial expr math-integ-var 20))
  870. (let ((accum 0)
  871. (n 1))
  872. (while math-t1
  873. (if (setq accum (math-add accum
  874. (math-div (math-mul (car math-t1)
  875. (math-pow
  876. math-integ-var
  877. n))
  878. n))
  879. math-t1 (cdr math-t1))
  880. (setq n (1+ n))))
  881. accum))
  882. ;; Try looking it up!
  883. (cond ((= (length expr) 2)
  884. (and (symbolp (car expr))
  885. (setq math-t1 (get (car expr) 'math-integral))
  886. (progn
  887. (while (and math-t1
  888. (not (setq math-t2 (funcall (car math-t1)
  889. (nth 1 expr)))))
  890. (setq math-t1 (cdr math-t1)))
  891. (and math-t2 (math-normalize math-t2)))))
  892. ((= (length expr) 3)
  893. (and (symbolp (car expr))
  894. (setq math-t1 (get (car expr) 'math-integral-2))
  895. (progn
  896. (while (and math-t1
  897. (not (setq math-t2 (funcall (car math-t1)
  898. (nth 1 expr)
  899. (nth 2 expr)))))
  900. (setq math-t1 (cdr math-t1)))
  901. (and math-t2 (math-normalize math-t2))))))
  902. ;; Integral of a rational function.
  903. (and (math-ratpoly-p expr math-integ-var)
  904. (setq math-t1 (calcFunc-apart expr math-integ-var))
  905. (not (equal math-t1 expr))
  906. (math-integral math-t1))
  907. ;; Try user-defined integration rules.
  908. (and math-has-rules
  909. (let ((math-old-integ (symbol-function 'calcFunc-integ))
  910. (input (list 'calcFunc-integtry expr math-integ-var))
  911. res part)
  912. (unwind-protect
  913. (progn
  914. (fset 'calcFunc-integ 'math-sub-integration)
  915. (setq res (math-rewrite input
  916. '(var IntegRules var-IntegRules)
  917. 1))
  918. (fset 'calcFunc-integ math-old-integ)
  919. (and (not (equal res input))
  920. (if (setq part (math-expr-calls
  921. res '(calcFunc-integsubst)))
  922. (and (memq (length part) '(3 4 5))
  923. (let ((parts (mapcar
  924. (function
  925. (lambda (x)
  926. (math-expr-subst
  927. x (nth 2 part)
  928. math-integ-var)))
  929. (cdr part))))
  930. (math-integrate-by-substitution
  931. expr (car parts) t
  932. (or (nth 2 parts)
  933. (list 'calcFunc-integfailed
  934. math-integ-var))
  935. (nth 3 parts))))
  936. (if (not (math-expr-calls res
  937. '(calcFunc-integtry
  938. calcFunc-integfailed)))
  939. res))))
  940. (fset 'calcFunc-integ math-old-integ))))
  941. ;; See if the function is a symbolic derivative.
  942. (and (string-match "'" (symbol-name (car expr)))
  943. (let ((name (symbol-name (car expr)))
  944. (p expr) (n 0) (which nil) (bad nil))
  945. (while (setq n (1+ n) p (cdr p))
  946. (if (equal (car p) math-integ-var)
  947. (if which (setq bad t) (setq which n))
  948. (if (math-expr-contains (car p) math-integ-var)
  949. (setq bad t))))
  950. (and which (not bad)
  951. (let ((prime (if (= which 1) "'" (format "'%d" which))))
  952. (and (string-match (concat prime "\\('['0-9]*\\|$\\)")
  953. name)
  954. (cons (intern
  955. (concat
  956. (substring name 0 (match-beginning 0))
  957. (substring name (+ (match-beginning 0)
  958. (length prime)))))
  959. (cdr expr)))))))
  960. ;; Try transformation methods (parts, substitutions).
  961. (and (> math-integ-level 0)
  962. (math-do-integral-methods expr))
  963. ;; Try expanding the function's definition.
  964. (let ((res (math-expand-formula expr)))
  965. (and res
  966. (math-integral res))))))
  967. (defun math-sub-integration (expr &rest rest)
  968. (or (if (or (not rest)
  969. (and (< math-integ-level math-integral-limit)
  970. (eq (car rest) math-integ-var)))
  971. (math-integral expr)
  972. (let ((res (apply math-old-integ expr rest)))
  973. (and (or (= math-integ-level math-integral-limit)
  974. (not (math-expr-calls res 'calcFunc-integ)))
  975. res)))
  976. (list 'calcFunc-integfailed expr)))
  977. ;; math-so-far is a local variable for math-do-integral-methods, but
  978. ;; is used by math-integ-try-linear-substitutions and
  979. ;; math-integ-try-substitutions.
  980. (defvar math-so-far)
  981. ;; math-integ-expr is a local variable for math-do-integral-methods,
  982. ;; but is used by math-integ-try-linear-substitutions and
  983. ;; math-integ-try-substitutions.
  984. (defvar math-integ-expr)
  985. (defun math-do-integral-methods (math-integ-expr)
  986. (let ((math-so-far math-integ-var-list-list)
  987. rat-in)
  988. ;; Integration by substitution, for various likely sub-expressions.
  989. ;; (In first pass, we look only for sub-exprs that are linear in X.)
  990. (or (math-integ-try-linear-substitutions math-integ-expr)
  991. (math-integ-try-substitutions math-integ-expr)
  992. ;; If function has sines and cosines, try tan(x/2) substitution.
  993. (and (let ((p (setq rat-in (math-expr-rational-in math-integ-expr))))
  994. (while (and p
  995. (memq (car (car p)) '(calcFunc-sin
  996. calcFunc-cos
  997. calcFunc-tan
  998. calcFunc-sec
  999. calcFunc-csc
  1000. calcFunc-cot))
  1001. (equal (nth 1 (car p)) math-integ-var))
  1002. (setq p (cdr p)))
  1003. (null p))
  1004. (or (and (math-integ-parts-easy math-integ-expr)
  1005. (math-integ-try-parts math-integ-expr t))
  1006. (math-integrate-by-good-substitution
  1007. math-integ-expr (list 'calcFunc-tan (math-div math-integ-var 2)))))
  1008. ;; If function has sinh and cosh, try tanh(x/2) substitution.
  1009. (and (let ((p rat-in))
  1010. (while (and p
  1011. (memq (car (car p)) '(calcFunc-sinh
  1012. calcFunc-cosh
  1013. calcFunc-tanh
  1014. calcFunc-sech
  1015. calcFunc-csch
  1016. calcFunc-coth
  1017. calcFunc-exp))
  1018. (equal (nth 1 (car p)) math-integ-var))
  1019. (setq p (cdr p)))
  1020. (null p))
  1021. (or (and (math-integ-parts-easy math-integ-expr)
  1022. (math-integ-try-parts math-integ-expr t))
  1023. (math-integrate-by-good-substitution
  1024. math-integ-expr (list 'calcFunc-tanh (math-div math-integ-var 2)))))
  1025. ;; If function has square roots, try sin, tan, or sec substitution.
  1026. (and (let ((p rat-in))
  1027. (setq math-t1 nil)
  1028. (while (and p
  1029. (or (equal (car p) math-integ-var)
  1030. (and (eq (car (car p)) 'calcFunc-sqrt)
  1031. (setq math-t1 (math-is-polynomial
  1032. (nth 1 (setq math-t2 (car p)))
  1033. math-integ-var 2)))))
  1034. (setq p (cdr p)))
  1035. (and (null p) math-t1))
  1036. (if (cdr (cdr math-t1))
  1037. (if (math-guess-if-neg (nth 2 math-t1))
  1038. (let* ((c (math-sqrt (math-neg (nth 2 math-t1))))
  1039. (d (math-div (nth 1 math-t1) (math-mul -2 c)))
  1040. (a (math-sqrt (math-add (car math-t1) (math-sqr d)))))
  1041. (math-integrate-by-good-substitution
  1042. math-integ-expr (list 'calcFunc-arcsin
  1043. (math-div-thru
  1044. (math-add (math-mul c math-integ-var) d)
  1045. a))))
  1046. (let* ((c (math-sqrt (nth 2 math-t1)))
  1047. (d (math-div (nth 1 math-t1) (math-mul 2 c)))
  1048. (aa (math-sub (car math-t1) (math-sqr d))))
  1049. (if (and nil (not (and (eq d 0) (eq c 1))))
  1050. (math-integrate-by-good-substitution
  1051. math-integ-expr (math-add (math-mul c math-integ-var) d))
  1052. (if (math-guess-if-neg aa)
  1053. (math-integrate-by-good-substitution
  1054. math-integ-expr (list 'calcFunc-arccosh
  1055. (math-div-thru
  1056. (math-add (math-mul c math-integ-var)
  1057. d)
  1058. (math-sqrt (math-neg aa)))))
  1059. (math-integrate-by-good-substitution
  1060. math-integ-expr (list 'calcFunc-arcsinh
  1061. (math-div-thru
  1062. (math-add (math-mul c math-integ-var)
  1063. d)
  1064. (math-sqrt aa))))))))
  1065. (math-integrate-by-good-substitution math-integ-expr math-t2)) )
  1066. ;; Try integration by parts.
  1067. (math-integ-try-parts math-integ-expr)
  1068. ;; Give up.
  1069. nil)))
  1070. (defun math-integ-parts-easy (expr)
  1071. (cond ((Math-primp expr) t)
  1072. ((memq (car expr) '(+ - *))
  1073. (and (math-integ-parts-easy (nth 1 expr))
  1074. (math-integ-parts-easy (nth 2 expr))))
  1075. ((eq (car expr) '/)
  1076. (and (math-integ-parts-easy (nth 1 expr))
  1077. (math-atomic-factorp (nth 2 expr))))
  1078. ((eq (car expr) '^)
  1079. (and (natnump (nth 2 expr))
  1080. (math-integ-parts-easy (nth 1 expr))))
  1081. ((eq (car expr) 'neg)
  1082. (math-integ-parts-easy (nth 1 expr)))
  1083. (t t)))
  1084. ;; math-prev-parts-v is local to calcFunc-integ (as well as
  1085. ;; math-integrate-by-parts), but is used by math-integ-try-parts.
  1086. (defvar math-prev-parts-v)
  1087. ;; math-good-parts is local to calcFunc-integ (as well as
  1088. ;; math-integ-try-parts), but is used by math-integrate-by-parts.
  1089. (defvar math-good-parts)
  1090. (defun math-integ-try-parts (expr &optional math-good-parts)
  1091. ;; Integration by parts:
  1092. ;; integ(f(x) g(x),x) = f(x) h(x) - integ(h(x) f'(x),x)
  1093. ;; where h(x) = integ(g(x),x).
  1094. (or (let ((exp (calcFunc-expand expr)))
  1095. (and (not (equal exp expr))
  1096. (math-integral exp)))
  1097. (and (eq (car expr) '*)
  1098. (let ((first-bad (or (math-polynomial-p (nth 1 expr)
  1099. math-integ-var)
  1100. (equal (nth 2 expr) math-prev-parts-v))))
  1101. (or (and first-bad ; so try this one first
  1102. (math-integrate-by-parts (nth 1 expr) (nth 2 expr)))
  1103. (math-integrate-by-parts (nth 2 expr) (nth 1 expr))
  1104. (and (not first-bad)
  1105. (math-integrate-by-parts (nth 1 expr) (nth 2 expr))))))
  1106. (and (eq (car expr) '/)
  1107. (math-expr-contains (nth 1 expr) math-integ-var)
  1108. (let ((recip (math-div 1 (nth 2 expr))))
  1109. (or (math-integrate-by-parts (nth 1 expr) recip)
  1110. (math-integrate-by-parts recip (nth 1 expr)))))
  1111. (and (eq (car expr) '^)
  1112. (math-integrate-by-parts (math-pow (nth 1 expr)
  1113. (math-sub (nth 2 expr) 1))
  1114. (nth 1 expr)))))
  1115. (defun math-integrate-by-parts (u vprime)
  1116. (let ((math-integ-level (if (or math-good-parts
  1117. (math-polynomial-p u math-integ-var))
  1118. math-integ-level
  1119. (1- math-integ-level)))
  1120. (math-doing-parts t)
  1121. v temp)
  1122. (and (>= math-integ-level 0)
  1123. (unwind-protect
  1124. (progn
  1125. (setcar (cdr math-cur-record) 'parts)
  1126. (math-tracing-integral "Integrating by parts, u = "
  1127. (math-format-value u 1000)
  1128. ", v' = "
  1129. (math-format-value vprime 1000)
  1130. "\n")
  1131. (and (setq v (math-integral vprime))
  1132. (setq temp (calcFunc-deriv u math-integ-var nil t))
  1133. (setq temp (let ((math-prev-parts-v v))
  1134. (math-integral (math-mul v temp) 'yes)))
  1135. (setq temp (math-sub (math-mul u v) temp))
  1136. (if (eq (nth 1 math-cur-record) 'parts)
  1137. (calcFunc-expand temp)
  1138. (setq v (list 'var 'PARTS math-cur-record)
  1139. temp (let (calc-next-why)
  1140. (math-simplify-extended
  1141. (math-solve-for (math-sub v temp) 0 v nil)))
  1142. temp (if (and (eq (car-safe temp) '/)
  1143. (math-zerop (nth 2 temp)))
  1144. nil temp)))))
  1145. (setcar (cdr math-cur-record) 'busy)))))
  1146. ;;; This tries two different formulations, hoping the algebraic simplifier
  1147. ;;; will be strong enough to handle at least one.
  1148. (defun math-integrate-by-substitution (expr u &optional user uinv uinvprime)
  1149. (and (> math-integ-level 0)
  1150. (let ((math-integ-level (max (- math-integ-level 2) 0)))
  1151. (math-integrate-by-good-substitution expr u user uinv uinvprime))))
  1152. (defun math-integrate-by-good-substitution (expr u &optional user
  1153. uinv uinvprime)
  1154. (let ((math-living-dangerously t)
  1155. deriv temp)
  1156. (and (setq uinv (if uinv
  1157. (math-expr-subst uinv math-integ-var
  1158. math-integ-var-2)
  1159. (let (calc-next-why)
  1160. (math-solve-for u
  1161. math-integ-var-2
  1162. math-integ-var nil))))
  1163. (progn
  1164. (math-tracing-integral "Integrating by substitution, u = "
  1165. (math-format-value u 1000)
  1166. "\n")
  1167. (or (and (setq deriv (calcFunc-deriv u
  1168. math-integ-var nil
  1169. (not user)))
  1170. (setq temp (math-integral (math-expr-subst
  1171. (math-expr-subst
  1172. (math-expr-subst
  1173. (math-div expr deriv)
  1174. u
  1175. math-integ-var-2)
  1176. math-integ-var
  1177. uinv)
  1178. math-integ-var-2
  1179. math-integ-var)
  1180. 'yes)))
  1181. (and (setq deriv (or uinvprime
  1182. (calcFunc-deriv uinv
  1183. math-integ-var-2
  1184. math-integ-var
  1185. (not user))))
  1186. (setq temp (math-integral (math-mul
  1187. (math-expr-subst
  1188. (math-expr-subst
  1189. (math-expr-subst
  1190. expr
  1191. u
  1192. math-integ-var-2)
  1193. math-integ-var
  1194. uinv)
  1195. math-integ-var-2
  1196. math-integ-var)
  1197. deriv)
  1198. 'yes)))))
  1199. (math-simplify-extended
  1200. (math-expr-subst temp math-integ-var u)))))
  1201. ;;; Look for substitutions of the form u = a x + b.
  1202. (defun math-integ-try-linear-substitutions (sub-expr)
  1203. (setq math-linear-subst-tried t)
  1204. (and (not (Math-primp sub-expr))
  1205. (or (and (not (memq (car sub-expr) '(+ - * / neg)))
  1206. (not (and (eq (car sub-expr) '^)
  1207. (integerp (nth 2 sub-expr))))
  1208. (math-expr-contains sub-expr math-integ-var)
  1209. (let ((res nil))
  1210. (while (and (setq sub-expr (cdr sub-expr))
  1211. (or (not (math-linear-in (car sub-expr)
  1212. math-integ-var))
  1213. (assoc (car sub-expr) math-so-far)
  1214. (progn
  1215. (setq math-so-far (cons (list (car sub-expr))
  1216. math-so-far))
  1217. (not (setq res
  1218. (math-integrate-by-substitution
  1219. math-integ-expr (car sub-expr))))))))
  1220. res))
  1221. (let ((res nil))
  1222. (while (and (setq sub-expr (cdr sub-expr))
  1223. (not (setq res (math-integ-try-linear-substitutions
  1224. (car sub-expr))))))
  1225. res))))
  1226. ;;; Recursively try different substitutions based on various sub-expressions.
  1227. (defun math-integ-try-substitutions (sub-expr &optional allow-rat)
  1228. (and (not (Math-primp sub-expr))
  1229. (not (assoc sub-expr math-so-far))
  1230. (math-expr-contains sub-expr math-integ-var)
  1231. (or (and (if (and (not (memq (car sub-expr) '(+ - * / neg)))
  1232. (not (and (eq (car sub-expr) '^)
  1233. (integerp (nth 2 sub-expr)))))
  1234. (setq allow-rat t)
  1235. (prog1 allow-rat (setq allow-rat nil)))
  1236. (not (eq sub-expr math-integ-expr))
  1237. (or (math-integrate-by-substitution math-integ-expr sub-expr)
  1238. (and (eq (car sub-expr) '^)
  1239. (integerp (nth 2 sub-expr))
  1240. (< (nth 2 sub-expr) 0)
  1241. (math-integ-try-substitutions
  1242. (math-pow (nth 1 sub-expr) (- (nth 2 sub-expr)))
  1243. t))))
  1244. (let ((res nil))
  1245. (setq math-so-far (cons (list sub-expr) math-so-far))
  1246. (while (and (setq sub-expr (cdr sub-expr))
  1247. (not (setq res (math-integ-try-substitutions
  1248. (car sub-expr) allow-rat)))))
  1249. res))))
  1250. ;; The variable math-expr-parts is local to math-expr-rational-in,
  1251. ;; but is used by math-expr-rational-in-rec
  1252. (defvar math-expr-parts)
  1253. (defun math-expr-rational-in (expr)
  1254. (let ((math-expr-parts nil))
  1255. (math-expr-rational-in-rec expr)
  1256. (mapcar 'car math-expr-parts)))
  1257. (defun math-expr-rational-in-rec (expr)
  1258. (cond ((Math-primp expr)
  1259. (and (equal expr math-integ-var)
  1260. (not (assoc expr math-expr-parts))
  1261. (setq math-expr-parts (cons (list expr) math-expr-parts))))
  1262. ((or (memq (car expr) '(+ - * / neg))
  1263. (and (eq (car expr) '^) (integerp (nth 2 expr))))
  1264. (math-expr-rational-in-rec (nth 1 expr))
  1265. (and (nth 2 expr) (math-expr-rational-in-rec (nth 2 expr))))
  1266. ((and (eq (car expr) '^)
  1267. (eq (math-quarter-integer (nth 2 expr)) 2))
  1268. (math-expr-rational-in-rec (list 'calcFunc-sqrt (nth 1 expr))))
  1269. (t
  1270. (and (not (assoc expr math-expr-parts))
  1271. (math-expr-contains expr math-integ-var)
  1272. (setq math-expr-parts (cons (list expr) math-expr-parts))))))
  1273. (defun math-expr-calls (expr funcs &optional arg-contains)
  1274. (if (consp expr)
  1275. (if (or (memq (car expr) funcs)
  1276. (and (eq (car expr) '^) (eq (car funcs) 'calcFunc-sqrt)
  1277. (eq (math-quarter-integer (nth 2 expr)) 2)))
  1278. (and (or (not arg-contains)
  1279. (math-expr-contains expr arg-contains))
  1280. expr)
  1281. (and (not (Math-primp expr))
  1282. (let ((res nil))
  1283. (while (and (setq expr (cdr expr))
  1284. (not (setq res (math-expr-calls
  1285. (car expr) funcs arg-contains)))))
  1286. res)))))
  1287. (defun math-fix-const-terms (expr except-vars)
  1288. (cond ((not (math-expr-depends expr except-vars)) 0)
  1289. ((Math-primp expr) expr)
  1290. ((eq (car expr) '+)
  1291. (math-add (math-fix-const-terms (nth 1 expr) except-vars)
  1292. (math-fix-const-terms (nth 2 expr) except-vars)))
  1293. ((eq (car expr) '-)
  1294. (math-sub (math-fix-const-terms (nth 1 expr) except-vars)
  1295. (math-fix-const-terms (nth 2 expr) except-vars)))
  1296. (t expr)))
  1297. ;; Command for debugging the Calculator's symbolic integrator.
  1298. (defun calc-dump-integral-cache (&optional arg)
  1299. (interactive "P")
  1300. (let ((buf (current-buffer)))
  1301. (unwind-protect
  1302. (let ((p math-integral-cache)
  1303. math-cur-record)
  1304. (display-buffer (get-buffer-create "*Integral Cache*"))
  1305. (set-buffer (get-buffer "*Integral Cache*"))
  1306. (erase-buffer)
  1307. (while p
  1308. (setq math-cur-record (car p))
  1309. (or arg (math-replace-integral-parts math-cur-record))
  1310. (insert (math-format-flat-expr (car math-cur-record) 0)
  1311. " --> "
  1312. (if (symbolp (nth 1 math-cur-record))
  1313. (concat "(" (symbol-name (nth 1 math-cur-record)) ")")
  1314. (math-format-flat-expr (nth 1 math-cur-record) 0))
  1315. "\n")
  1316. (setq p (cdr p)))
  1317. (goto-char (point-min)))
  1318. (set-buffer buf))))
  1319. ;; The variable math-max-integral-limit is local to calcFunc-integ,
  1320. ;; but is used by math-try-integral.
  1321. (defvar math-max-integral-limit)
  1322. (defun math-try-integral (expr)
  1323. (let ((math-integ-level math-integral-limit)
  1324. (math-integ-depth 0)
  1325. (math-integ-msg "Working...done")
  1326. (math-cur-record nil) ; a technicality
  1327. (math-integrating t)
  1328. (calc-prefer-frac t)
  1329. (calc-symbolic-mode t)
  1330. (math-has-rules (calc-has-rules 'var-IntegRules)))
  1331. (or (math-integral expr 'yes)
  1332. (and math-any-substs
  1333. (setq math-enable-subst t)
  1334. (math-integral expr 'yes))
  1335. (and (> math-max-integral-limit math-integral-limit)
  1336. (setq math-integral-limit math-max-integral-limit
  1337. math-integ-level math-integral-limit)
  1338. (math-integral expr 'yes)))))
  1339. (defvar var-IntegLimit nil)
  1340. (defun calcFunc-integ (expr var &optional low high)
  1341. (cond
  1342. ;; Do these even if the parts turn out not to be integrable.
  1343. ((eq (car-safe expr) '+)
  1344. (math-add (calcFunc-integ (nth 1 expr) var low high)
  1345. (calcFunc-integ (nth 2 expr) var low high)))
  1346. ((eq (car-safe expr) '-)
  1347. (math-sub (calcFunc-integ (nth 1 expr) var low high)
  1348. (calcFunc-integ (nth 2 expr) var low high)))
  1349. ((eq (car-safe expr) 'neg)
  1350. (math-neg (calcFunc-integ (nth 1 expr) var low high)))
  1351. ((and (eq (car-safe expr) '*)
  1352. (not (math-expr-contains (nth 1 expr) var)))
  1353. (math-mul (nth 1 expr) (calcFunc-integ (nth 2 expr) var low high)))
  1354. ((and (eq (car-safe expr) '*)
  1355. (not (math-expr-contains (nth 2 expr) var)))
  1356. (math-mul (calcFunc-integ (nth 1 expr) var low high) (nth 2 expr)))
  1357. ((and (eq (car-safe expr) '/)
  1358. (not (math-expr-contains (nth 1 expr) var))
  1359. (not (math-equal-int (nth 1 expr) 1)))
  1360. (math-mul (nth 1 expr)
  1361. (calcFunc-integ (math-div 1 (nth 2 expr)) var low high)))
  1362. ((and (eq (car-safe expr) '/)
  1363. (not (math-expr-contains (nth 2 expr) var)))
  1364. (math-div (calcFunc-integ (nth 1 expr) var low high) (nth 2 expr)))
  1365. ((and (eq (car-safe expr) '/)
  1366. (eq (car-safe (nth 1 expr)) '*)
  1367. (not (math-expr-contains (nth 1 (nth 1 expr)) var)))
  1368. (math-mul (nth 1 (nth 1 expr))
  1369. (calcFunc-integ (math-div (nth 2 (nth 1 expr)) (nth 2 expr))
  1370. var low high)))
  1371. ((and (eq (car-safe expr) '/)
  1372. (eq (car-safe (nth 1 expr)) '*)
  1373. (not (math-expr-contains (nth 2 (nth 1 expr)) var)))
  1374. (math-mul (nth 2 (nth 1 expr))
  1375. (calcFunc-integ (math-div (nth 1 (nth 1 expr)) (nth 2 expr))
  1376. var low high)))
  1377. ((and (eq (car-safe expr) '/)
  1378. (eq (car-safe (nth 2 expr)) '*)
  1379. (not (math-expr-contains (nth 1 (nth 2 expr)) var)))
  1380. (math-div (calcFunc-integ (math-div (nth 1 expr) (nth 2 (nth 2 expr)))
  1381. var low high)
  1382. (nth 1 (nth 2 expr))))
  1383. ((and (eq (car-safe expr) '/)
  1384. (eq (car-safe (nth 2 expr)) '*)
  1385. (not (math-expr-contains (nth 2 (nth 2 expr)) var)))
  1386. (math-div (calcFunc-integ (math-div (nth 1 expr) (nth 1 (nth 2 expr)))
  1387. var low high)
  1388. (nth 2 (nth 2 expr))))
  1389. ((eq (car-safe expr) 'vec)
  1390. (cons 'vec (mapcar (function (lambda (x) (calcFunc-integ x var low high)))
  1391. (cdr expr))))
  1392. (t
  1393. (let ((state (list calc-angle-mode
  1394. ;;calc-symbolic-mode
  1395. ;;calc-prefer-frac
  1396. calc-internal-prec
  1397. (calc-var-value 'var-IntegRules)
  1398. (calc-var-value 'var-IntegSimpRules))))
  1399. (or (equal state math-integral-cache-state)
  1400. (setq math-integral-cache-state state
  1401. math-integral-cache nil)))
  1402. (let* ((math-max-integral-limit (or (and (natnump var-IntegLimit)
  1403. var-IntegLimit)
  1404. 3))
  1405. (math-integral-limit 1)
  1406. (sexpr (math-expr-subst expr var math-integ-var))
  1407. (trace-buffer (get-buffer "*Trace*"))
  1408. (calc-language (if (eq calc-language 'big) nil calc-language))
  1409. (math-any-substs t)
  1410. (math-enable-subst nil)
  1411. (math-prev-parts-v nil)
  1412. (math-doing-parts nil)
  1413. (math-good-parts nil)
  1414. (res
  1415. (if trace-buffer
  1416. (let ((calcbuf (current-buffer))
  1417. (calcwin (selected-window)))
  1418. (unwind-protect
  1419. (progn
  1420. (if (get-buffer-window trace-buffer)
  1421. (select-window (get-buffer-window trace-buffer)))
  1422. (set-buffer trace-buffer)
  1423. (goto-char (point-max))
  1424. (or (assq 'scroll-stop (buffer-local-variables))
  1425. (progn
  1426. (make-local-variable 'scroll-step)
  1427. (setq scroll-step 3)))
  1428. (insert "\n\n\n")
  1429. (set-buffer calcbuf)
  1430. (math-try-integral sexpr))
  1431. (select-window calcwin)
  1432. (set-buffer calcbuf)))
  1433. (math-try-integral sexpr))))
  1434. (if res
  1435. (progn
  1436. (if (calc-has-rules 'var-IntegAfterRules)
  1437. (setq res (math-rewrite res '(var IntegAfterRules
  1438. var-IntegAfterRules))))
  1439. (math-simplify
  1440. (if (and low high)
  1441. (math-sub (math-expr-subst res math-integ-var high)
  1442. (math-expr-subst res math-integ-var low))
  1443. (setq res (math-fix-const-terms res math-integ-vars))
  1444. (if low
  1445. (math-expr-subst res math-integ-var low)
  1446. (math-expr-subst res math-integ-var var)))))
  1447. (append (list 'calcFunc-integ expr var)
  1448. (and low (list low))
  1449. (and high (list high))))))))
  1450. (math-defintegral calcFunc-inv
  1451. (math-integral (math-div 1 u)))
  1452. (math-defintegral calcFunc-conj
  1453. (let ((int (math-integral u)))
  1454. (and int
  1455. (list 'calcFunc-conj int))))
  1456. (math-defintegral calcFunc-deg
  1457. (let ((int (math-integral u)))
  1458. (and int
  1459. (list 'calcFunc-deg int))))
  1460. (math-defintegral calcFunc-rad
  1461. (let ((int (math-integral u)))
  1462. (and int
  1463. (list 'calcFunc-rad int))))
  1464. (math-defintegral calcFunc-re
  1465. (let ((int (math-integral u)))
  1466. (and int
  1467. (list 'calcFunc-re int))))
  1468. (math-defintegral calcFunc-im
  1469. (let ((int (math-integral u)))
  1470. (and int
  1471. (list 'calcFunc-im int))))
  1472. (math-defintegral calcFunc-sqrt
  1473. (and (equal u math-integ-var)
  1474. (math-mul '(frac 2 3)
  1475. (list 'calcFunc-sqrt (math-pow u 3)))))
  1476. (math-defintegral calcFunc-exp
  1477. (or (and (equal u math-integ-var)
  1478. (list 'calcFunc-exp u))
  1479. (let ((p (math-is-polynomial u math-integ-var 2)))
  1480. (and (nth 2 p)
  1481. (let ((sqa (math-sqrt (math-neg (nth 2 p)))))
  1482. (math-div
  1483. (math-mul
  1484. (math-mul (math-div (list 'calcFunc-sqrt '(var pi var-pi))
  1485. sqa)
  1486. (math-normalize
  1487. (list 'calcFunc-exp
  1488. (math-div (math-sub (math-mul (car p)
  1489. (nth 2 p))
  1490. (math-div
  1491. (math-sqr (nth 1 p))
  1492. 4))
  1493. (nth 2 p)))))
  1494. (list 'calcFunc-erf
  1495. (math-sub (math-mul sqa math-integ-var)
  1496. (math-div (nth 1 p) (math-mul 2 sqa)))))
  1497. 2))))))
  1498. (math-defintegral calcFunc-ln
  1499. (or (and (equal u math-integ-var)
  1500. (math-sub (math-mul u (list 'calcFunc-ln u)) u))
  1501. (and (eq (car u) '*)
  1502. (math-integral (math-add (list 'calcFunc-ln (nth 1 u))
  1503. (list 'calcFunc-ln (nth 2 u)))))
  1504. (and (eq (car u) '/)
  1505. (math-integral (math-sub (list 'calcFunc-ln (nth 1 u))
  1506. (list 'calcFunc-ln (nth 2 u)))))
  1507. (and (eq (car u) '^)
  1508. (math-integral (math-mul (nth 2 u)
  1509. (list 'calcFunc-ln (nth 1 u)))))))
  1510. (math-defintegral calcFunc-log10
  1511. (and (equal u math-integ-var)
  1512. (math-sub (math-mul u (list 'calcFunc-ln u))
  1513. (math-div u (list 'calcFunc-ln 10)))))
  1514. (math-defintegral-2 calcFunc-log
  1515. (math-integral (math-div (list 'calcFunc-ln u)
  1516. (list 'calcFunc-ln v))))
  1517. (math-defintegral calcFunc-sin
  1518. (or (and (equal u math-integ-var)
  1519. (math-neg (math-from-radians-2 (list 'calcFunc-cos u))))
  1520. (and (nth 2 (math-is-polynomial u math-integ-var 2))
  1521. (math-integral (math-to-exponentials (list 'calcFunc-sin u))))))
  1522. (math-defintegral calcFunc-cos
  1523. (or (and (equal u math-integ-var)
  1524. (math-from-radians-2 (list 'calcFunc-sin u)))
  1525. (and (nth 2 (math-is-polynomial u math-integ-var 2))
  1526. (math-integral (math-to-exponentials (list 'calcFunc-cos u))))))
  1527. (math-defintegral calcFunc-tan
  1528. (and (equal u math-integ-var)
  1529. (math-from-radians-2
  1530. (list 'calcFunc-ln (list 'calcFunc-sec u)))))
  1531. (math-defintegral calcFunc-sec
  1532. (and (equal u math-integ-var)
  1533. (math-from-radians-2
  1534. (list 'calcFunc-ln
  1535. (math-add
  1536. (list 'calcFunc-sec u)
  1537. (list 'calcFunc-tan u))))))
  1538. (math-defintegral calcFunc-csc
  1539. (and (equal u math-integ-var)
  1540. (math-from-radians-2
  1541. (list 'calcFunc-ln
  1542. (math-sub
  1543. (list 'calcFunc-csc u)
  1544. (list 'calcFunc-cot u))))))
  1545. (math-defintegral calcFunc-cot
  1546. (and (equal u math-integ-var)
  1547. (math-from-radians-2
  1548. (list 'calcFunc-ln (list 'calcFunc-sin u)))))
  1549. (math-defintegral calcFunc-arcsin
  1550. (and (equal u math-integ-var)
  1551. (math-add (math-mul u (list 'calcFunc-arcsin u))
  1552. (math-from-radians-2
  1553. (list 'calcFunc-sqrt (math-sub 1 (math-sqr u)))))))
  1554. (math-defintegral calcFunc-arccos
  1555. (and (equal u math-integ-var)
  1556. (math-sub (math-mul u (list 'calcFunc-arccos u))
  1557. (math-from-radians-2
  1558. (list 'calcFunc-sqrt (math-sub 1 (math-sqr u)))))))
  1559. (math-defintegral calcFunc-arctan
  1560. (and (equal u math-integ-var)
  1561. (math-sub (math-mul u (list 'calcFunc-arctan u))
  1562. (math-from-radians-2
  1563. (math-div (list 'calcFunc-ln (math-add 1 (math-sqr u)))
  1564. 2)))))
  1565. (math-defintegral calcFunc-sinh
  1566. (and (equal u math-integ-var)
  1567. (list 'calcFunc-cosh u)))
  1568. (math-defintegral calcFunc-cosh
  1569. (and (equal u math-integ-var)
  1570. (list 'calcFunc-sinh u)))
  1571. (math-defintegral calcFunc-tanh
  1572. (and (equal u math-integ-var)
  1573. (list 'calcFunc-ln (list 'calcFunc-cosh u))))
  1574. (math-defintegral calcFunc-sech
  1575. (and (equal u math-integ-var)
  1576. (list 'calcFunc-arctan (list 'calcFunc-sinh u))))
  1577. (math-defintegral calcFunc-csch
  1578. (and (equal u math-integ-var)
  1579. (list 'calcFunc-ln (list 'calcFunc-tanh (math-div u 2)))))
  1580. (math-defintegral calcFunc-coth
  1581. (and (equal u math-integ-var)
  1582. (list 'calcFunc-ln (list 'calcFunc-sinh u))))
  1583. (math-defintegral calcFunc-arcsinh
  1584. (and (equal u math-integ-var)
  1585. (math-sub (math-mul u (list 'calcFunc-arcsinh u))
  1586. (list 'calcFunc-sqrt (math-add (math-sqr u) 1)))))
  1587. (math-defintegral calcFunc-arccosh
  1588. (and (equal u math-integ-var)
  1589. (math-sub (math-mul u (list 'calcFunc-arccosh u))
  1590. (list 'calcFunc-sqrt (math-sub 1 (math-sqr u))))))
  1591. (math-defintegral calcFunc-arctanh
  1592. (and (equal u math-integ-var)
  1593. (math-sub (math-mul u (list 'calcFunc-arctan u))
  1594. (math-div (list 'calcFunc-ln
  1595. (math-add 1 (math-sqr u)))
  1596. 2))))
  1597. ;;; (Ax + B) / (ax^2 + bx + c)^n forms.
  1598. (math-defintegral-2 /
  1599. (math-integral-rational-funcs u v))
  1600. (defun math-integral-rational-funcs (u v)
  1601. (let ((pu (math-is-polynomial u math-integ-var 1))
  1602. (vpow 1) pv)
  1603. (and pu
  1604. (catch 'int-rat
  1605. (if (and (eq (car-safe v) '^) (natnump (nth 2 v)))
  1606. (setq vpow (nth 2 v)
  1607. v (nth 1 v)))
  1608. (and (setq pv (math-is-polynomial v math-integ-var 2))
  1609. (let ((int (math-mul-thru
  1610. (car pu)
  1611. (math-integral-q02 (car pv) (nth 1 pv)
  1612. (nth 2 pv) v vpow))))
  1613. (if (cdr pu)
  1614. (setq int (math-add int
  1615. (math-mul-thru
  1616. (nth 1 pu)
  1617. (math-integral-q12
  1618. (car pv) (nth 1 pv)
  1619. (nth 2 pv) v vpow)))))
  1620. int))))))
  1621. (defun math-integral-q12 (a b c v vpow)
  1622. (let (q)
  1623. (cond ((not c)
  1624. (cond ((= vpow 1)
  1625. (math-sub (math-div math-integ-var b)
  1626. (math-mul (math-div a (math-sqr b))
  1627. (list 'calcFunc-ln v))))
  1628. ((= vpow 2)
  1629. (math-div (math-add (list 'calcFunc-ln v)
  1630. (math-div a v))
  1631. (math-sqr b)))
  1632. (t
  1633. (let ((nm1 (math-sub vpow 1))
  1634. (nm2 (math-sub vpow 2)))
  1635. (math-div (math-sub
  1636. (math-div a (math-mul nm1 (math-pow v nm1)))
  1637. (math-div 1 (math-mul nm2 (math-pow v nm2))))
  1638. (math-sqr b))))))
  1639. ((math-zerop
  1640. (setq q (math-sub (math-mul 4 (math-mul a c)) (math-sqr b))))
  1641. (let ((part (math-div b (math-mul 2 c))))
  1642. (math-mul-thru (math-pow c vpow)
  1643. (math-integral-q12 part 1 nil
  1644. (math-add math-integ-var part)
  1645. (* vpow 2)))))
  1646. ((= vpow 1)
  1647. (and (math-ratp q) (math-negp q)
  1648. (let ((calc-symbolic-mode t))
  1649. (math-ratp (math-sqrt (math-neg q))))
  1650. (throw 'int-rat nil)) ; should have used calcFunc-apart first
  1651. (math-sub (math-div (list 'calcFunc-ln v) (math-mul 2 c))
  1652. (math-mul-thru (math-div b (math-mul 2 c))
  1653. (math-integral-q02 a b c v 1))))
  1654. (t
  1655. (let ((n (1- vpow)))
  1656. (math-sub (math-neg (math-div
  1657. (math-add (math-mul b math-integ-var)
  1658. (math-mul 2 a))
  1659. (math-mul n (math-mul q (math-pow v n)))))
  1660. (math-mul-thru (math-div (math-mul b (1- (* 2 n)))
  1661. (math-mul n q))
  1662. (math-integral-q02 a b c v n))))))))
  1663. (defun math-integral-q02 (a b c v vpow)
  1664. (let (q rq part)
  1665. (cond ((not c)
  1666. (cond ((= vpow 1)
  1667. (math-div (list 'calcFunc-ln v) b))
  1668. (t
  1669. (math-div (math-pow v (- 1 vpow))
  1670. (math-mul (- 1 vpow) b)))))
  1671. ((math-zerop
  1672. (setq q (math-sub (math-mul 4 (math-mul a c)) (math-sqr b))))
  1673. (let ((part (math-div b (math-mul 2 c))))
  1674. (math-mul-thru (math-pow c vpow)
  1675. (math-integral-q02 part 1 nil
  1676. (math-add math-integ-var part)
  1677. (* vpow 2)))))
  1678. ((progn
  1679. (setq part (math-add (math-mul 2 (math-mul c math-integ-var)) b))
  1680. (> vpow 1))
  1681. (let ((n (1- vpow)))
  1682. (math-add (math-div part (math-mul n (math-mul q (math-pow v n))))
  1683. (math-mul-thru (math-div (math-mul (- (* 4 n) 2) c)
  1684. (math-mul n q))
  1685. (math-integral-q02 a b c v n)))))
  1686. ((math-guess-if-neg q)
  1687. (setq rq (list 'calcFunc-sqrt (math-neg q)))
  1688. ;;(math-div-thru (list 'calcFunc-ln
  1689. ;; (math-div (math-sub part rq)
  1690. ;; (math-add part rq)))
  1691. ;; rq)
  1692. (math-div (math-mul -2 (list 'calcFunc-arctanh
  1693. (math-div part rq)))
  1694. rq))
  1695. (t
  1696. (setq rq (list 'calcFunc-sqrt q))
  1697. (math-div (math-mul 2 (math-to-radians-2
  1698. (list 'calcFunc-arctan
  1699. (math-div part rq))))
  1700. rq)))))
  1701. (math-defintegral calcFunc-erf
  1702. (and (equal u math-integ-var)
  1703. (math-add (math-mul u (list 'calcFunc-erf u))
  1704. (math-div 1 (math-mul (list 'calcFunc-exp (math-sqr u))
  1705. (list 'calcFunc-sqrt
  1706. '(var pi var-pi)))))))
  1707. (math-defintegral calcFunc-erfc
  1708. (and (equal u math-integ-var)
  1709. (math-sub (math-mul u (list 'calcFunc-erfc u))
  1710. (math-div 1 (math-mul (list 'calcFunc-exp (math-sqr u))
  1711. (list 'calcFunc-sqrt
  1712. '(var pi var-pi)))))))
  1713. (defvar math-tabulate-initial nil)
  1714. (defvar math-tabulate-function nil)
  1715. ;; These variables are local to calcFunc-table, but are used by
  1716. ;; math-scan-for-limits.
  1717. (defvar calc-low)
  1718. (defvar calc-high)
  1719. (defvar math-var)
  1720. (defun calcFunc-table (expr math-var &optional calc-low calc-high step)
  1721. (or calc-low
  1722. (setq calc-low '(neg (var inf var-inf)) calc-high '(var inf var-inf)))
  1723. (or calc-high (setq calc-high calc-low calc-low 1))
  1724. (and (or (math-infinitep calc-low) (math-infinitep calc-high))
  1725. (not step)
  1726. (math-scan-for-limits expr))
  1727. (and step (math-zerop step) (math-reject-arg step 'nonzerop))
  1728. (let ((known (+ (if (Math-objectp calc-low) 1 0)
  1729. (if (Math-objectp calc-high) 1 0)
  1730. (if (or (null step) (Math-objectp step)) 1 0)))
  1731. (count '(var inf var-inf))
  1732. vec)
  1733. (or (= known 2) ; handy optimization
  1734. (equal calc-high '(var inf var-inf))
  1735. (progn
  1736. (setq count (math-div (math-sub calc-high calc-low) (or step 1)))
  1737. (or (Math-objectp count)
  1738. (setq count (math-simplify count)))
  1739. (if (Math-messy-integerp count)
  1740. (setq count (math-trunc count)))))
  1741. (if (Math-negp count)
  1742. (setq count -1))
  1743. (if (integerp count)
  1744. (let ((var-DUMMY nil)
  1745. (vec math-tabulate-initial)
  1746. (math-working-step-2 (1+ count))
  1747. (math-working-step 0))
  1748. (setq expr (math-evaluate-expr
  1749. (math-expr-subst expr math-var '(var DUMMY var-DUMMY))))
  1750. (while (>= count 0)
  1751. (setq math-working-step (1+ math-working-step)
  1752. var-DUMMY calc-low
  1753. vec (cond ((eq math-tabulate-function 'calcFunc-sum)
  1754. (math-add vec (math-evaluate-expr expr)))
  1755. ((eq math-tabulate-function 'calcFunc-prod)
  1756. (math-mul vec (math-evaluate-expr expr)))
  1757. (t
  1758. (cons (math-evaluate-expr expr) vec)))
  1759. calc-low (math-add calc-low (or step 1))
  1760. count (1- count)))
  1761. (if math-tabulate-function
  1762. vec
  1763. (cons 'vec (nreverse vec))))
  1764. (if (Math-integerp count)
  1765. (calc-record-why 'fixnump calc-high)
  1766. (if (Math-num-integerp calc-low)
  1767. (if (Math-num-integerp calc-high)
  1768. (calc-record-why 'integerp step)
  1769. (calc-record-why 'integerp calc-high))
  1770. (calc-record-why 'integerp calc-low)))
  1771. (append (list (or math-tabulate-function 'calcFunc-table)
  1772. expr math-var)
  1773. (and (not (and (equal calc-low '(neg (var inf var-inf)))
  1774. (equal calc-high '(var inf var-inf))))
  1775. (list calc-low calc-high))
  1776. (and step (list step))))))
  1777. (defun math-scan-for-limits (x)
  1778. (cond ((Math-primp x))
  1779. ((and (eq (car x) 'calcFunc-subscr)
  1780. (Math-vectorp (nth 1 x))
  1781. (math-expr-contains (nth 2 x) math-var))
  1782. (let* ((calc-next-why nil)
  1783. (low-val (math-solve-for (nth 2 x) 1 math-var nil))
  1784. (high-val (math-solve-for (nth 2 x) (1- (length (nth 1 x)))
  1785. math-var nil))
  1786. temp)
  1787. (and low-val (math-realp low-val)
  1788. high-val (math-realp high-val))
  1789. (and (Math-lessp high-val low-val)
  1790. (setq temp low-val low-val high-val high-val temp))
  1791. (setq calc-low (math-max calc-low (math-ceiling low-val))
  1792. calc-high (math-min calc-high (math-floor high-val)))))
  1793. (t
  1794. (while (setq x (cdr x))
  1795. (math-scan-for-limits (car x))))))
  1796. (defvar math-disable-sums nil)
  1797. (defun calcFunc-sum (expr var &optional low high step)
  1798. (if math-disable-sums (math-reject-arg))
  1799. (let* ((res (let* ((calc-internal-prec (+ calc-internal-prec 2)))
  1800. (math-sum-rec expr var low high step)))
  1801. (math-disable-sums t))
  1802. (math-normalize res)))
  1803. (defun math-sum-rec (expr var &optional low high step)
  1804. (or low (setq low '(neg (var inf var-inf)) high '(var inf var-inf)))
  1805. (and low (not high) (setq high low low 1))
  1806. (let (t1 t2 val)
  1807. (setq val
  1808. (cond
  1809. ((not (math-expr-contains expr var))
  1810. (math-mul expr (math-add (math-div (math-sub high low) (or step 1))
  1811. 1)))
  1812. ((and step (not (math-equal-int step 1)))
  1813. (if (math-negp step)
  1814. (math-sum-rec expr var high low (math-neg step))
  1815. (let ((lo (math-simplify (math-div low step))))
  1816. (if (math-known-num-integerp lo)
  1817. (math-sum-rec (math-normalize
  1818. (math-expr-subst expr var
  1819. (math-mul step var)))
  1820. var lo (math-simplify (math-div high step)))
  1821. (math-sum-rec (math-normalize
  1822. (math-expr-subst expr var
  1823. (math-add (math-mul step var)
  1824. low)))
  1825. var 0
  1826. (math-simplify (math-div (math-sub high low)
  1827. step)))))))
  1828. ((memq (setq t1 (math-compare low high)) '(0 1))
  1829. (if (eq t1 0)
  1830. (math-expr-subst expr var low)
  1831. 0))
  1832. ((setq t1 (math-is-polynomial expr var 20))
  1833. (let ((poly nil)
  1834. (n 0))
  1835. (while t1
  1836. (setq poly (math-poly-mix poly 1
  1837. (math-sum-integer-power n) (car t1))
  1838. n (1+ n)
  1839. t1 (cdr t1)))
  1840. (setq n (math-build-polynomial-expr poly high))
  1841. (if (= low 1)
  1842. n
  1843. (math-sub n (math-build-polynomial-expr poly
  1844. (math-sub low 1))))))
  1845. ((and (memq (car expr) '(+ -))
  1846. (setq t1 (math-sum-rec (nth 1 expr) var low high)
  1847. t2 (math-sum-rec (nth 2 expr) var low high))
  1848. (not (and (math-expr-calls t1 '(calcFunc-sum))
  1849. (math-expr-calls t2 '(calcFunc-sum)))))
  1850. (list (car expr) t1 t2))
  1851. ((and (eq (car expr) '*)
  1852. (setq t1 (math-sum-const-factors expr var)))
  1853. (math-mul (car t1) (math-sum-rec (cdr t1) var low high)))
  1854. ((and (eq (car expr) '*) (memq (car-safe (nth 1 expr)) '(+ -)))
  1855. (math-sum-rec (math-add-or-sub (math-mul (nth 1 (nth 1 expr))
  1856. (nth 2 expr))
  1857. (math-mul (nth 2 (nth 1 expr))
  1858. (nth 2 expr))
  1859. nil (eq (car (nth 1 expr)) '-))
  1860. var low high))
  1861. ((and (eq (car expr) '*) (memq (car-safe (nth 2 expr)) '(+ -)))
  1862. (math-sum-rec (math-add-or-sub (math-mul (nth 1 expr)
  1863. (nth 1 (nth 2 expr)))
  1864. (math-mul (nth 1 expr)
  1865. (nth 2 (nth 2 expr)))
  1866. nil (eq (car (nth 2 expr)) '-))
  1867. var low high))
  1868. ((and (eq (car expr) '/)
  1869. (not (math-primp (nth 1 expr)))
  1870. (setq t1 (math-sum-const-factors (nth 1 expr) var)))
  1871. (math-mul (car t1)
  1872. (math-sum-rec (math-div (cdr t1) (nth 2 expr))
  1873. var low high)))
  1874. ((and (eq (car expr) '/)
  1875. (setq t1 (math-sum-const-factors (nth 2 expr) var)))
  1876. (math-div (math-sum-rec (math-div (nth 1 expr) (cdr t1))
  1877. var low high)
  1878. (car t1)))
  1879. ((eq (car expr) 'neg)
  1880. (math-neg (math-sum-rec (nth 1 expr) var low high)))
  1881. ((and (eq (car expr) '^)
  1882. (not (math-expr-contains (nth 1 expr) var))
  1883. (setq t1 (math-is-polynomial (nth 2 expr) var 1)))
  1884. (let ((x (math-pow (nth 1 expr) (nth 1 t1))))
  1885. (math-div (math-mul (math-sub (math-pow x (math-add 1 high))
  1886. (math-pow x low))
  1887. (math-pow (nth 1 expr) (car t1)))
  1888. (math-sub x 1))))
  1889. ((and (setq t1 (math-to-exponentials expr))
  1890. (setq t1 (math-sum-rec t1 var low high))
  1891. (not (math-expr-calls t1 '(calcFunc-sum))))
  1892. (math-to-exps t1))
  1893. ((memq (car expr) '(calcFunc-ln calcFunc-log10))
  1894. (list (car expr) (calcFunc-prod (nth 1 expr) var low high)))
  1895. ((and (eq (car expr) 'calcFunc-log)
  1896. (= (length expr) 3)
  1897. (not (math-expr-contains (nth 2 expr) var)))
  1898. (list 'calcFunc-log
  1899. (calcFunc-prod (nth 1 expr) var low high)
  1900. (nth 2 expr)))))
  1901. (if (equal val '(var nan var-nan)) (setq val nil))
  1902. (or val
  1903. (let* ((math-tabulate-initial 0)
  1904. (math-tabulate-function 'calcFunc-sum))
  1905. (calcFunc-table expr var low high)))))
  1906. (defun calcFunc-asum (expr var low &optional high step no-mul-flag)
  1907. (or high (setq high low low 1))
  1908. (if (and step (not (math-equal-int step 1)))
  1909. (if (math-negp step)
  1910. (math-mul (math-pow -1 low)
  1911. (calcFunc-asum expr var high low (math-neg step) t))
  1912. (let ((lo (math-simplify (math-div low step))))
  1913. (if (math-num-integerp lo)
  1914. (calcFunc-asum (math-normalize
  1915. (math-expr-subst expr var
  1916. (math-mul step var)))
  1917. var lo (math-simplify (math-div high step)))
  1918. (calcFunc-asum (math-normalize
  1919. (math-expr-subst expr var
  1920. (math-add (math-mul step var)
  1921. low)))
  1922. var 0
  1923. (math-simplify (math-div (math-sub high low)
  1924. step))))))
  1925. (math-mul (if no-mul-flag 1 (math-pow -1 low))
  1926. (calcFunc-sum (math-mul (math-pow -1 var) expr) var low high))))
  1927. (defun math-sum-const-factors (expr var)
  1928. (let ((const nil)
  1929. (not-const nil)
  1930. (p expr))
  1931. (while (eq (car-safe p) '*)
  1932. (if (math-expr-contains (nth 1 p) var)
  1933. (setq not-const (cons (nth 1 p) not-const))
  1934. (setq const (cons (nth 1 p) const)))
  1935. (setq p (nth 2 p)))
  1936. (if (math-expr-contains p var)
  1937. (setq not-const (cons p not-const))
  1938. (setq const (cons p const)))
  1939. (and const
  1940. (cons (let ((temp (car const)))
  1941. (while (setq const (cdr const))
  1942. (setq temp (list '* (car const) temp)))
  1943. temp)
  1944. (let ((temp (or (car not-const) 1)))
  1945. (while (setq not-const (cdr not-const))
  1946. (setq temp (list '* (car not-const) temp)))
  1947. temp)))))
  1948. (defvar math-sum-int-pow-cache (list '(0 1)))
  1949. ;; Following is from CRC Math Tables, 27th ed, pp. 52-53.
  1950. (defun math-sum-integer-power (pow)
  1951. (let ((calc-prefer-frac t)
  1952. (n (length math-sum-int-pow-cache)))
  1953. (while (<= n pow)
  1954. (let* ((new (list 0 0))
  1955. (lin new)
  1956. (pp (cdr (nth (1- n) math-sum-int-pow-cache)))
  1957. (p 2)
  1958. (sum 0)
  1959. q)
  1960. (while pp
  1961. (setq q (math-div (car pp) p)
  1962. new (cons (math-mul q n) new)
  1963. sum (math-add sum q)
  1964. p (1+ p)
  1965. pp (cdr pp)))
  1966. (setcar lin (math-sub 1 (math-mul n sum)))
  1967. (setq math-sum-int-pow-cache
  1968. (nconc math-sum-int-pow-cache (list (nreverse new)))
  1969. n (1+ n))))
  1970. (nth pow math-sum-int-pow-cache)))
  1971. (defun math-to-exponentials (expr)
  1972. (and (consp expr)
  1973. (= (length expr) 2)
  1974. (let ((x (nth 1 expr))
  1975. (pi (if calc-symbolic-mode '(var pi var-pi) (math-pi)))
  1976. (i (if calc-symbolic-mode '(var i var-i) '(cplx 0 1))))
  1977. (cond ((eq (car expr) 'calcFunc-exp)
  1978. (list '^ '(var e var-e) x))
  1979. ((eq (car expr) 'calcFunc-sin)
  1980. (or (eq calc-angle-mode 'rad)
  1981. (setq x (list '/ (list '* x pi) 180)))
  1982. (list '/ (list '-
  1983. (list '^ '(var e var-e) (list '* x i))
  1984. (list '^ '(var e var-e)
  1985. (list 'neg (list '* x i))))
  1986. (list '* 2 i)))
  1987. ((eq (car expr) 'calcFunc-cos)
  1988. (or (eq calc-angle-mode 'rad)
  1989. (setq x (list '/ (list '* x pi) 180)))
  1990. (list '/ (list '+
  1991. (list '^ '(var e var-e)
  1992. (list '* x i))
  1993. (list '^ '(var e var-e)
  1994. (list 'neg (list '* x i))))
  1995. 2))
  1996. ((eq (car expr) 'calcFunc-sinh)
  1997. (list '/ (list '-
  1998. (list '^ '(var e var-e) x)
  1999. (list '^ '(var e var-e) (list 'neg x)))
  2000. 2))
  2001. ((eq (car expr) 'calcFunc-cosh)
  2002. (list '/ (list '+
  2003. (list '^ '(var e var-e) x)
  2004. (list '^ '(var e var-e) (list 'neg x)))
  2005. 2))
  2006. (t nil)))))
  2007. (defun math-to-exps (expr)
  2008. (cond (calc-symbolic-mode expr)
  2009. ((Math-primp expr)
  2010. (if (equal expr '(var e var-e)) (math-e) expr))
  2011. ((and (eq (car expr) '^)
  2012. (equal (nth 1 expr) '(var e var-e)))
  2013. (list 'calcFunc-exp (nth 2 expr)))
  2014. (t
  2015. (cons (car expr) (mapcar 'math-to-exps (cdr expr))))))
  2016. (defvar math-disable-prods nil)
  2017. (defun calcFunc-prod (expr var &optional low high step)
  2018. (if math-disable-prods (math-reject-arg))
  2019. (let* ((res (let* ((calc-internal-prec (+ calc-internal-prec 2)))
  2020. (math-prod-rec expr var low high step)))
  2021. (math-disable-prods t))
  2022. (math-normalize res)))
  2023. (defun math-prod-rec (expr var &optional low high step)
  2024. (or low (setq low '(neg (var inf var-inf)) high '(var inf var-inf)))
  2025. (and low (not high) (setq high '(var inf var-inf)))
  2026. (let (t1 t2 t3 val)
  2027. (setq val
  2028. (cond
  2029. ((not (math-expr-contains expr var))
  2030. (math-pow expr (math-add (math-div (math-sub high low) (or step 1))
  2031. 1)))
  2032. ((and step (not (math-equal-int step 1)))
  2033. (if (math-negp step)
  2034. (math-prod-rec expr var high low (math-neg step))
  2035. (let ((lo (math-simplify (math-div low step))))
  2036. (if (math-known-num-integerp lo)
  2037. (math-prod-rec (math-normalize
  2038. (math-expr-subst expr var
  2039. (math-mul step var)))
  2040. var lo (math-simplify (math-div high step)))
  2041. (math-prod-rec (math-normalize
  2042. (math-expr-subst expr var
  2043. (math-add (math-mul step
  2044. var)
  2045. low)))
  2046. var 0
  2047. (math-simplify (math-div (math-sub high low)
  2048. step)))))))
  2049. ((and (memq (car expr) '(* /))
  2050. (setq t1 (math-prod-rec (nth 1 expr) var low high)
  2051. t2 (math-prod-rec (nth 2 expr) var low high))
  2052. (not (and (math-expr-calls t1 '(calcFunc-prod))
  2053. (math-expr-calls t2 '(calcFunc-prod)))))
  2054. (list (car expr) t1 t2))
  2055. ((and (eq (car expr) '^)
  2056. (not (math-expr-contains (nth 2 expr) var)))
  2057. (math-pow (math-prod-rec (nth 1 expr) var low high)
  2058. (nth 2 expr)))
  2059. ((and (eq (car expr) '^)
  2060. (not (math-expr-contains (nth 1 expr) var)))
  2061. (math-pow (nth 1 expr)
  2062. (calcFunc-sum (nth 2 expr) var low high)))
  2063. ((eq (car expr) 'sqrt)
  2064. (math-normalize (list 'calcFunc-sqrt
  2065. (list 'calcFunc-prod (nth 1 expr)
  2066. var low high))))
  2067. ((eq (car expr) 'neg)
  2068. (math-mul (math-pow -1 (math-add (math-sub high low) 1))
  2069. (math-prod-rec (nth 1 expr) var low high)))
  2070. ((eq (car expr) 'calcFunc-exp)
  2071. (list 'calcFunc-exp (calcFunc-sum (nth 1 expr) var low high)))
  2072. ((and (setq t1 (math-is-polynomial expr var 1))
  2073. (setq t2
  2074. (cond
  2075. ((or (and (math-equal-int (nth 1 t1) 1)
  2076. (setq low (math-simplify
  2077. (math-add low (car t1)))
  2078. high (math-simplify
  2079. (math-add high (car t1)))))
  2080. (and (math-equal-int (nth 1 t1) -1)
  2081. (setq t2 low
  2082. low (math-simplify
  2083. (math-sub (car t1) high))
  2084. high (math-simplify
  2085. (math-sub (car t1) t2)))))
  2086. (if (or (math-zerop low) (math-zerop high))
  2087. 0
  2088. (if (and (or (math-negp low) (math-negp high))
  2089. (or (math-num-integerp low)
  2090. (math-num-integerp high)))
  2091. (if (math-posp high)
  2092. 0
  2093. (math-mul (math-pow -1
  2094. (math-add
  2095. (math-add low high) 1))
  2096. (list '/
  2097. (list 'calcFunc-fact
  2098. (math-neg low))
  2099. (list 'calcFunc-fact
  2100. (math-sub -1 high)))))
  2101. (list '/
  2102. (list 'calcFunc-fact high)
  2103. (list 'calcFunc-fact (math-sub low 1))))))
  2104. ((and (or (and (math-equal-int (nth 1 t1) 2)
  2105. (setq t2 (math-simplify
  2106. (math-add (math-mul low 2)
  2107. (car t1)))
  2108. t3 (math-simplify
  2109. (math-add (math-mul high 2)
  2110. (car t1)))))
  2111. (and (math-equal-int (nth 1 t1) -2)
  2112. (setq t2 (math-simplify
  2113. (math-sub (car t1)
  2114. (math-mul high 2)))
  2115. t3 (math-simplify
  2116. (math-sub (car t1)
  2117. (math-mul low
  2118. 2))))))
  2119. (or (math-integerp t2)
  2120. (and (math-messy-integerp t2)
  2121. (setq t2 (math-trunc t2)))
  2122. (math-integerp t3)
  2123. (and (math-messy-integerp t3)
  2124. (setq t3 (math-trunc t3)))))
  2125. (if (or (math-zerop t2) (math-zerop t3))
  2126. 0
  2127. (if (or (math-evenp t2) (math-evenp t3))
  2128. (if (or (math-negp t2) (math-negp t3))
  2129. (if (math-posp high)
  2130. 0
  2131. (list '/
  2132. (list 'calcFunc-dfact
  2133. (math-neg t2))
  2134. (list 'calcFunc-dfact
  2135. (math-sub -2 t3))))
  2136. (list '/
  2137. (list 'calcFunc-dfact t3)
  2138. (list 'calcFunc-dfact
  2139. (math-sub t2 2))))
  2140. (if (math-negp t3)
  2141. (list '*
  2142. (list '^ -1
  2143. (list '/ (list '- (list '- t2 t3)
  2144. 2)
  2145. 2))
  2146. (list '/
  2147. (list 'calcFunc-dfact
  2148. (math-neg t2))
  2149. (list 'calcFunc-dfact
  2150. (math-sub -2 t3))))
  2151. (if (math-posp t2)
  2152. (list '/
  2153. (list 'calcFunc-dfact t3)
  2154. (list 'calcFunc-dfact
  2155. (math-sub t2 2)))
  2156. nil))))))))
  2157. t2)))
  2158. (if (equal val '(var nan var-nan)) (setq val nil))
  2159. (or val
  2160. (let* ((math-tabulate-initial 1)
  2161. (math-tabulate-function 'calcFunc-prod))
  2162. (calcFunc-table expr var low high)))))
  2163. (defvar math-solve-ranges nil)
  2164. (defvar math-solve-sign)
  2165. ;;; Attempt to reduce math-solve-lhs = math-solve-rhs to
  2166. ;;; math-solve-var = math-solve-rhs', where math-solve-var appears
  2167. ;;; in math-solve-lhs but not in math-solve-rhs or math-solve-rhs';
  2168. ;;; return math-solve-rhs'.
  2169. ;;; Uses global values: math-solve-var, math-solve-full.
  2170. (defvar math-solve-var)
  2171. (defvar math-solve-full)
  2172. ;; The variables math-solve-lhs, math-solve-rhs and math-try-solve-sign
  2173. ;; are local to math-try-solve-for, but are used by math-try-solve-prod.
  2174. ;; (math-solve-lhs and math-solve-rhs are is also local to
  2175. ;; math-decompose-poly, but used by math-solve-poly-funny-powers.)
  2176. (defvar math-solve-lhs)
  2177. (defvar math-solve-rhs)
  2178. (defvar math-try-solve-sign)
  2179. (defun math-try-solve-for
  2180. (math-solve-lhs math-solve-rhs &optional math-try-solve-sign no-poly)
  2181. (let (math-t1 math-t2 math-t3)
  2182. (cond ((equal math-solve-lhs math-solve-var)
  2183. (setq math-solve-sign math-try-solve-sign)
  2184. (if (eq math-solve-full 'all)
  2185. (let ((vec (list 'vec (math-evaluate-expr math-solve-rhs)))
  2186. newvec var p)
  2187. (while math-solve-ranges
  2188. (setq p (car math-solve-ranges)
  2189. var (car p)
  2190. newvec (list 'vec))
  2191. (while (setq p (cdr p))
  2192. (setq newvec (nconc newvec
  2193. (cdr (math-expr-subst
  2194. vec var (car p))))))
  2195. (setq vec newvec
  2196. math-solve-ranges (cdr math-solve-ranges)))
  2197. (math-normalize vec))
  2198. math-solve-rhs))
  2199. ((Math-primp math-solve-lhs)
  2200. nil)
  2201. ((and (eq (car math-solve-lhs) '-)
  2202. (eq (car-safe (nth 1 math-solve-lhs)) (car-safe (nth 2 math-solve-lhs)))
  2203. (Math-zerop math-solve-rhs)
  2204. (= (length (nth 1 math-solve-lhs)) 2)
  2205. (= (length (nth 2 math-solve-lhs)) 2)
  2206. (setq math-t1 (get (car (nth 1 math-solve-lhs)) 'math-inverse))
  2207. (setq math-t2 (funcall math-t1 '(var SOLVEDUM SOLVEDUM)))
  2208. (eq (math-expr-contains-count math-t2 '(var SOLVEDUM SOLVEDUM)) 1)
  2209. (setq math-t3 (math-solve-above-dummy math-t2))
  2210. (setq math-t1 (math-try-solve-for
  2211. (math-sub (nth 1 (nth 1 math-solve-lhs))
  2212. (math-expr-subst
  2213. math-t2 math-t3
  2214. (nth 1 (nth 2 math-solve-lhs))))
  2215. 0)))
  2216. math-t1)
  2217. ((eq (car math-solve-lhs) 'neg)
  2218. (math-try-solve-for (nth 1 math-solve-lhs) (math-neg math-solve-rhs)
  2219. (and math-try-solve-sign (- math-try-solve-sign))))
  2220. ((and (not (eq math-solve-full 't)) (math-try-solve-prod)))
  2221. ((and (not no-poly)
  2222. (setq math-t2
  2223. (math-decompose-poly math-solve-lhs
  2224. math-solve-var 15 math-solve-rhs)))
  2225. (setq math-t1 (cdr (nth 1 math-t2))
  2226. math-t1 (let ((math-solve-ranges math-solve-ranges))
  2227. (cond ((= (length math-t1) 5)
  2228. (apply 'math-solve-quartic (car math-t2) math-t1))
  2229. ((= (length math-t1) 4)
  2230. (apply 'math-solve-cubic (car math-t2) math-t1))
  2231. ((= (length math-t1) 3)
  2232. (apply 'math-solve-quadratic (car math-t2) math-t1))
  2233. ((= (length math-t1) 2)
  2234. (apply 'math-solve-linear
  2235. (car math-t2) math-try-solve-sign math-t1))
  2236. (math-solve-full
  2237. (math-poly-all-roots (car math-t2) math-t1))
  2238. (calc-symbolic-mode nil)
  2239. (t
  2240. (math-try-solve-for
  2241. (car math-t2)
  2242. (math-poly-any-root (reverse math-t1) 0 t)
  2243. nil t)))))
  2244. (if math-t1
  2245. (if (eq (nth 2 math-t2) 1)
  2246. math-t1
  2247. (math-solve-prod math-t1 (math-try-solve-for (nth 2 math-t2) 0 nil t)))
  2248. (calc-record-why "*Unable to find a symbolic solution")
  2249. nil))
  2250. ((and (math-solve-find-root-term math-solve-lhs nil)
  2251. (eq (math-expr-contains-count math-solve-lhs math-t1) 1)) ; just in case
  2252. (math-try-solve-for (math-simplify
  2253. (math-sub (if (or math-t3 (math-evenp math-t2))
  2254. (math-pow math-t1 math-t2)
  2255. (math-neg (math-pow math-t1 math-t2)))
  2256. (math-expand-power
  2257. (math-sub (math-normalize
  2258. (math-expr-subst
  2259. math-solve-lhs math-t1 0))
  2260. math-solve-rhs)
  2261. math-t2 math-solve-var)))
  2262. 0))
  2263. ((eq (car math-solve-lhs) '+)
  2264. (cond ((not (math-expr-contains (nth 1 math-solve-lhs) math-solve-var))
  2265. (math-try-solve-for (nth 2 math-solve-lhs)
  2266. (math-sub math-solve-rhs (nth 1 math-solve-lhs))
  2267. math-try-solve-sign))
  2268. ((not (math-expr-contains (nth 2 math-solve-lhs) math-solve-var))
  2269. (math-try-solve-for (nth 1 math-solve-lhs)
  2270. (math-sub math-solve-rhs (nth 2 math-solve-lhs))
  2271. math-try-solve-sign))))
  2272. ((eq (car math-solve-lhs) 'calcFunc-eq)
  2273. (math-try-solve-for (math-sub (nth 1 math-solve-lhs) (nth 2 math-solve-lhs))
  2274. math-solve-rhs math-try-solve-sign no-poly))
  2275. ((eq (car math-solve-lhs) '-)
  2276. (cond ((or (and (eq (car-safe (nth 1 math-solve-lhs)) 'calcFunc-sin)
  2277. (eq (car-safe (nth 2 math-solve-lhs)) 'calcFunc-cos))
  2278. (and (eq (car-safe (nth 1 math-solve-lhs)) 'calcFunc-cos)
  2279. (eq (car-safe (nth 2 math-solve-lhs)) 'calcFunc-sin)))
  2280. (math-try-solve-for (math-sub (nth 1 math-solve-lhs)
  2281. (list (car (nth 1 math-solve-lhs))
  2282. (math-sub
  2283. (math-quarter-circle t)
  2284. (nth 1 (nth 2 math-solve-lhs)))))
  2285. math-solve-rhs))
  2286. ((not (math-expr-contains (nth 1 math-solve-lhs) math-solve-var))
  2287. (math-try-solve-for (nth 2 math-solve-lhs)
  2288. (math-sub (nth 1 math-solve-lhs) math-solve-rhs)
  2289. (and math-try-solve-sign
  2290. (- math-try-solve-sign))))
  2291. ((not (math-expr-contains (nth 2 math-solve-lhs) math-solve-var))
  2292. (math-try-solve-for (nth 1 math-solve-lhs)
  2293. (math-add math-solve-rhs (nth 2 math-solve-lhs))
  2294. math-try-solve-sign))))
  2295. ((and (eq math-solve-full 't) (math-try-solve-prod)))
  2296. ((and (eq (car math-solve-lhs) '%)
  2297. (not (math-expr-contains (nth 2 math-solve-lhs) math-solve-var)))
  2298. (math-try-solve-for (nth 1 math-solve-lhs) (math-add math-solve-rhs
  2299. (math-solve-get-int
  2300. (nth 2 math-solve-lhs)))))
  2301. ((eq (car math-solve-lhs) 'calcFunc-log)
  2302. (cond ((not (math-expr-contains (nth 2 math-solve-lhs) math-solve-var))
  2303. (math-try-solve-for (nth 1 math-solve-lhs)
  2304. (math-pow (nth 2 math-solve-lhs) math-solve-rhs)))
  2305. ((not (math-expr-contains (nth 1 math-solve-lhs) math-solve-var))
  2306. (math-try-solve-for (nth 2 math-solve-lhs) (math-pow
  2307. (nth 1 math-solve-lhs)
  2308. (math-div 1 math-solve-rhs))))))
  2309. ((and (= (length math-solve-lhs) 2)
  2310. (symbolp (car math-solve-lhs))
  2311. (setq math-t1 (get (car math-solve-lhs) 'math-inverse))
  2312. (setq math-t2 (funcall math-t1 math-solve-rhs)))
  2313. (setq math-t1 (get (car math-solve-lhs) 'math-inverse-sign))
  2314. (math-try-solve-for (nth 1 math-solve-lhs) (math-normalize math-t2)
  2315. (and math-try-solve-sign math-t1
  2316. (if (integerp math-t1)
  2317. (* math-t1 math-try-solve-sign)
  2318. (funcall math-t1 math-solve-lhs
  2319. math-try-solve-sign)))))
  2320. ((and (symbolp (car math-solve-lhs))
  2321. (setq math-t1 (get (car math-solve-lhs) 'math-inverse-n))
  2322. (setq math-t2 (funcall math-t1 math-solve-lhs math-solve-rhs)))
  2323. math-t2)
  2324. ((setq math-t1 (math-expand-formula math-solve-lhs))
  2325. (math-try-solve-for math-t1 math-solve-rhs math-try-solve-sign))
  2326. (t
  2327. (calc-record-why "*No inverse known" math-solve-lhs)
  2328. nil))))
  2329. (defun math-try-solve-prod ()
  2330. (cond ((eq (car math-solve-lhs) '*)
  2331. (cond ((not (math-expr-contains (nth 1 math-solve-lhs) math-solve-var))
  2332. (math-try-solve-for (nth 2 math-solve-lhs)
  2333. (math-div math-solve-rhs (nth 1 math-solve-lhs))
  2334. (math-solve-sign math-try-solve-sign
  2335. (nth 1 math-solve-lhs))))
  2336. ((not (math-expr-contains (nth 2 math-solve-lhs) math-solve-var))
  2337. (math-try-solve-for (nth 1 math-solve-lhs)
  2338. (math-div math-solve-rhs (nth 2 math-solve-lhs))
  2339. (math-solve-sign math-try-solve-sign
  2340. (nth 2 math-solve-lhs))))
  2341. ((Math-zerop math-solve-rhs)
  2342. (math-solve-prod (let ((math-solve-ranges math-solve-ranges))
  2343. (math-try-solve-for (nth 2 math-solve-lhs) 0))
  2344. (math-try-solve-for (nth 1 math-solve-lhs) 0)))))
  2345. ((eq (car math-solve-lhs) '/)
  2346. (cond ((not (math-expr-contains (nth 1 math-solve-lhs) math-solve-var))
  2347. (math-try-solve-for (nth 2 math-solve-lhs)
  2348. (math-div (nth 1 math-solve-lhs) math-solve-rhs)
  2349. (math-solve-sign math-try-solve-sign
  2350. (nth 1 math-solve-lhs))))
  2351. ((not (math-expr-contains (nth 2 math-solve-lhs) math-solve-var))
  2352. (math-try-solve-for (nth 1 math-solve-lhs)
  2353. (math-mul math-solve-rhs (nth 2 math-solve-lhs))
  2354. (math-solve-sign math-try-solve-sign
  2355. (nth 2 math-solve-lhs))))
  2356. ((setq math-t1 (math-try-solve-for (math-sub (nth 1 math-solve-lhs)
  2357. (math-mul (nth 2 math-solve-lhs)
  2358. math-solve-rhs))
  2359. 0))
  2360. math-t1)))
  2361. ((eq (car math-solve-lhs) '^)
  2362. (cond ((not (math-expr-contains (nth 1 math-solve-lhs) math-solve-var))
  2363. (math-try-solve-for
  2364. (nth 2 math-solve-lhs)
  2365. (math-add (math-normalize
  2366. (list 'calcFunc-log math-solve-rhs (nth 1 math-solve-lhs)))
  2367. (math-div
  2368. (math-mul 2
  2369. (math-mul '(var pi var-pi)
  2370. (math-solve-get-int
  2371. '(var i var-i))))
  2372. (math-normalize
  2373. (list 'calcFunc-ln (nth 1 math-solve-lhs)))))))
  2374. ((not (math-expr-contains (nth 2 math-solve-lhs) math-solve-var))
  2375. (cond ((and (integerp (nth 2 math-solve-lhs))
  2376. (>= (nth 2 math-solve-lhs) 2)
  2377. (setq math-t1 (math-integer-log2 (nth 2 math-solve-lhs))))
  2378. (setq math-t2 math-solve-rhs)
  2379. (if (and (eq math-solve-full t)
  2380. (math-known-realp (nth 1 math-solve-lhs)))
  2381. (progn
  2382. (while (>= (setq math-t1 (1- math-t1)) 0)
  2383. (setq math-t2 (list 'calcFunc-sqrt math-t2)))
  2384. (setq math-t2 (math-solve-get-sign math-t2)))
  2385. (while (>= (setq math-t1 (1- math-t1)) 0)
  2386. (setq math-t2 (math-solve-get-sign
  2387. (math-normalize
  2388. (list 'calcFunc-sqrt math-t2))))))
  2389. (math-try-solve-for
  2390. (nth 1 math-solve-lhs)
  2391. (math-normalize math-t2)))
  2392. ((math-looks-negp (nth 2 math-solve-lhs))
  2393. (math-try-solve-for
  2394. (list '^ (nth 1 math-solve-lhs)
  2395. (math-neg (nth 2 math-solve-lhs)))
  2396. (math-div 1 math-solve-rhs)))
  2397. ((and (eq math-solve-full t)
  2398. (Math-integerp (nth 2 math-solve-lhs))
  2399. (math-known-realp (nth 1 math-solve-lhs)))
  2400. (setq math-t1 (math-normalize
  2401. (list 'calcFunc-nroot math-solve-rhs
  2402. (nth 2 math-solve-lhs))))
  2403. (if (math-evenp (nth 2 math-solve-lhs))
  2404. (setq math-t1 (math-solve-get-sign math-t1)))
  2405. (math-try-solve-for
  2406. (nth 1 math-solve-lhs) math-t1
  2407. (and math-try-solve-sign
  2408. (math-oddp (nth 2 math-solve-lhs))
  2409. (math-solve-sign math-try-solve-sign
  2410. (nth 2 math-solve-lhs)))))
  2411. (t (math-try-solve-for
  2412. (nth 1 math-solve-lhs)
  2413. (math-mul
  2414. (math-normalize
  2415. (list 'calcFunc-exp
  2416. (if (Math-realp (nth 2 math-solve-lhs))
  2417. (math-div (math-mul
  2418. '(var pi var-pi)
  2419. (math-solve-get-int
  2420. '(var i var-i)
  2421. (and (integerp (nth 2 math-solve-lhs))
  2422. (math-abs
  2423. (nth 2 math-solve-lhs)))))
  2424. (math-div (nth 2 math-solve-lhs) 2))
  2425. (math-div (math-mul
  2426. 2
  2427. (math-mul
  2428. '(var pi var-pi)
  2429. (math-solve-get-int
  2430. '(var i var-i)
  2431. (and (integerp (nth 2 math-solve-lhs))
  2432. (math-abs
  2433. (nth 2 math-solve-lhs))))))
  2434. (nth 2 math-solve-lhs)))))
  2435. (math-normalize
  2436. (list 'calcFunc-nroot
  2437. math-solve-rhs
  2438. (nth 2 math-solve-lhs))))
  2439. (and math-try-solve-sign
  2440. (math-oddp (nth 2 math-solve-lhs))
  2441. (math-solve-sign math-try-solve-sign
  2442. (nth 2 math-solve-lhs)))))))))
  2443. (t nil)))
  2444. (defun math-solve-prod (lsoln rsoln)
  2445. (cond ((null lsoln)
  2446. rsoln)
  2447. ((null rsoln)
  2448. lsoln)
  2449. ((eq math-solve-full 'all)
  2450. (cons 'vec (append (cdr lsoln) (cdr rsoln))))
  2451. (math-solve-full
  2452. (list 'calcFunc-if
  2453. (list 'calcFunc-gt (math-solve-get-sign 1) 0)
  2454. lsoln
  2455. rsoln))
  2456. (t lsoln)))
  2457. ;;; This deals with negative, fractional, and symbolic powers of "x".
  2458. ;; The variable math-solve-b is local to math-decompose-poly,
  2459. ;; but is used by math-solve-poly-funny-powers.
  2460. (defvar math-solve-b)
  2461. (defun math-solve-poly-funny-powers (sub-rhs) ; uses "t1", "t2"
  2462. (setq math-t1 math-solve-lhs)
  2463. (let ((pp math-poly-neg-powers)
  2464. fac)
  2465. (while pp
  2466. (setq fac (math-pow (car pp) (or math-poly-mult-powers 1))
  2467. math-t1 (math-mul math-t1 fac)
  2468. math-solve-rhs (math-mul math-solve-rhs fac)
  2469. pp (cdr pp))))
  2470. (if sub-rhs (setq math-t1 (math-sub math-t1 math-solve-rhs)))
  2471. (let ((math-poly-neg-powers nil))
  2472. (setq math-t2 (math-mul (or math-poly-mult-powers 1)
  2473. (let ((calc-prefer-frac t))
  2474. (math-div 1 math-poly-frac-powers)))
  2475. math-t1 (math-is-polynomial
  2476. (math-simplify (calcFunc-expand math-t1)) math-solve-b 50))))
  2477. ;;; This converts "a x^8 + b x^5 + c x^2" to "(a (x^3)^2 + b (x^3) + c) * x^2".
  2478. (defun math-solve-crunch-poly (max-degree) ; uses "t1", "t3"
  2479. (let ((count 0))
  2480. (while (and math-t1 (Math-zerop (car math-t1)))
  2481. (setq math-t1 (cdr math-t1)
  2482. count (1+ count)))
  2483. (and math-t1
  2484. (let* ((degree (1- (length math-t1)))
  2485. (scale degree))
  2486. (while (and (> scale 1) (= (car math-t3) 1))
  2487. (and (= (% degree scale) 0)
  2488. (let ((p math-t1)
  2489. (n 0)
  2490. (new-t1 nil)
  2491. (okay t))
  2492. (while (and p okay)
  2493. (if (= (% n scale) 0)
  2494. (setq new-t1 (nconc new-t1 (list (car p))))
  2495. (or (Math-zerop (car p))
  2496. (setq okay nil)))
  2497. (setq p (cdr p)
  2498. n (1+ n)))
  2499. (if okay
  2500. (setq math-t3 (cons scale (cdr math-t3))
  2501. math-t1 new-t1))))
  2502. (setq scale (1- scale)))
  2503. (setq math-t3 (list (math-mul (car math-t3) math-t2)
  2504. (math-mul count math-t2)))
  2505. (<= (1- (length math-t1)) max-degree)))))
  2506. (defun calcFunc-poly (expr var &optional degree)
  2507. (if degree
  2508. (or (natnump degree) (math-reject-arg degree 'fixnatnump))
  2509. (setq degree 50))
  2510. (let ((p (math-is-polynomial expr var degree 'gen)))
  2511. (if p
  2512. (if (equal p '(0))
  2513. (list 'vec)
  2514. (cons 'vec p))
  2515. (math-reject-arg expr "Expected a polynomial"))))
  2516. (defun calcFunc-gpoly (expr var &optional degree)
  2517. (if degree
  2518. (or (natnump degree) (math-reject-arg degree 'fixnatnump))
  2519. (setq degree 50))
  2520. (let* ((math-poly-base-variable var)
  2521. (d (math-decompose-poly expr var degree nil)))
  2522. (if d
  2523. (cons 'vec d)
  2524. (math-reject-arg expr "Expected a polynomial"))))
  2525. (defun math-decompose-poly (math-solve-lhs math-solve-var degree sub-rhs)
  2526. (let ((math-solve-rhs (or sub-rhs 1))
  2527. math-t1 math-t2 math-t3)
  2528. (setq math-t2 (math-polynomial-base
  2529. math-solve-lhs
  2530. (function
  2531. (lambda (math-solve-b)
  2532. (let ((math-poly-neg-powers '(1))
  2533. (math-poly-mult-powers nil)
  2534. (math-poly-frac-powers 1)
  2535. (math-poly-exp-base t))
  2536. (and (not (equal math-solve-b math-solve-lhs))
  2537. (or (not (memq (car-safe math-solve-b) '(+ -))) sub-rhs)
  2538. (setq math-t3 '(1 0) math-t2 1
  2539. math-t1 (math-is-polynomial math-solve-lhs
  2540. math-solve-b 50))
  2541. (if (and (equal math-poly-neg-powers '(1))
  2542. (memq math-poly-mult-powers '(nil 1))
  2543. (eq math-poly-frac-powers 1)
  2544. sub-rhs)
  2545. (setq math-t1 (cons (math-sub (car math-t1) math-solve-rhs)
  2546. (cdr math-t1)))
  2547. (math-solve-poly-funny-powers sub-rhs))
  2548. (math-solve-crunch-poly degree)
  2549. (or (math-expr-contains math-solve-b math-solve-var)
  2550. (math-expr-contains (car math-t3) math-solve-var))))))))
  2551. (if math-t2
  2552. (list (math-pow math-t2 (car math-t3))
  2553. (cons 'vec math-t1)
  2554. (if sub-rhs
  2555. (math-pow math-t2 (nth 1 math-t3))
  2556. (math-div (math-pow math-t2 (nth 1 math-t3)) math-solve-rhs))))))
  2557. (defun math-solve-linear (var sign b a)
  2558. (math-try-solve-for var
  2559. (math-div (math-neg b) a)
  2560. (math-solve-sign sign a)
  2561. t))
  2562. (defun math-solve-quadratic (var c b a)
  2563. (math-try-solve-for
  2564. var
  2565. (if (math-looks-evenp b)
  2566. (let ((halfb (math-div b 2)))
  2567. (math-div
  2568. (math-add
  2569. (math-neg halfb)
  2570. (math-solve-get-sign
  2571. (math-normalize
  2572. (list 'calcFunc-sqrt
  2573. (math-add (math-sqr halfb)
  2574. (math-mul (math-neg c) a))))))
  2575. a))
  2576. (math-div
  2577. (math-add
  2578. (math-neg b)
  2579. (math-solve-get-sign
  2580. (math-normalize
  2581. (list 'calcFunc-sqrt
  2582. (math-add (math-sqr b)
  2583. (math-mul 4 (math-mul (math-neg c) a)))))))
  2584. (math-mul 2 a)))
  2585. nil t))
  2586. (defun math-solve-cubic (var d c b a)
  2587. (let* ((p (math-div b a))
  2588. (q (math-div c a))
  2589. (r (math-div d a))
  2590. (psqr (math-sqr p))
  2591. (aa (math-sub q (math-div psqr 3)))
  2592. (bb (math-add r
  2593. (math-div (math-sub (math-mul 2 (math-mul psqr p))
  2594. (math-mul 9 (math-mul p q)))
  2595. 27)))
  2596. m)
  2597. (if (Math-zerop aa)
  2598. (math-try-solve-for (math-pow (math-add var (math-div p 3)) 3)
  2599. (math-neg bb) nil t)
  2600. (if (Math-zerop bb)
  2601. (math-try-solve-for
  2602. (math-mul (math-add var (math-div p 3))
  2603. (math-add (math-sqr (math-add var (math-div p 3)))
  2604. aa))
  2605. 0 nil t)
  2606. (setq m (math-mul 2 (list 'calcFunc-sqrt (math-div aa -3))))
  2607. (math-try-solve-for
  2608. var
  2609. (math-sub
  2610. (math-normalize
  2611. (math-mul
  2612. m
  2613. (list 'calcFunc-cos
  2614. (math-div
  2615. (math-sub (list 'calcFunc-arccos
  2616. (math-div (math-mul 3 bb)
  2617. (math-mul aa m)))
  2618. (math-mul 2
  2619. (math-mul
  2620. (math-add 1 (math-solve-get-int
  2621. 1 3))
  2622. (math-half-circle
  2623. calc-symbolic-mode))))
  2624. 3))))
  2625. (math-div p 3))
  2626. nil t)))))
  2627. (defun math-solve-quartic (var d c b a aa)
  2628. (setq a (math-div a aa))
  2629. (setq b (math-div b aa))
  2630. (setq c (math-div c aa))
  2631. (setq d (math-div d aa))
  2632. (math-try-solve-for
  2633. var
  2634. (let* ((asqr (math-sqr a))
  2635. (asqr4 (math-div asqr 4))
  2636. (y (let ((math-solve-full nil)
  2637. calc-next-why)
  2638. (math-solve-cubic math-solve-var
  2639. (math-sub (math-sub
  2640. (math-mul 4 (math-mul b d))
  2641. (math-mul asqr d))
  2642. (math-sqr c))
  2643. (math-sub (math-mul a c)
  2644. (math-mul 4 d))
  2645. (math-neg b)
  2646. 1)))
  2647. (rsqr (math-add (math-sub asqr4 b) y))
  2648. (r (list 'calcFunc-sqrt rsqr))
  2649. (sign1 (math-solve-get-sign 1))
  2650. (de (list 'calcFunc-sqrt
  2651. (math-add
  2652. (math-sub (math-mul 3 asqr4)
  2653. (math-mul 2 b))
  2654. (if (Math-zerop rsqr)
  2655. (math-mul
  2656. 2
  2657. (math-mul sign1
  2658. (list 'calcFunc-sqrt
  2659. (math-sub (math-sqr y)
  2660. (math-mul 4 d)))))
  2661. (math-sub
  2662. (math-mul sign1
  2663. (math-div
  2664. (math-sub (math-sub
  2665. (math-mul 4 (math-mul a b))
  2666. (math-mul 8 c))
  2667. (math-mul asqr a))
  2668. (math-mul 4 r)))
  2669. rsqr))))))
  2670. (math-normalize
  2671. (math-sub (math-add (math-mul sign1 (math-div r 2))
  2672. (math-solve-get-sign (math-div de 2)))
  2673. (math-div a 4))))
  2674. nil t))
  2675. (defvar math-symbolic-solve nil)
  2676. (defvar math-int-coefs nil)
  2677. ;; The variable math-int-threshold is local to math-poly-all-roots,
  2678. ;; but is used by math-poly-newton-root.
  2679. (defvar math-int-threshold)
  2680. ;; The variables math-int-scale, math-int-factors and math-double-roots
  2681. ;; are local to math-poly-all-roots, but are used by math-poly-integer-root.
  2682. (defvar math-int-scale)
  2683. (defvar math-int-factors)
  2684. (defvar math-double-roots)
  2685. (defun math-poly-all-roots (var p &optional math-factoring)
  2686. (catch 'ouch
  2687. (let* ((math-symbolic-solve calc-symbolic-mode)
  2688. (roots nil)
  2689. (deg (1- (length p)))
  2690. (orig-p (reverse p))
  2691. (math-int-coefs nil)
  2692. (math-int-scale nil)
  2693. (math-double-roots nil)
  2694. (math-int-factors nil)
  2695. (math-int-threshold nil)
  2696. (pp p))
  2697. ;; If rational coefficients, look for exact rational factors.
  2698. (while (and pp (Math-ratp (car pp)))
  2699. (setq pp (cdr pp)))
  2700. (if pp
  2701. (if (or math-factoring math-symbolic-solve)
  2702. (throw 'ouch nil))
  2703. (let ((lead (car orig-p))
  2704. (calc-prefer-frac t)
  2705. (scale (apply 'math-lcm-denoms p)))
  2706. (setq math-int-scale (math-abs (math-mul scale lead))
  2707. math-int-threshold (math-div '(float 5 -2) math-int-scale)
  2708. math-int-coefs (cdr (math-div (cons 'vec orig-p) lead)))))
  2709. (if (> deg 4)
  2710. (let ((calc-prefer-frac nil)
  2711. (calc-symbolic-mode nil)
  2712. (pp p)
  2713. (def-p (copy-sequence orig-p)))
  2714. (while pp
  2715. (if (Math-numberp (car pp))
  2716. (setq pp (cdr pp))
  2717. (throw 'ouch nil)))
  2718. (while (> deg (if math-symbolic-solve 2 4))
  2719. (let* ((x (math-poly-any-root def-p '(float 0 0) nil))
  2720. b c pp)
  2721. (if (and (eq (car-safe x) 'cplx)
  2722. (math-nearly-zerop (nth 2 x) (nth 1 x)))
  2723. (setq x (calcFunc-re x)))
  2724. (or math-factoring
  2725. (setq roots (cons x roots)))
  2726. (or (math-numberp x)
  2727. (setq x (math-evaluate-expr x)))
  2728. (setq pp def-p
  2729. b (car def-p))
  2730. (while (setq pp (cdr pp))
  2731. (setq c (car pp))
  2732. (setcar pp b)
  2733. (setq b (math-add (math-mul x b) c)))
  2734. (setq def-p (cdr def-p)
  2735. deg (1- deg))))
  2736. (setq p (reverse def-p))))
  2737. (if (> deg 1)
  2738. (let ((math-solve-var '(var DUMMY var-DUMMY))
  2739. (math-solve-sign nil)
  2740. (math-solve-ranges nil)
  2741. (math-solve-full 'all))
  2742. (if (= (length p) (length math-int-coefs))
  2743. (setq p (reverse math-int-coefs)))
  2744. (setq roots (append (cdr (apply (cond ((= deg 2)
  2745. 'math-solve-quadratic)
  2746. ((= deg 3)
  2747. 'math-solve-cubic)
  2748. (t
  2749. 'math-solve-quartic))
  2750. math-solve-var p))
  2751. roots)))
  2752. (if (> deg 0)
  2753. (setq roots (cons (math-div (math-neg (car p)) (nth 1 p))
  2754. roots))))
  2755. (if math-factoring
  2756. (progn
  2757. (while roots
  2758. (math-poly-integer-root (car roots))
  2759. (setq roots (cdr roots)))
  2760. (list math-int-factors (nreverse math-int-coefs) math-int-scale))
  2761. (let ((vec nil) res)
  2762. (while roots
  2763. (let ((root (car roots))
  2764. (math-solve-full (and math-solve-full 'all)))
  2765. (if (math-floatp root)
  2766. (setq root (math-poly-any-root orig-p root t)))
  2767. (setq vec (append vec
  2768. (cdr (or (math-try-solve-for var root nil t)
  2769. (throw 'ouch nil))))))
  2770. (setq roots (cdr roots)))
  2771. (setq vec (cons 'vec (nreverse vec)))
  2772. (if math-symbolic-solve
  2773. (setq vec (math-normalize vec)))
  2774. (if (eq math-solve-full t)
  2775. (list 'calcFunc-subscr
  2776. vec
  2777. (math-solve-get-int 1 (1- (length orig-p)) 1))
  2778. vec))))))
  2779. (defun math-lcm-denoms (&rest fracs)
  2780. (let ((den 1))
  2781. (while fracs
  2782. (if (eq (car-safe (car fracs)) 'frac)
  2783. (setq den (calcFunc-lcm den (nth 2 (car fracs)))))
  2784. (setq fracs (cdr fracs)))
  2785. den))
  2786. (defun math-poly-any-root (p x polish) ; p is a reverse poly coeff list
  2787. (let* ((newt (if (math-zerop x)
  2788. (math-poly-newton-root
  2789. p '(cplx (float 123 -6) (float 1 -4)) 4)
  2790. (math-poly-newton-root p x 4)))
  2791. (res (if (math-zerop (cdr newt))
  2792. (car newt)
  2793. (if (and (math-lessp (cdr newt) '(float 1 -3)) (not polish))
  2794. (setq newt (math-poly-newton-root p (car newt) 30)))
  2795. (if (math-zerop (cdr newt))
  2796. (car newt)
  2797. (math-poly-laguerre-root p x polish)))))
  2798. (and math-symbolic-solve (math-floatp res)
  2799. (throw 'ouch nil))
  2800. res))
  2801. (defun math-poly-newton-root (p x iters)
  2802. (let* ((calc-prefer-frac nil)
  2803. (calc-symbolic-mode nil)
  2804. (try-integer math-int-coefs)
  2805. (dx x) b d)
  2806. (while (and (> (setq iters (1- iters)) 0)
  2807. (let ((pp p))
  2808. (math-working "newton" x)
  2809. (setq b (car p)
  2810. d 0)
  2811. (while (setq pp (cdr pp))
  2812. (setq d (math-add (math-mul x d) b)
  2813. b (math-add (math-mul x b) (car pp))))
  2814. (not (math-zerop d)))
  2815. (progn
  2816. (setq dx (math-div b d)
  2817. x (math-sub x dx))
  2818. (if try-integer
  2819. (let ((adx (math-abs-approx dx)))
  2820. (and (math-lessp adx math-int-threshold)
  2821. (let ((iroot (math-poly-integer-root x)))
  2822. (if iroot
  2823. (setq x iroot dx 0)
  2824. (setq try-integer nil))))))
  2825. (or (not (or (eq dx 0)
  2826. (math-nearly-zerop dx (math-abs-approx x))))
  2827. (progn (setq dx 0) nil)))))
  2828. (cons x (if (math-zerop x)
  2829. 1 (math-div (math-abs-approx dx) (math-abs-approx x))))))
  2830. (defun math-poly-integer-root (x)
  2831. (and (math-lessp (calcFunc-xpon (math-abs-approx x)) calc-internal-prec)
  2832. math-int-coefs
  2833. (let* ((calc-prefer-frac t)
  2834. (xre (calcFunc-re x))
  2835. (xim (calcFunc-im x))
  2836. (xresq (math-sqr xre))
  2837. (ximsq (math-sqr xim)))
  2838. (if (math-lessp ximsq (calcFunc-scf xresq -1))
  2839. ;; Look for linear factor
  2840. (let* ((rnd (math-div (math-round (math-mul xre math-int-scale))
  2841. math-int-scale))
  2842. (icp math-int-coefs)
  2843. (rem (car icp))
  2844. (newcoef nil))
  2845. (while (setq icp (cdr icp))
  2846. (setq newcoef (cons rem newcoef)
  2847. rem (math-add (car icp)
  2848. (math-mul rem rnd))))
  2849. (and (math-zerop rem)
  2850. (progn
  2851. (setq math-int-coefs (nreverse newcoef)
  2852. math-int-factors (cons (list (math-neg rnd))
  2853. math-int-factors))
  2854. rnd)))
  2855. ;; Look for irreducible quadratic factor
  2856. (let* ((rnd1 (math-div (math-round
  2857. (math-mul xre (math-mul -2 math-int-scale)))
  2858. math-int-scale))
  2859. (sqscale (math-sqr math-int-scale))
  2860. (rnd0 (math-div (math-round (math-mul (math-add xresq ximsq)
  2861. sqscale))
  2862. sqscale))
  2863. (rem1 (car math-int-coefs))
  2864. (icp (cdr math-int-coefs))
  2865. (rem0 (car icp))
  2866. (newcoef nil)
  2867. (found (assoc (list rnd0 rnd1 (math-posp xim))
  2868. math-double-roots))
  2869. this)
  2870. (if found
  2871. (setq math-double-roots (delq found math-double-roots)
  2872. rem0 0 rem1 0)
  2873. (while (setq icp (cdr icp))
  2874. (setq this rem1
  2875. newcoef (cons rem1 newcoef)
  2876. rem1 (math-sub rem0 (math-mul this rnd1))
  2877. rem0 (math-sub (car icp) (math-mul this rnd0)))))
  2878. (and (math-zerop rem0)
  2879. (math-zerop rem1)
  2880. (let ((aa (math-div rnd1 -2)))
  2881. (or found (setq math-int-coefs (reverse newcoef)
  2882. math-double-roots (cons (list
  2883. (list
  2884. rnd0 rnd1
  2885. (math-negp xim)))
  2886. math-double-roots)
  2887. math-int-factors (cons (cons rnd0 rnd1)
  2888. math-int-factors)))
  2889. (math-add aa
  2890. (let ((calc-symbolic-mode math-symbolic-solve))
  2891. (math-mul (math-sqrt (math-sub (math-sqr aa)
  2892. rnd0))
  2893. (if (math-negp xim) -1 1)))))))))))
  2894. ;;; The following routine is from Numerical Recipes, section 9.5.
  2895. (defun math-poly-laguerre-root (p x polish)
  2896. (let* ((calc-prefer-frac nil)
  2897. (calc-symbolic-mode nil)
  2898. (iters 0)
  2899. (m (1- (length p)))
  2900. (try-newt (not polish))
  2901. (tried-newt nil)
  2902. b d f x1 dx dxold)
  2903. (while
  2904. (and (or (< (setq iters (1+ iters)) 50)
  2905. (math-reject-arg x "*Laguerre's method failed to converge"))
  2906. (let ((err (math-abs-approx (car p)))
  2907. (abx (math-abs-approx x))
  2908. (pp p))
  2909. (setq b (car p)
  2910. d 0 f 0)
  2911. (while (setq pp (cdr pp))
  2912. (setq f (math-add (math-mul x f) d)
  2913. d (math-add (math-mul x d) b)
  2914. b (math-add (math-mul x b) (car pp))
  2915. err (math-add (math-abs-approx b) (math-mul abx err))))
  2916. (math-lessp (calcFunc-scf err (- -2 calc-internal-prec))
  2917. (math-abs-approx b)))
  2918. (or (not (math-zerop d))
  2919. (not (math-zerop f))
  2920. (progn
  2921. (setq x (math-pow (math-neg b) (list 'frac 1 m)))
  2922. nil))
  2923. (let* ((g (math-div d b))
  2924. (g2 (math-sqr g))
  2925. (h (math-sub g2 (math-mul 2 (math-div f b))))
  2926. (sq (math-sqrt
  2927. (math-mul (1- m) (math-sub (math-mul m h) g2))))
  2928. (gp (math-add g sq))
  2929. (gm (math-sub g sq)))
  2930. (if (math-lessp (calcFunc-abssqr gp) (calcFunc-abssqr gm))
  2931. (setq gp gm))
  2932. (setq dx (math-div m gp)
  2933. x1 (math-sub x dx))
  2934. (if (and try-newt
  2935. (math-lessp (math-abs-approx dx)
  2936. (calcFunc-scf (math-abs-approx x) -3)))
  2937. (let ((newt (math-poly-newton-root p x1 7)))
  2938. (setq tried-newt t
  2939. try-newt nil)
  2940. (if (math-zerop (cdr newt))
  2941. (setq x (car newt) x1 x)
  2942. (if (math-lessp (cdr newt) '(float 1 -6))
  2943. (let ((newt2 (math-poly-newton-root
  2944. p (car newt) 20)))
  2945. (if (math-zerop (cdr newt2))
  2946. (setq x (car newt2) x1 x)
  2947. (setq x (car newt))))))))
  2948. (not (or (eq x x1)
  2949. (math-nearly-equal x x1))))
  2950. (let ((cdx (math-abs-approx dx)))
  2951. (setq x x1
  2952. tried-newt nil)
  2953. (prog1
  2954. (or (<= iters 6)
  2955. (math-lessp cdx dxold)
  2956. (progn
  2957. (if polish
  2958. (let ((digs (calcFunc-xpon
  2959. (math-div (math-abs-approx x) cdx))))
  2960. (calc-record-why
  2961. "*Could not attain full precision")
  2962. (if (natnump digs)
  2963. (let ((calc-internal-prec (max 3 digs)))
  2964. (setq x (math-normalize x))))))
  2965. nil))
  2966. (setq dxold cdx)))
  2967. (or polish
  2968. (math-lessp (calcFunc-scf (math-abs-approx x)
  2969. (- calc-internal-prec))
  2970. dxold))))
  2971. (or (and (math-floatp x)
  2972. (math-poly-integer-root x))
  2973. x)))
  2974. (defun math-solve-above-dummy (x)
  2975. (and (not (Math-primp x))
  2976. (if (and (equal (nth 1 x) '(var SOLVEDUM SOLVEDUM))
  2977. (= (length x) 2))
  2978. x
  2979. (let ((res nil))
  2980. (while (and (setq x (cdr x))
  2981. (not (setq res (math-solve-above-dummy (car x))))))
  2982. res))))
  2983. (defun math-solve-find-root-term (x neg) ; sets "t2", "t3"
  2984. (if (math-solve-find-root-in-prod x)
  2985. (setq math-t3 neg
  2986. math-t1 x)
  2987. (and (memq (car-safe x) '(+ -))
  2988. (or (math-solve-find-root-term (nth 1 x) neg)
  2989. (math-solve-find-root-term (nth 2 x)
  2990. (if (eq (car x) '-) (not neg) neg))))))
  2991. (defun math-solve-find-root-in-prod (x)
  2992. (and (consp x)
  2993. (math-expr-contains x math-solve-var)
  2994. (or (and (eq (car x) 'calcFunc-sqrt)
  2995. (setq math-t2 2))
  2996. (and (eq (car x) '^)
  2997. (or (and (memq (math-quarter-integer (nth 2 x)) '(1 2 3))
  2998. (setq math-t2 2))
  2999. (and (eq (car-safe (nth 2 x)) 'frac)
  3000. (eq (nth 2 (nth 2 x)) 3)
  3001. (setq math-t2 3))))
  3002. (and (memq (car x) '(* /))
  3003. (or (and (not (math-expr-contains (nth 1 x) math-solve-var))
  3004. (math-solve-find-root-in-prod (nth 2 x)))
  3005. (and (not (math-expr-contains (nth 2 x) math-solve-var))
  3006. (math-solve-find-root-in-prod (nth 1 x))))))))
  3007. ;; The variable math-solve-vars is local to math-solve-system,
  3008. ;; but is used by math-solve-system-rec.
  3009. (defvar math-solve-vars)
  3010. ;; The variable math-solve-simplifying is local to math-solve-system
  3011. ;; and math-solve-system-rec, but is used by math-solve-system-subst.
  3012. (defvar math-solve-simplifying)
  3013. (defun math-solve-system (exprs math-solve-vars math-solve-full)
  3014. (setq exprs (mapcar 'list (if (Math-vectorp exprs)
  3015. (cdr exprs)
  3016. (list exprs)))
  3017. math-solve-vars (if (Math-vectorp math-solve-vars)
  3018. (cdr math-solve-vars)
  3019. (list math-solve-vars)))
  3020. (or (let ((math-solve-simplifying nil))
  3021. (math-solve-system-rec exprs math-solve-vars nil))
  3022. (let ((math-solve-simplifying t))
  3023. (math-solve-system-rec exprs math-solve-vars nil))))
  3024. ;;; The following backtracking solver works by choosing a variable
  3025. ;;; and equation, and trying to solve the equation for the variable.
  3026. ;;; If it succeeds it calls itself recursively with that variable and
  3027. ;;; equation removed from their respective lists, and with the solution
  3028. ;;; added to solns as well as being substituted into all existing
  3029. ;;; equations. The algorithm terminates when any solution path
  3030. ;;; manages to remove all the variables from var-list.
  3031. ;;; To support calcFunc-roots, entries in eqn-list and solns are
  3032. ;;; actually lists of equations.
  3033. ;; The variables math-solve-system-res and math-solve-system-vv are
  3034. ;; local to math-solve-system-rec, but are used by math-solve-system-subst.
  3035. (defvar math-solve-system-vv)
  3036. (defvar math-solve-system-res)
  3037. (defun math-solve-system-rec (eqn-list var-list solns)
  3038. (if var-list
  3039. (let ((v var-list)
  3040. (math-solve-system-res nil))
  3041. ;; Try each variable in turn.
  3042. (while
  3043. (and
  3044. v
  3045. (let* ((math-solve-system-vv (car v))
  3046. (e eqn-list)
  3047. (elim (eq (car-safe math-solve-system-vv) 'calcFunc-elim)))
  3048. (if elim
  3049. (setq math-solve-system-vv (nth 1 math-solve-system-vv)))
  3050. ;; Try each equation in turn.
  3051. (while
  3052. (and
  3053. e
  3054. (let ((e2 (car e))
  3055. (eprev nil)
  3056. res2)
  3057. (setq math-solve-system-res nil)
  3058. ;; Try to solve for math-solve-system-vv the list of equations e2.
  3059. (while (and e2
  3060. (setq res2 (or (and (eq (car e2) eprev)
  3061. res2)
  3062. (math-solve-for (car e2) 0
  3063. math-solve-system-vv
  3064. math-solve-full))))
  3065. (setq eprev (car e2)
  3066. math-solve-system-res (cons (if (eq math-solve-full 'all)
  3067. (cdr res2)
  3068. (list res2))
  3069. math-solve-system-res)
  3070. e2 (cdr e2)))
  3071. (if e2
  3072. (setq math-solve-system-res nil)
  3073. ;; Found a solution. Now try other variables.
  3074. (setq math-solve-system-res (nreverse math-solve-system-res)
  3075. math-solve-system-res (math-solve-system-rec
  3076. (mapcar
  3077. 'math-solve-system-subst
  3078. (delq (car e)
  3079. (copy-sequence eqn-list)))
  3080. (delq (car v) (copy-sequence var-list))
  3081. (let ((math-solve-simplifying nil)
  3082. (s (mapcar
  3083. (function
  3084. (lambda (x)
  3085. (cons
  3086. (car x)
  3087. (math-solve-system-subst
  3088. (cdr x)))))
  3089. solns)))
  3090. (if elim
  3091. s
  3092. (cons (cons
  3093. math-solve-system-vv
  3094. (apply 'append math-solve-system-res))
  3095. s)))))
  3096. (not math-solve-system-res))))
  3097. (setq e (cdr e)))
  3098. (not math-solve-system-res)))
  3099. (setq v (cdr v)))
  3100. math-solve-system-res)
  3101. ;; Eliminated all variables, so now put solution into the proper format.
  3102. (setq solns (sort solns
  3103. (function
  3104. (lambda (x y)
  3105. (not (memq (car x) (memq (car y) math-solve-vars)))))))
  3106. (if (eq math-solve-full 'all)
  3107. (math-transpose
  3108. (math-normalize
  3109. (cons 'vec
  3110. (if solns
  3111. (mapcar (function (lambda (x) (cons 'vec (cdr x)))) solns)
  3112. (mapcar (function (lambda (x) (cons 'vec x))) eqn-list)))))
  3113. (math-normalize
  3114. (cons 'vec
  3115. (if solns
  3116. (mapcar (function (lambda (x) (cons 'calcFunc-eq x))) solns)
  3117. (mapcar 'car eqn-list)))))))
  3118. (defun math-solve-system-subst (x) ; uses "res" and "v"
  3119. (let ((accum nil)
  3120. (res2 math-solve-system-res))
  3121. (while x
  3122. (setq accum (nconc accum
  3123. (mapcar (function
  3124. (lambda (r)
  3125. (if math-solve-simplifying
  3126. (math-simplify
  3127. (math-expr-subst
  3128. (car x) math-solve-system-vv r))
  3129. (math-expr-subst
  3130. (car x) math-solve-system-vv r))))
  3131. (car res2)))
  3132. x (cdr x)
  3133. res2 (cdr res2)))
  3134. accum))
  3135. ;; calc-command-flags is declared in calc.el
  3136. (defvar calc-command-flags)
  3137. (defun math-get-from-counter (name)
  3138. (let ((ctr (assq name calc-command-flags)))
  3139. (if ctr
  3140. (setcdr ctr (1+ (cdr ctr)))
  3141. (setq ctr (cons name 1)
  3142. calc-command-flags (cons ctr calc-command-flags)))
  3143. (cdr ctr)))
  3144. (defvar var-GenCount)
  3145. (defun math-solve-get-sign (val)
  3146. (setq val (math-simplify val))
  3147. (if (and (eq (car-safe val) '*)
  3148. (Math-numberp (nth 1 val)))
  3149. (list '* (nth 1 val) (math-solve-get-sign (nth 2 val)))
  3150. (and (eq (car-safe val) 'calcFunc-sqrt)
  3151. (eq (car-safe (nth 1 val)) '^)
  3152. (setq val (math-normalize (list '^
  3153. (nth 1 (nth 1 val))
  3154. (math-div (nth 2 (nth 1 val)) 2)))))
  3155. (if math-solve-full
  3156. (if (and (calc-var-value 'var-GenCount)
  3157. (Math-natnump var-GenCount)
  3158. (not (eq math-solve-full 'all)))
  3159. (prog1
  3160. (math-mul (list 'calcFunc-as var-GenCount) val)
  3161. (setq var-GenCount (math-add var-GenCount 1))
  3162. (calc-refresh-evaltos 'var-GenCount))
  3163. (let* ((var (concat "s" (int-to-string (math-get-from-counter 'solve-sign))))
  3164. (var2 (list 'var (intern var) (intern (concat "var-" var)))))
  3165. (if (eq math-solve-full 'all)
  3166. (setq math-solve-ranges (cons (list var2 1 -1)
  3167. math-solve-ranges)))
  3168. (math-mul var2 val)))
  3169. (calc-record-why "*Choosing positive solution")
  3170. val)))
  3171. (defun math-solve-get-int (val &optional range first)
  3172. (if math-solve-full
  3173. (if (and (calc-var-value 'var-GenCount)
  3174. (Math-natnump var-GenCount)
  3175. (not (eq math-solve-full 'all)))
  3176. (prog1
  3177. (math-mul val (list 'calcFunc-an var-GenCount))
  3178. (setq var-GenCount (math-add var-GenCount 1))
  3179. (calc-refresh-evaltos 'var-GenCount))
  3180. (let* ((var (concat "n" (int-to-string
  3181. (math-get-from-counter 'solve-int))))
  3182. (var2 (list 'var (intern var) (intern (concat "var-" var)))))
  3183. (if (and range (eq math-solve-full 'all))
  3184. (setq math-solve-ranges (cons (cons var2
  3185. (cdr (calcFunc-index
  3186. range (or first 0))))
  3187. math-solve-ranges)))
  3188. (math-mul val var2)))
  3189. (calc-record-why "*Choosing 0 for arbitrary integer in solution")
  3190. 0))
  3191. (defun math-solve-sign (sign expr)
  3192. (and sign
  3193. (let ((s1 (math-possible-signs expr)))
  3194. (cond ((memq s1 '(4 6))
  3195. sign)
  3196. ((memq s1 '(1 3))
  3197. (- sign))))))
  3198. (defun math-looks-evenp (expr)
  3199. (if (Math-integerp expr)
  3200. (math-evenp expr)
  3201. (if (memq (car expr) '(* /))
  3202. (math-looks-evenp (nth 1 expr)))))
  3203. (defun math-solve-for (lhs rhs math-solve-var math-solve-full &optional sign)
  3204. (if (math-expr-contains rhs math-solve-var)
  3205. (math-solve-for (math-sub lhs rhs) 0 math-solve-var math-solve-full)
  3206. (and (math-expr-contains lhs math-solve-var)
  3207. (math-with-extra-prec 1
  3208. (let* ((math-poly-base-variable math-solve-var)
  3209. (res (math-try-solve-for lhs rhs sign)))
  3210. (if (and (eq math-solve-full 'all)
  3211. (math-known-realp math-solve-var))
  3212. (let ((old-len (length res))
  3213. new-len)
  3214. (setq res (delq nil
  3215. (mapcar (function
  3216. (lambda (x)
  3217. (and (not (memq (car-safe x)
  3218. '(cplx polar)))
  3219. x)))
  3220. res))
  3221. new-len (length res))
  3222. (if (< new-len old-len)
  3223. (calc-record-why (if (= new-len 1)
  3224. "*All solutions were complex"
  3225. (format
  3226. "*Omitted %d complex solutions"
  3227. (- old-len new-len)))))))
  3228. res)))))
  3229. (defun math-solve-eqn (expr var full)
  3230. (if (memq (car-safe expr) '(calcFunc-neq calcFunc-lt calcFunc-gt
  3231. calcFunc-leq calcFunc-geq))
  3232. (let ((res (math-solve-for (cons '- (cdr expr))
  3233. 0 var full
  3234. (if (eq (car expr) 'calcFunc-neq) nil 1))))
  3235. (and res
  3236. (if (eq math-solve-sign 1)
  3237. (list (car expr) var res)
  3238. (if (eq math-solve-sign -1)
  3239. (list (car expr) res var)
  3240. (or (eq (car expr) 'calcFunc-neq)
  3241. (calc-record-why
  3242. "*Can't determine direction of inequality"))
  3243. (and (memq (car expr) '(calcFunc-neq calcFunc-lt calcFunc-gt))
  3244. (list 'calcFunc-neq var res))))))
  3245. (let ((res (math-solve-for expr 0 var full)))
  3246. (and res
  3247. (list 'calcFunc-eq var res)))))
  3248. (defun math-reject-solution (expr var func)
  3249. (if (math-expr-contains expr var)
  3250. (or (equal (car calc-next-why) '(* "Unable to find a symbolic solution"))
  3251. (calc-record-why "*Unable to find a solution")))
  3252. (list func expr var))
  3253. (defun calcFunc-solve (expr var)
  3254. (or (if (or (Math-vectorp expr) (Math-vectorp var))
  3255. (math-solve-system expr var nil)
  3256. (math-solve-eqn expr var nil))
  3257. (math-reject-solution expr var 'calcFunc-solve)))
  3258. (defun calcFunc-fsolve (expr var)
  3259. (or (if (or (Math-vectorp expr) (Math-vectorp var))
  3260. (math-solve-system expr var t)
  3261. (math-solve-eqn expr var t))
  3262. (math-reject-solution expr var 'calcFunc-fsolve)))
  3263. (defun calcFunc-roots (expr var)
  3264. (let ((math-solve-ranges nil))
  3265. (or (if (or (Math-vectorp expr) (Math-vectorp var))
  3266. (math-solve-system expr var 'all)
  3267. (math-solve-for expr 0 var 'all))
  3268. (math-reject-solution expr var 'calcFunc-roots))))
  3269. (defun calcFunc-finv (expr var)
  3270. (let ((res (math-solve-for expr math-integ-var var nil)))
  3271. (if res
  3272. (math-normalize (math-expr-subst res math-integ-var var))
  3273. (math-reject-solution expr var 'calcFunc-finv))))
  3274. (defun calcFunc-ffinv (expr var)
  3275. (let ((res (math-solve-for expr math-integ-var var t)))
  3276. (if res
  3277. (math-normalize (math-expr-subst res math-integ-var var))
  3278. (math-reject-solution expr var 'calcFunc-finv))))
  3279. (put 'calcFunc-inv 'math-inverse
  3280. (function (lambda (x) (math-div 1 x))))
  3281. (put 'calcFunc-inv 'math-inverse-sign -1)
  3282. (put 'calcFunc-sqrt 'math-inverse
  3283. (function (lambda (x) (math-sqr x))))
  3284. (put 'calcFunc-conj 'math-inverse
  3285. (function (lambda (x) (list 'calcFunc-conj x))))
  3286. (put 'calcFunc-abs 'math-inverse
  3287. (function (lambda (x) (math-solve-get-sign x))))
  3288. (put 'calcFunc-deg 'math-inverse
  3289. (function (lambda (x) (list 'calcFunc-rad x))))
  3290. (put 'calcFunc-deg 'math-inverse-sign 1)
  3291. (put 'calcFunc-rad 'math-inverse
  3292. (function (lambda (x) (list 'calcFunc-deg x))))
  3293. (put 'calcFunc-rad 'math-inverse-sign 1)
  3294. (put 'calcFunc-ln 'math-inverse
  3295. (function (lambda (x) (list 'calcFunc-exp x))))
  3296. (put 'calcFunc-ln 'math-inverse-sign 1)
  3297. (put 'calcFunc-log10 'math-inverse
  3298. (function (lambda (x) (list 'calcFunc-exp10 x))))
  3299. (put 'calcFunc-log10 'math-inverse-sign 1)
  3300. (put 'calcFunc-lnp1 'math-inverse
  3301. (function (lambda (x) (list 'calcFunc-expm1 x))))
  3302. (put 'calcFunc-lnp1 'math-inverse-sign 1)
  3303. (put 'calcFunc-exp 'math-inverse
  3304. (function (lambda (x) (math-add (math-normalize (list 'calcFunc-ln x))
  3305. (math-mul 2
  3306. (math-mul '(var pi var-pi)
  3307. (math-solve-get-int
  3308. '(var i var-i))))))))
  3309. (put 'calcFunc-exp 'math-inverse-sign 1)
  3310. (put 'calcFunc-expm1 'math-inverse
  3311. (function (lambda (x) (math-add (math-normalize (list 'calcFunc-lnp1 x))
  3312. (math-mul 2
  3313. (math-mul '(var pi var-pi)
  3314. (math-solve-get-int
  3315. '(var i var-i))))))))
  3316. (put 'calcFunc-expm1 'math-inverse-sign 1)
  3317. (put 'calcFunc-sin 'math-inverse
  3318. (function (lambda (x) (let ((n (math-solve-get-int 1)))
  3319. (math-add (math-mul (math-normalize
  3320. (list 'calcFunc-arcsin x))
  3321. (math-pow -1 n))
  3322. (math-mul (math-half-circle t)
  3323. n))))))
  3324. (put 'calcFunc-cos 'math-inverse
  3325. (function (lambda (x) (math-add (math-solve-get-sign
  3326. (math-normalize
  3327. (list 'calcFunc-arccos x)))
  3328. (math-solve-get-int
  3329. (math-full-circle t))))))
  3330. (put 'calcFunc-tan 'math-inverse
  3331. (function (lambda (x) (math-add (math-normalize (list 'calcFunc-arctan x))
  3332. (math-solve-get-int
  3333. (math-half-circle t))))))
  3334. (put 'calcFunc-arcsin 'math-inverse
  3335. (function (lambda (x) (math-normalize (list 'calcFunc-sin x)))))
  3336. (put 'calcFunc-arccos 'math-inverse
  3337. (function (lambda (x) (math-normalize (list 'calcFunc-cos x)))))
  3338. (put 'calcFunc-arctan 'math-inverse
  3339. (function (lambda (x) (math-normalize (list 'calcFunc-tan x)))))
  3340. (put 'calcFunc-sinh 'math-inverse
  3341. (function (lambda (x) (let ((n (math-solve-get-int 1)))
  3342. (math-add (math-mul (math-normalize
  3343. (list 'calcFunc-arcsinh x))
  3344. (math-pow -1 n))
  3345. (math-mul (math-half-circle t)
  3346. (math-mul
  3347. '(var i var-i)
  3348. n)))))))
  3349. (put 'calcFunc-sinh 'math-inverse-sign 1)
  3350. (put 'calcFunc-cosh 'math-inverse
  3351. (function (lambda (x) (math-add (math-solve-get-sign
  3352. (math-normalize
  3353. (list 'calcFunc-arccosh x)))
  3354. (math-mul (math-full-circle t)
  3355. (math-solve-get-int
  3356. '(var i var-i)))))))
  3357. (put 'calcFunc-tanh 'math-inverse
  3358. (function (lambda (x) (math-add (math-normalize
  3359. (list 'calcFunc-arctanh x))
  3360. (math-mul (math-half-circle t)
  3361. (math-solve-get-int
  3362. '(var i var-i)))))))
  3363. (put 'calcFunc-tanh 'math-inverse-sign 1)
  3364. (put 'calcFunc-arcsinh 'math-inverse
  3365. (function (lambda (x) (math-normalize (list 'calcFunc-sinh x)))))
  3366. (put 'calcFunc-arcsinh 'math-inverse-sign 1)
  3367. (put 'calcFunc-arccosh 'math-inverse
  3368. (function (lambda (x) (math-normalize (list 'calcFunc-cosh x)))))
  3369. (put 'calcFunc-arctanh 'math-inverse
  3370. (function (lambda (x) (math-normalize (list 'calcFunc-tanh x)))))
  3371. (put 'calcFunc-arctanh 'math-inverse-sign 1)
  3372. (defun calcFunc-taylor (expr var num)
  3373. (let ((x0 0) (v var))
  3374. (if (memq (car-safe var) '(+ - calcFunc-eq))
  3375. (setq x0 (if (eq (car var) '+) (math-neg (nth 2 var)) (nth 2 var))
  3376. v (nth 1 var)))
  3377. (or (and (eq (car-safe v) 'var)
  3378. (math-expr-contains expr v)
  3379. (natnump num)
  3380. (let ((accum (math-expr-subst expr v x0))
  3381. (var2 (if (eq (car var) 'calcFunc-eq)
  3382. (cons '- (cdr var))
  3383. var))
  3384. (n 0)
  3385. (nfac 1)
  3386. (fprime expr))
  3387. (while (and (<= (setq n (1+ n)) num)
  3388. (setq fprime (calcFunc-deriv fprime v nil t)))
  3389. (setq fprime (math-simplify fprime)
  3390. nfac (math-mul nfac n)
  3391. accum (math-add accum
  3392. (math-div (math-mul (math-pow var2 n)
  3393. (math-expr-subst
  3394. fprime v x0))
  3395. nfac))))
  3396. (and fprime
  3397. (math-normalize accum))))
  3398. (list 'calcFunc-taylor expr var num))))
  3399. (provide 'calcalg2)
  3400. ;;; calcalg2.el ends here