patches.red 77 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247
  1. module patches; % Patches to correct problems in REDUCE 3.7.
  2. % Author: Anthony C. Hearn.
  3. % Copyright (c) 2001 Anthony C. Hearn. All Rights Reserved.
  4. global '(patch!-date!*);
  5. patch!-date!* := "21-Dec-2001";
  6. % Bugs fixed by these patches.
  7. % 28 Jun 99. Gnuplot handling on the Macintosh was not correct.
  8. % 7 Aug 99. The evaluation of df(tan((sqrt(1-x^2)*asin acos x
  9. % + 2*sqrt(1-x^2)*x)/x),x) did not terminate.
  10. % 20 Oct 99. The sequence a1:=12x^2-16x+3; a2:=3x-4; off mcd;
  11. % on combineexpt; e^(a1/a2); gave the wrong answer.
  12. % 8 Nov 99. factorize(2*c*s*u^3*v^5-2*c*s*u^3*v +2*c*s*u*v^5-2*c*s*u*v
  13. % -s^2*u^4*v^4+s^2*u^4+s^2*u^2*v^6-s^2*u^2*v^4-s^2*u^2*v^2
  14. % +s^2*u^2 +s^2*v^6-s^2*v^2+u^4*v^4-u^4*v^2 -v^4+v^2) gave
  15. % a catastrophic error.
  16. % 9 Nov 99. Patched procedures generated a "redefined" message.
  17. % 16 Nov 99. Some EXCALC calculations could cause a catastrophic error.
  18. % 18 Dec 99. Integrations could give catastrophic errors because some
  19. % kernels were not unique.
  20. % 31 Jan 00. The sequence weight x=1,y=1; wtlevel 10; factor x; led to
  21. % the error that x was invalid as a kernel.
  22. % 5 Feb 00. The sequence x := mat((1,2)); sign sqrt 42; led to a
  23. % spurious error.
  24. % 6 Feb 00. The sequence on complex; sqrt(i*sqrt(3)-1); gave a wrong
  25. % result.
  26. % 10 Feb 00. Some root evaluations could lead to an error like
  27. % <equation> invalid as scalar.
  28. % 18 Feb 00. A sequence like m := mat((a,b),(c,d)); det sub(a=1,m);
  29. % would cause a type mismatch error.
  30. % 18 Apr 00. Complaints about the pattern matching limit of 5 terms
  31. % are resolved by the addition of a variable matchlength!*,
  32. % whose initial value of 5 can be changed as needed.
  33. % 22 Apr 00. The RULE mechanism left spurious expressions in various
  34. % non-local variables.
  35. % 28 Jul 00. A sum index within a derivative was treated as an identifier
  36. % (e.g., sum(x^n/factorial n*sub(x=0,df(cos x,x,n)),n,0,5);
  37. % 2 Aug 00. With complex on, some factorizations seemed to run forever
  38. % (e.g., factorize (400y^12+400y^10*z+40y^9*z^2+100y^8*z^2
  39. % +20y^7*z^5+120y^7*z^4+20y^7*z^3+41y^6*z^4+60y^5*z^7
  40. % +60y^5*z^5+20y^4*z^7+6y^4*z^6+20y^4*z^5
  41. % +2y^3*z^6+9y^2*z^8+6y*z^8+z^8))
  42. % 29 Aug 00. The sequence load_package gentran,scope; matrix a(10,10);
  43. % on gentranopt; gentran a(1,1) ::=: a(1,1); caused a
  44. % segmentation violation or similar error.
  45. % 19 Sep 00. Clearing some sqrt rules could lead to a spurious
  46. % "not found" message.
  47. % 20 Sep 00. The sequence load_package algint;
  48. % int(1/sqrt((2*e^c-y)/(e^c*y)),y);
  49. % caused a catastrophic error.
  50. % 8 Nov 00. Some sequences did not optimize completely when the SCOPE
  51. % command "optimize" was used.
  52. % 20 Nov 00. The sum operator did not always preserve a noncom order
  53. % (e.g., noncom u,v; sum(u(m)*v(1-m),m,0,1);)
  54. % 12 Dec 00. int with four arguments did not automatically load the
  55. % defint package.
  56. % 13 Dec 00. Some gcd calculations could produce an endless loop. E.g.,
  57. % in on numval,rounded; y:=x^4+x3*x^3+x2*x^2+x1*x+x0;
  58. % on fullroots; solve(y,x);
  59. % 9 Jan 01. SOLVE did not return results in same order as the given
  60. % variables (e.g., solve({y=x+t^2,x=y+u^2},{x,y,u,t});
  61. % 14 Jan 01. Some resultants (e.g. resultant(p^3-3p^2-a,3p*(p-2),p))
  62. % caused an error.
  63. % 19 Jan 01. Some algebraic integrals could produce a catastrophic
  64. % error when the algint package was loaded.
  65. % 22 Jan 01. Some algebraic integrals could produce a spurious zero
  66. % divisor message when the algint package was loaded (e.g.,
  67. % int((sqrt((-sqrt(a^4*x^2+4)+a^2*x)/(2*x))
  68. % *(-sqrt(a^4*x^2+4)*a^2*x-a^4*x^2-4))/(2*(a^4*x^2+4)),x))
  69. % 23 Jan 01. Inverses of matrices containing non-commuting objects
  70. % could be incorrect (e.g. noncom q; 1/mat((1,0,0),
  71. % (x/p*q 1,1,0),(x*y/(2p*(p-1))*q 1*q 1,y/(p-2)*q 1,1))).
  72. % 2 Feb 01. Some calls of SOLVE could produce a "zero divisor" error
  73. % error (e.g., solve(sqrt x*sqrt((4x^2*x+1)/x)-1=0,x)).
  74. % 9 Feb 01. The patched version of combine!-logs included an undefined
  75. % macro.
  76. % 20 Feb 01. Even with combineexpt on, expressions like a*a^x and
  77. % e*e^(2/(2-x)) did not simplify adequately.
  78. % 6 Mar 01. With algint loaded, some integrals would abort before
  79. % completion (e.g., int((x^(2/3)*sqrt(sqrt(y)*sqrt(pi) + 2pi
  80. % *y*x)*sqrt(- sqrt(y)*sqrt(pi)+2pi*y*x))/(4pi*y*x^3 - x),x)).
  81. % 7 Apr 01. Factorizations with rounded and complex rounded were not
  82. % supported.
  83. % 23 Apr 01. A term could be dropped from the solution of a set of
  84. % linear equations involving surds.
  85. % 7 May 01. Patches of 19 Sep 00 updated to correct bug.
  86. % 1 Jun 01. With precise on, sqrt(x^2) returned x rather than abs(x).
  87. % 11 Jun 01. Expressions involving noncommuting arguments of a
  88. % commuting operator were not handled correctly.
  89. % E.g., operator p,q; noncom q; p q a*p q b -p q b*p q a;
  90. % 15 Jun 01. Patch of 9 Jan 01 gave a catastrophic error with depend
  91. % statements, e.g., depend u,z; solve(u=y/x,z).
  92. % 7 Aug 01. Resultants could return an error or the wrong sign
  93. % (replaces patch of 14 Jan 01).
  94. % 9 Aug 01. Rules for tan, like let tan(~x)=>sin x/cos x, made some
  95. % integrals not return a closed form (e.g., int(1/sin(y)^2,y)).
  96. % 24 Aug 01. Some factorizations with complex on could have the wrong
  97. % sign.
  98. % 7 Sep 01. Some solve problems could cause a catastrophic error in
  99. % SQFRF.
  100. % 7 Nov 01. Gdimension and gindependent_sets in the Groebner package
  101. % could sometimes deliver wrong results.
  102. % 30 Nov 01. Resultants could return with an incorrect zero result
  103. % (replaces patch of 7 Aug 01).
  104. % 21 Dec 01. A resultant calculation involving polynomials with rational
  105. % coefficients would cause a type error, e.g.,
  106. % resultant(a*x^3/2,b*x^5 + 1,x);
  107. % Alg declarations.
  108. fluid '(matchlength!*);
  109. matchlength!* := 5;
  110. flag('(matchlength!*),'share);
  111. fluid '(!*sqrtrulep);
  112. patch alg;
  113. % 20 Oct 99, 20 Feb 01.
  114. symbolic procedure exptunwind(u,v);
  115. begin scalar x,x1,x2,y,z,z2;
  116. a: if null v then return u;
  117. x := caar v;
  118. x1 := cadr x;
  119. x2 := caddr x;
  120. y := cdar v;
  121. v := cdr v;
  122. if !*combineexpt and length u=1 and null cdr(z2 := kernels u)
  123. then u := {(({'expt,car z2,ldeg u} . 1) . lc u)};
  124. while (z := assocp1(x1,v)) and
  125. (z2 := simp {'plus,{'times,x2,y},{'times,caddar z,cdr z}})
  126. and (!*combineexpt or (fixp numr z2 and fixp denr z2))
  127. do <<if fixp numr z2 and fixp denr z2
  128. then <<x2 := divide(numr z2,denr z2);
  129. if car x2>0
  130. then <<if fixp x1 then u := multf(x1**car x2,u)
  131. else u := multpf(mksp(x1,car x2),u);
  132. z2 := cdr x2 ./ denr z2>>;
  133. y := numr z2>>
  134. else y := 1;
  135. x2 := prepsq(quotf(numr z2,y) ./ denr z2);
  136. v := delete(z,v)>>;
  137. if !*combineexpt and y=1 and fixp x1 then
  138. <<while (z := assocp2(x2,v)) and cdr z=1 and fixp cadar z do
  139. <<x1 := cadar z * x1; v := delete(z,v)>>;
  140. if eqcar(x2,'quotient) and fixp cadr x2 and fixp caddr x2
  141. and cadr x2<caddr x2
  142. then <<z := nrootn(x1**cadr x2,caddr x2);
  143. if cdr z = 1 then u := multd(car z,u)
  144. else if car z = 1
  145. then u := multf(formsf(x1,x2,1),u)
  146. else <<u := multd(car z,u);
  147. v := (list('expt,cdr z,x2) . 1) . v>>>>
  148. else u := multf(formsf(x1,x2,y),u)>>
  149. else u := multf(formsf(x1,x2,y),u);
  150. go to a
  151. end;
  152. % 31 Jan 00.
  153. symbolic procedure factor1(u,v,w);
  154. begin scalar x,y,z,r;
  155. y := lispeval w;
  156. for each j in u do
  157. if (x := getrtype j) and (z := get(x,'factor1fn))
  158. then apply2(z,u,v)
  159. else <<while eqcar(j:=reval j,'list) and cdr j do
  160. <<r:=append(r,cddr j); j:=cadr j>>;
  161. x := !*a2kwoweight j;
  162. if v then y := aconc!*(delete(x,y),x)
  163. else if not(x member y)
  164. then msgpri(nil,j,"not found",nil,nil)
  165. else y := delete(x,y)>>;
  166. set(w,y);
  167. if r then return factor1(r,v,w)
  168. end;
  169. % 5 Feb 00.
  170. algebraic (let sign(sqrt ~a) => 1 when sign a=1);
  171. % 18 Feb 00.
  172. symbolic procedure getrtype u;
  173. begin scalar x,y;
  174. return
  175. if null u then nil
  176. else if atom u
  177. then if not idp u then not numberp u and getrtype1 u
  178. else if flagp(u,'share)
  179. then if (x := eval u) eq u then nil else getrtype x
  180. else if (x := get(u,'avalue)) and
  181. not(car x memq '(scalar generic))
  182. or (x := get(u,'rtype)) and (x := list x)
  183. then if y := get(car x,'rtypefn) then apply1(y,nil)
  184. else car x
  185. else nil
  186. else if not idp car u then nil
  187. else if (x := get(car u,'avalue)) and (x := get(car x,'rtypefn))
  188. then apply1(x,cdr u)
  189. else if car u eq 'sub then 'yetunknowntype
  190. else getrtype2 u
  191. end;
  192. symbolic procedure let3(u,v,w,b,flgg);
  193. begin scalar x,y1,y2,z;
  194. x := u;
  195. if null x then <<u := 0; return errpri1 u>>
  196. else if numberp x then return errpri1 u;
  197. y2 := getrtype v;
  198. if b and idp x then <<remprop(x,'rtype); remprop(x,'avalue)>>;
  199. if (y1 := getrtype x)
  200. then return if z := get(y1,'typeletfn)
  201. then lispapply(z,list(x,v,y1,b,getrtype v))
  202. else typelet(x,v,y1,b,getrtype v)
  203. else if y2 and not(y2 eq 'yetunknowntype)
  204. then return if z := get(y2,'typeletfn)
  205. then lispapply(z,list(x,v,nil,b,y2))
  206. else typelet(x,v,nil,b,y2)
  207. else letscalar(u,v,w,x,b,flgg)
  208. end;
  209. % 18 Apr 00.
  210. symbolic procedure mcharg1(u,v,w);
  211. if null u and null v then list nil
  212. else begin integer m,n;
  213. m := length u;
  214. n := length v;
  215. if flagp(w,'nary) and m>2
  216. then if m<=matchlength!* and flagp(w,'symmetric)
  217. then return mchcomb(u,v,w)
  218. else if n=2 then <<u := cdr mkbin(w,u); m := 2>>
  219. else return nil;
  220. return if m neq n then nil
  221. else if flagp(w,'symmetric) then mchsarg(u,v,w)
  222. else if mtp v then list pair(v,u)
  223. else mcharg2(u,v,list nil,w)
  224. end;
  225. % 19 Sep 00, 7 May 01, 15 Jun 01.
  226. symbolic procedure letscalar(u,v,w,x,b,flgg);
  227. begin
  228. if not atom x
  229. then if not idp car x then return errpri2(u,'hold)
  230. else if car x eq 'df
  231. then if null letdf(u,v,w,x,b) then nil
  232. else return nil
  233. else if getrtype car x
  234. then return let2(reval x,v,w,b)
  235. else if not get(car x,'simpfn)
  236. then <<redmsg(car x,"operator");
  237. mkop car x;
  238. return let3(u,v,w,b,flgg)>>
  239. else nil
  240. else if null b and null w
  241. then <<remprop(x,'avalue);
  242. remprop(x,'rtype);
  243. remflag(list x,'antisymmetric);
  244. remprop(x,'infix);
  245. remprop(x,'kvalue);
  246. remflag(list x,'linear);
  247. remflag(list x,'noncom);
  248. remprop(x,'op);
  249. remprop(x,'opmtch);
  250. remprop(x,'simpfn);
  251. remflag(list x,'symmetric);
  252. wtl!* := delasc(x,wtl!*);
  253. if flagp(x,'opfn)
  254. then <<remflag(list x,'opfn); remd x>>;
  255. rmsubs();
  256. return nil>>;
  257. if eqcar(x,'expt) and caddr x memq frlis!*
  258. then letexprn(u,v,w,!*k2q x,b,flgg)
  259. else if eqcar(x,'sqrt)
  260. then <<!*sqrtrulep := t;
  261. let2({'expt,cadr x,'(quotient 1 2)},v,w,b)>>;
  262. x := simp0 x where !*precise = t;
  263. return if not domainp numr x then letexprn(u,v,w,x,b,flgg)
  264. else errpri1 u
  265. end;
  266. symbolic procedure setk1(u,v,b);
  267. begin scalar x,y,z,!*uncached;
  268. !*uncached := t;
  269. if atom u
  270. then <<if null b
  271. then <<if not get(u,'avalue)
  272. then msgpri(nil,u,"not found",nil,nil)
  273. else remprop(u,'avalue);
  274. return nil>>
  275. else if (x:= get(u,'avalue)) then put!-avalue(u,car x,v)
  276. else put!-avalue(u,'scalar,v);
  277. return v>>
  278. else if not atom car u
  279. then rerror(alg,25,"Invalid syntax: improper assignment");
  280. u := car u . revlis cdr u;
  281. if null b
  282. then <<z:=assoc(u,wtl!*);
  283. if not(y := get(car u,'kvalue))
  284. or not (x := assoc(u,y))
  285. then <<if null z and null !*sqrtrulep then
  286. msgpri(nil,u,"not found",nil,nil)>>
  287. else put(car u,'kvalue,delete(x,y));
  288. if z then wtl!*:=delasc(u,wtl!*);
  289. return nil>>
  290. else if not (y := get(car u,'kvalue))
  291. then put!-kvalue(car u,nil,u,v)
  292. else <<if x := assoc(u,y)
  293. then <<updoldrules(u,v); y := delasc(car x,y)>>;
  294. put!-kvalue(car u,y,u,v)>>;
  295. return v
  296. end;
  297. % 7 May 01.
  298. symbolic procedure clearrules u;
  299. begin scalar !*sqrtrulep;
  300. return rule!-list(u,nil)
  301. end;
  302. % 2 Feb 01.
  303. symbolic procedure simprad(u,n);
  304. if !*reduced then multsq(radfa(numr u,n),invsq radfa(denr u,n))
  305. else begin scalar iflag,x,y,z;
  306. if !*rationalize then <<
  307. y:=list(denr u,1);
  308. u:=multf(numr u, exptf(denr u,n-1)) ./ 1 >>
  309. else y := radf(denr u,n);
  310. if n=2 and minusf numr u
  311. then <<iflag := t; x := radf(negf numr u,n)>>
  312. else x := radf(numr u,n);
  313. z := simp list('quotient,retimes cdr x, retimes cdr y);
  314. if domainp numr z and domainp denr z
  315. then z := multsq(mkrootsq(prepf numr z,n),
  316. invsq mkrootsq(prepf denr z,n))
  317. else <<if iflag
  318. then <<iflag := nil;
  319. z := negsq z>>;
  320. z := mkrootsq(prepsq z,n)>>;
  321. z := multsq(multsq(if !*precise and evenp n
  322. then car x ./ 1
  323. else car x ./ 1, 1 ./ car y), z);
  324. if iflag then z := multsq(z,mkrootsq(-1,2));
  325. return z
  326. end;
  327. symbolic procedure radfa(u,n);
  328. begin scalar x,y;
  329. x := fctrf u;
  330. if numberp car x then x := append(zfactor car x,cdr x)
  331. else x := (car x ./ 1) . cdr x;
  332. y := 1 ./ 1;
  333. for each j in x do y := multsq(y,radfb(car j,cdr j,n));
  334. return y
  335. end;
  336. symbolic procedure radfb(u,m,n);
  337. begin scalar x,y;
  338. x := radf(u,n);
  339. y := exptf(car x,m) ./ 1;
  340. return multsq(exptsq(mkrootlsq(cdr x,n),m),y)
  341. end;
  342. % 20 Feb 01.
  343. symbolic procedure reval2(u,v);
  344. if v or null !*combineexpt or dmode!* then !*q2a1(simp!* u,v)
  345. else !*q2a1((simp!* u where !*mcd = nil),v);
  346. % 1 Jun 01.
  347. symbolic procedure simpexpt2(u,n,flg);
  348. begin scalar m,n,x,y;
  349. if u=1 then return 1 ./ 1;
  350. m:=numr n;
  351. if pairp u then <<
  352. if car u eq 'expt
  353. then <<n:=multsq(m:=simp caddr u,n);
  354. if !*precise
  355. then u := list('abs,cadr u)
  356. else u := cadr u;
  357. return simpexpt1(u,n,flg)>>
  358. else if car u eq 'sqrt and not !*keepsqrts
  359. then return simpexpt2(cadr u, multsq(1 ./ 2,n),flg)
  360. else if car u eq 'times and not !*precise
  361. then <<x := 1 ./ 1;
  362. for each z in cdr u do x := multsq(simpexpt1(z,n,flg),x);
  363. return x>>
  364. else if car u eq 'times and (y:=split!-sign cdr u) and car y
  365. then <<x := simpexpt1(retimes append(cadr y,cddr y),n,flg);
  366. for each z in car y do x := multsq(simpexpt1(z,n,flg),x);
  367. return x>>
  368. else if car u eq 'quotient
  369. and (not !*precise
  370. or posnump caddr u and posnump prepsq n
  371. )
  372. then <<if not flg and !*mcd then
  373. return simpexpt1(prepsq simp!* u,n,t);
  374. n := prepsq n;
  375. return quotsq(simpexpt{cadr u,n},simpexpt{caddr u,n})>>
  376. else if car u eq 'minus and not !*precise and not(cadr u = 1)
  377. then return (multsq(simpexpt list(-1,expon),
  378. simpexpt list(cadr u,expon))) where expon=prepsq n>>;
  379. if null flg
  380. then <<if null(dmode!* and idp u and get(u,dmode!*))
  381. then u := prepsq simp!* u;
  382. return simpexpt1(u,n,t)>>
  383. else if numberp u and zerop u then return nil ./ 1
  384. else if not numberp m then m := prepf m;
  385. n := prepf denr n;
  386. if m memq frlis!* and n=1 then return list ((u . m) . 1) . 1;
  387. if !*mcd or not numberp m or n neq 1
  388. or atom u or denr simp!* u neq 1 then return simpx1(u,m,n)
  389. else return mksq(u,m)
  390. end;
  391. endpatch;
  392. % Algint declarations.
  393. fluid '(!*noacn !*structure !*tra !*trmin gaussiani intvar sqrtflag);
  394. fluid '(!*pvar listofallsqrts listofnewsqrts);
  395. global '(modevalcount);
  396. patch algint;
  397. % 20 Sep 00.
  398. symbolic procedure algebraiccase(expression,zlist,varlist);
  399. begin
  400. scalar rischpart,deriv,w,firstterm;
  401. scalar sqrtflag,!*structure;
  402. sqrtflag:=t;
  403. sqrtsave(listofallsqrts,listofnewsqrts,list(intvar . intvar));
  404. rischpart:= errorset!*(list('doalggeom,mkquote expression),
  405. !*backtrace);
  406. newplace list (intvar.intvar);
  407. if atom rischpart
  408. then <<
  409. if !*tra then prin2t "Inner integration failed";
  410. deriv:=nil ./ 1;
  411. rischpart:=deriv >>
  412. else
  413. if atom car rischpart
  414. then <<
  415. if !*tra or !*trmin then
  416. prin2t "The 'logarithmic part' is not elementary";
  417. return (nil ./ 1) . expression >>
  418. else <<
  419. rischpart:=car rischpart;
  420. deriv:=!*diffsq(rischpart,intvar) where sqrtflag=nil;
  421. if !*tra or !*trmin then <<
  422. prin2t "Inner working yields";
  423. printsq rischpart;
  424. prin2t "with derivative";
  425. printsq deriv >> >>;
  426. deriv:=!*addsq(expression,negsq deriv);
  427. if null numr deriv
  428. then return rischpart . (nil ./ 1);
  429. if null involvesq(deriv,intvar)
  430. then return !*addsq(rischpart,
  431. !*multsq(deriv,((mksp(intvar,1) .* 1) .+ nil) ./ 1))
  432. . (nil ./ 1);
  433. varlist:=getvariables deriv;
  434. zlist:=findzvars(varlist,list intvar,intvar,nil);
  435. varlist:=setdiff(varlist,zlist);
  436. firstterm:=simp!* car zlist;
  437. w:=sqrt2top !*multsq(deriv,invsq !*diffsq(firstterm,intvar));
  438. if null involvesq(w,intvar)
  439. then return !*addsq(rischpart,!*multsq(w,firstterm)) . (nil ./ 1);
  440. if !*noacn then interr "Testing only logarithmic code";
  441. deriv:=transcendentalcase(deriv,intvar,nil,zlist,varlist);
  442. return !*addsq(car deriv, rischpart) . cdr deriv
  443. end;
  444. % 22 Jan 01, 9 Feb 01.
  445. symbolic procedure combine!-logs(coef,logarg);
  446. begin
  447. scalar ans,dencoef,parts,logs,lparts,!*rationalize,trueimag;
  448. !*rationalize:=t;
  449. coef:=simp!* coef;
  450. if null numr logarg then return coef;
  451. parts:=split!-real!-imag numr coef;
  452. if null numr cdr parts then return multsq(coef,logarg);
  453. dencoef:=multf(denr coef,denr logarg);
  454. if !*tra then <<
  455. prin2t "attempting to find 'real' form for";
  456. mathprint list('times,list('plus,prepsq car parts,
  457. list('times,prepsq cdr parts,'i)),
  458. prepsq logarg) >>;
  459. logarg:=numr logarg;
  460. logs:= 1 ./ 1;
  461. while pairp logarg do <<
  462. if ldeg logarg neq 1 then interr "what a log";
  463. if atom mvar logarg then interr "what a log";
  464. if car mvar logarg neq 'log then interr "what a log";
  465. logs:=!*multsq(logs,
  466. !*exptsq(simp!* cadr mvar logarg,lc logarg));
  467. logarg:=red logarg >>;
  468. logs:=rationalizesq logs;
  469. ans:=multsq(!*multsq(car parts,logs),1 ./ dencoef);
  470. lparts:=split!-real!-imag numr logs;
  471. if numr difff(denr cdr lparts,intvar)
  472. then interr "unexpected denominator";
  473. lparts:=!*multsq(denr cdr lparts ./ 1,car lparts) . cdr lparts;
  474. if not onep denr car lparts then interr "unexpected denominator";
  475. trueimag:=quotsq(addf(!*exptf(numr car lparts,2),
  476. !*exptf(numr cdr lparts,2)) ./ 1,
  477. !*exptf(denr logs,2) ./ 1);
  478. if numr diffsq(trueimag,intvar)
  479. then ans:=!*addsq(ans,
  480. !*multsq(gaussiani ./ multf(2,dencoef),
  481. !*multsq(simplogsq trueimag,cdr parts)));
  482. trueimag:=!*multsq(car lparts,!*invsq(numr cdr lparts ./ 1));
  483. if numr diffsq(trueimag,intvar)
  484. then ans:=!*addsq(ans,!*multsq(!*multsq(cdr parts,1 ./ dencoef),
  485. !*k2q list('atan,prepsq!* trueimag)));
  486. return ans;
  487. end;
  488. % 6 Mar 01.
  489. symbolic procedure modevalvar v;
  490. begin scalar w;
  491. if atom v
  492. then <<if (w := get(v,'modvalue)) then return w;
  493. put(v,'modvalue,modevalcount);
  494. modevalcount := modevalcount+1;
  495. return modevalcount-1>>
  496. else if car v neq 'sqrt
  497. then <<if !*tra then <<princ "Unexpected algebraic:"; print v>>;
  498. error1()>>
  499. else if numberp cadr v then return (mksp(v,1) .* 1) .+ nil;
  500. w := modeval(!*q2f simp cadr v,!*pvar);
  501. w := assoc(w,listofallsqrts);
  502. if w then return cdr w else return 'failed
  503. end;
  504. endpatch;
  505. % Excalc declarations.
  506. global '(basisforml!* detm!* indxl!* metricd!* metricu!*);
  507. smacro procedure ldpf u;
  508. caar u;
  509. smacro procedure lowerind u;
  510. list('minus,u);
  511. patch excalc;
  512. % 16 Nov 99.
  513. symbolic procedure mkmetric u;
  514. begin scalar x,y,z,okord;
  515. putform(list(cadr u,nil,nil),0);
  516. put(cadr u,'indxsymmetries,
  517. '((lambda (indl) (tot!-sym!-indp
  518. (evlis '((nth indl 1)
  519. (nth indl 2)))))));
  520. put(cadr u,'indxsymmetrize,
  521. '((lambda (indl) (symmetrize!-inds '(1 2) indl))));
  522. flag(list cadr u,'covariant);
  523. okord := kord!*;
  524. kord!* := basisforml!*;
  525. x := simp!* caddr u;
  526. y := indxl!*;
  527. metricu!* := t;
  528. for each j in indxl!* do
  529. <<for each k in y do
  530. setk(list(cadr u,lowerind j,lowerind k),0);
  531. y := cdr y>>;
  532. for each j on partitsq(x,'basep) do
  533. if ldeg ldpf j = 2 then
  534. setk(list(cadr u,lowerind cadr mvar ldpf j,
  535. lowerind cadr mvar ldpf j),
  536. mk!*sq lc j)
  537. else
  538. setk(list(cadr u,lowerind cadr mvar ldpf j,
  539. lowerind cadr mvar lc ldpf j),
  540. mk!*sq multsq(lc j,1 ./ 2));
  541. kord!* := okord;
  542. x := for each j in indxl!* collect
  543. for each k in indxl!* collect
  544. simpindexvar list(cadr u,lowerind j,lowerind k);
  545. z := subfg!*;
  546. subfg!* := nil;
  547. y := lnrsolve(x,generateident length indxl!*);
  548. subfg!* := z;
  549. metricd!* := mkasmetric x;
  550. metricu!* := mkasmetric y;
  551. detm!* := mk!*sq detq x
  552. end;
  553. endpatch;
  554. % Ezgcd declarations.
  555. fluid '(image!-set reduced!-degree!-lclst unlucky!-case);
  556. symbolic smacro procedure polyzerop u; null u;
  557. patch ezgcd;
  558. % 8 Nov 99.
  559. symbolic procedure ezgcdf(u,v);
  560. begin scalar kordx,x;
  561. kordx := kord!*;
  562. x := errorset2{'ezgcdf1,mkquote u,mkquote v};
  563. if null errorp x then return first x;
  564. setkorder kordx;
  565. return gcdf1(u,v)
  566. end;
  567. symbolic procedure poly!-gcd(u,v);
  568. begin scalar !*exp,z;
  569. if polyzerop u then return poly!-abs v
  570. else if polyzerop v then return poly!-abs u
  571. else if u=1 or v=1 then return 1;
  572. !*exp := t;
  573. if quotf1(u,v) then z := v
  574. else if quotf1(v,u) then z := u
  575. else if !*gcd then z := gcdlist list(u,v)
  576. else z := 1;
  577. return poly!-abs z
  578. end;
  579. symbolic procedure gcdlist3(l,onestep,vlist);
  580. begin
  581. scalar unlucky!-case,image!-set,gg,gcont,l1,w,w1,w2,
  582. reduced!-degree!-lclst,p1,p2;
  583. l1:=for each p in l collect p . ezgcd!-comfac p;
  584. l:=for each c in l1 collect
  585. quotfail1(car c,comfac!-to!-poly cdr c,
  586. "Content divison in GCDLIST3 failed");
  587. gcont:=gcdlist for each c in l1 collect cddr c;
  588. if domainp gcont then if not(gcont=1)
  589. then errorf "GCONT has numeric part";
  590. l := sort(for each p in l collect poly!-abs p,function ordp);
  591. w := nil;
  592. while l do <<
  593. w := car l . w;
  594. repeat l := cdr l until null l or not(car w = car l)>>;
  595. l := reversip w;
  596. w := nil;
  597. if null cdr l then return multf(gcont,car l);
  598. if domainp (gg:=car (l:=sort(l,function degree!-order))) then
  599. return gcont;
  600. if ldeg gg=1 then <<
  601. if division!-test(gg,l) then return multf(poly!-abs gg,gcont)
  602. else return gcont >>;
  603. if onestep then <<
  604. p1 := poly!-abs car l; p2 := poly!-abs cadr l;
  605. if p1=p2 then <<
  606. if division!-test(p1,cddr l) then return multf(p1,gcont) >>
  607. else <<
  608. gg := poly!-gcd(lc p1,lc p2);
  609. w1 := multf(red p1, quotfail1(lc p2, gg,
  610. "Division failure when just one pseudoremainder step needed"));
  611. w2 := multf(red p2,negf quotfail1(lc p1, gg,
  612. "Division failure when just one pseudoremainder step needed"));
  613. w := ldeg p1 - ldeg p2;
  614. if w > 0 then w2 := multf(w2, (mksp(mvar p2, w) .* 1) .+ nil)
  615. else if w < 0
  616. then w1 := multf(w1, (mksp(mvar p1, -w) .* 1) .+ nil);
  617. gg := ezgcd!-pp addf(w1, w2);
  618. if division!-test(gg,l) then return multf(gg,gcont) >>>>;
  619. return gcdlist31(l,vlist,gcont,gg,l1)
  620. end;
  621. endpatch;
  622. % Groebner declarations.
  623. fluid '(!*groebopt !*gsugar global!-dipvars!*);
  624. smacro procedure vdpevlmon u; cadr u;
  625. patch groebner;
  626. % 7 Nov 01.
  627. symbolic procedure gindependent_seteval pars;
  628. begin scalar a,u,v,vars,w,oldorder,!*factor,!*exp,!*gsugar,!*groebopt;
  629. !*exp:=t;
  630. u:=reval car pars;
  631. v:=if cdr pars then reval cadr pars else nil;
  632. w:=for each j in groerevlist u collect if eqexpr j then !*eqn2a j
  633. else j;
  634. if null w then rerror(groebnr2,3,"empty list");
  635. a:=if null !*groebopt and global!-dipvars!* and cdr global!-dipvars!*
  636. then cdr global!-dipvars!* else gvarlis w;
  637. vars:=if null v then for each j in a collect !*a2k j else groerevlist v;
  638. if not vars then return'(list);
  639. oldorder:=vdpinit vars;
  640. w:=for each j in w collect vdpevlmon a2vdp j;
  641. vars:=for each y in vars collect y.vdpevlmon a2vdp y;
  642. w:=groebkwprec(vars,nil,w,nil);
  643. return 'list.for each s in w collect
  644. 'list.reversip for each x in s collect car x
  645. end;
  646. endpatch;
  647. % Int declarations.
  648. fluid '(!*failhard !*purerisch !*reverse !*trdint sqrt!-places!-alist
  649. badpart ccount cmap cmatrix content cval denbad denominator!*
  650. lhs!* loglist orderofelim rhs!* tanlist !*intflag!* indexlist
  651. intvar listofnewsqrts listofallsqrts lorder power!-list!*
  652. sqrtflag sqrtlist sqrt!-intvar basic!-listofnewsqrts
  653. basic!-listofallsqrts sqfr sillieslist varlist);
  654. global '(!*number!* !*seplogs !*spsize!* !*statistics gensymcount);
  655. patch int;
  656. % 18 Dec 99.
  657. symbolic procedure findtrialdivs zl;
  658. begin scalar dlists1,args1;
  659. for each z in zl do
  660. if exportan z
  661. then <<if car z eq 'tan
  662. then <<args1 := (mksp(z,2) .* 1) .+ 1;
  663. tanlist := (args1 ./ 1) . tanlist>>
  664. else args1 := !*kk2f z;
  665. dlists1 := (z . args1) . dlists1>>;
  666. return dlists1
  667. end;
  668. % 12 Dec 00.
  669. symbolic procedure simpdint u;
  670. begin scalar low,upp,fn,var,x,y;
  671. if length u neq 4
  672. then rerror(int,2,"Improper number of arguments to INT");
  673. load!-package 'defint;
  674. fn := car u;
  675. var := cadr u;
  676. low := caddr u;
  677. upp := cadddr u;
  678. low := reval low;
  679. upp := reval upp;
  680. if low = upp then return nil ./ 1
  681. else if null getd 'new_defint then nil
  682. else if upp = 'infinity
  683. then if low = 0
  684. then if not smemql('(infinity unknown),
  685. x := defint!* {fn,var})
  686. then return simp!* x else nil
  687. else if low = '(minus infinity)
  688. then return mkinfint(fn,var)
  689. else if freeof(var,low)
  690. then if not smemql('(infinity unknown),
  691. x := defint!* {fn,var})
  692. and not smemql('(infinity unknown),
  693. y := indefint!* {fn,var,low})
  694. then return simp!* {'difference,x,y} else nil
  695. else nil
  696. else if upp = '(minus infinity) or low = 'infinity
  697. then return negsq simpdint {fn,var,upp,low}
  698. else if low = '(minus infinity)
  699. then return
  700. simpdint{prepsq simp{'sub,{'equal,var,{'minus,var}},fn},
  701. var,{'minus,upp},'infinity}
  702. else if low = 0
  703. then if freeof(var,upp)
  704. and not smemql('(infinity unknown),
  705. x := indefint!* {fn,var,upp})
  706. then return simp!* x else nil
  707. else if freeof(var,upp) and freeof(var,low)
  708. and not smemq('(infinity unknown),
  709. x := indefint!* {fn,var,upp})
  710. and not smemql('(infinity unknown),
  711. y := indefint!* {fn,var,low})
  712. then return simp!* {'difference,x,y};
  713. return mkdint(fn,var,low,upp)
  714. end;
  715. % 1 Jun 01.
  716. symbolic procedure simpint u;
  717. if atom u or null cdr u or cddr u and (null cdddr u or cddddr u)
  718. then rerror(int,1,"Improper number of arguments to INT")
  719. else if cddr u then simpdint u
  720. else begin scalar ans,dmod,expression,variable,loglist,oldvarstack,
  721. !*intflag!*,!*purerisch,cflag,intvar,listofnewsqrts,
  722. listofallsqrts,sqrtfn,sqrt!-intvar,sqrt!-places!-alist,
  723. basic!-listofallsqrts,basic!-listofnewsqrts,coefft,
  724. varchange,w,!*precise;
  725. !*intflag!* := t;
  726. variable := !*a2k cadr u;
  727. if not(idp variable or pairp variable and numlistp cdr variable)
  728. then <<varchange := variable . intern gensym();
  729. if !*trint
  730. then prin2t {"Integration kernel", variable,
  731. "replaced by simple variable", cdr varchange};
  732. variable := cdr varchange>>;
  733. intvar := variable;
  734. w := cddr u;
  735. if w then rerror(int,3,"Too many arguments to INT");
  736. listofnewsqrts:= list mvar gaussiani;
  737. listofallsqrts:= list (cadr mvar gaussiani . gaussiani);
  738. sqrtfn := get('sqrt,'simpfn);
  739. put('sqrt,'simpfn,'proper!-simpsqrt);
  740. if dmode!* then
  741. << if (cflag:=get(dmode!*, 'cmpxfn)) then onoff('complex, nil);
  742. if (dmod := get(dmode!*,'dname)) then
  743. onoff(dmod,nil)>> where !*msg := nil;
  744. begin scalar dmode!*,!*exp,!*gcd,!*keepsqrts,!*limitedfactors,!*mcd,
  745. !*rationalize,!*structure,!*uncached,kord!*,
  746. ans1,denexp,badbit,nexp,oneterm;
  747. !*keepsqrts := !*limitedfactors := t;
  748. !*exp := !*gcd := !*mcd := !*structure := !*uncached := t;
  749. dmode!* := nil;
  750. if !*algint
  751. then <<
  752. sqrt!-intvar:=!*q2f simpsqrti variable;
  753. if (red sqrt!-intvar) or (lc sqrt!-intvar neq 1)
  754. or (ldeg sqrt!-intvar neq 1)
  755. then interr "Sqrt(x) not properly formed"
  756. else sqrt!-intvar:=mvar sqrt!-intvar;
  757. basic!-listofallsqrts:=listofallsqrts;
  758. basic!-listofnewsqrts:=listofnewsqrts;
  759. sqrtsave(basic!-listofallsqrts,basic!-listofnewsqrts,
  760. list(variable . variable))>>;
  761. coefft := (1 ./ 1);
  762. expression := int!-simp car u;
  763. if varchange
  764. then <<depend1(car varchange,cdr varchange,t);
  765. expression := int!-subsq(expression,{varchange})>>;
  766. denexp := 1 ./ denr expression;
  767. nexp := numr expression;
  768. while not atom nexp and null cdr nexp and
  769. not depends(mvar nexp,variable) do
  770. <<coefft := multsq(coefft,(((caar nexp) . 1) . nil) ./ 1);
  771. nexp := lc nexp>>;
  772. ans1 := nil;
  773. while nexp do begin
  774. scalar x,zv,tmp;
  775. if atom nexp then <<x := !*f2q nexp; nexp := nil>>
  776. else <<x := !*t2q car nexp; nexp := cdr nexp>>;
  777. x := multsq(x,denexp);
  778. zv := findzvars(getvariables x,list variable,variable,nil);
  779. begin scalar oldzlist;
  780. while oldzlist neq zv do <<
  781. oldzlist := zv;
  782. foreach zz in oldzlist do
  783. zv:=findzvars(distexp(pseudodiff(zz,variable)),
  784. zv,variable,t)>>;
  785. % The following line was added to make, for example,
  786. % int(df(sin(x)/x),x) return the expected result.
  787. zv := sort(zv, function ordp)
  788. end;
  789. tmp := ans1;
  790. while tmp do
  791. <<if zv=caar tmp
  792. then <<rplacd(car tmp,addsq(cdar tmp,x));
  793. tmp := nil; zv := nil>>
  794. else tmp := cdr tmp>>;
  795. if zv then ans1 := (zv . x) . ans1
  796. end;
  797. if length ans1 = 1 then oneterm := t;
  798. nexp := ans1;
  799. ans := nil ./ 1;
  800. badbit:=nil ./ 1;
  801. while nexp do
  802. <<u := cdar nexp;
  803. if !*trdint
  804. then <<princ "Integrate"; printsq u;
  805. princ "with Zvars "; print caar nexp>>;
  806. ans1 := errorset!*(list('integratesq,mkquote u,
  807. mkquote variable,mkquote loglist,
  808. mkquote caar nexp),
  809. !*backtrace);
  810. nexp := cdr nexp;
  811. if errorp ans1 then badbit := addsq(badbit,u)
  812. else <<ans := addsq(caar ans1, ans);
  813. badbit:=addsq(cdar ans1,badbit)>>>>;
  814. if !*trdint
  815. then <<prin2 "Partial answer="; printsq ans;
  816. prin2 "To do="; printsq badbit>>;
  817. if badbit neq '(nil . 1)
  818. then <<setkorder nil;
  819. badbit := reordsq badbit;
  820. ans := reordsq ans;
  821. coefft := reordsq coefft;
  822. if !*trdint then <<princ "Retrying..."; printsq badbit>>;
  823. if oneterm and ans = '(nil . 1) then ans1 := nil
  824. else ans1 := errorset!*(list('integratesq,mkquote badbit,
  825. mkquote variable,mkquote loglist,nil),
  826. !*backtrace);
  827. if null ans1 or errorp ans1
  828. then ans := addsq(ans,simpint1(badbit . variable . w))
  829. else <<ans := addsq(ans,caar ans1);
  830. if not smemq(variable, ans) then ans := nil ./ 1;
  831. if cdar ans1 neq '(nil . 1)
  832. then ans := addsq(ans,
  833. simpint1(cdar ans1 . variable . w))
  834. >>>>;
  835. end;
  836. ans := multsq(coefft,ans);
  837. if !*trdint then << prin2t "Resimp and all that"; printsq ans >>;
  838. put('int,'simpfn,'simpiden);
  839. put('sqrt,'simpfn,sqrtfn);
  840. << if dmod then onoff(dmod,t);
  841. if cflag then onoff('complex,t)>> where !*msg := nil;
  842. oldvarstack := varstack!*;
  843. varstack!* := nil;
  844. ans := errorset!*(list('int!-resub,mkquote ans,mkquote
  845. varchange),t);
  846. put('int,'simpfn,'simpint);
  847. varstack!* := oldvarstack;
  848. return if errorp ans then error1() else car ans
  849. end;
  850. symbolic procedure mkdint(fn,var,low,upp);
  851. begin scalar x,!*precise;
  852. if getd 'defint0
  853. and not((x := defint0 {fn,var,low,upp}) eq 'failed)
  854. then return simp x
  855. else if not smemq('infinity,low) and not smemq('infinity,upp)
  856. then <<x := prepsq!* simpint {fn,var};
  857. if not eqcar(x,'int)
  858. then return simp!* {'difference,
  859. subeval {{'equal,var,upp},x},
  860. subeval {{'equal,var,low},x}}>>;
  861. return mksq({'int,fn,var,low,upp},1)
  862. end;
  863. % 9 Aug 01.
  864. symbolic
  865. procedure transcendentalcase(integrand,svar,xlogs,zlist,varlist);
  866. begin scalar divlist,jhd!-content,content,prim,sqfr,dfu,indexlist,
  867. sillieslist,originalorder,wrongway,power!-list!*,
  868. sqrtlist,tanlist,loglist,dflogs,eprim,dfun,unintegrand,
  869. sqrtflag,badpart,rhs!*,lhs!*,gcdq,cmap,cval,orderofelim,cmatrix;
  870. scalar ccount,denominator!*,result,denbad,temp;
  871. gensymcount:=0;
  872. integrand:=sqrt2top integrand;
  873. if !*trint then << printc "Extension variables z<i> are";
  874. print zlist>>;
  875. begin scalar w,gg;
  876. gg:=1;
  877. foreach z in zlist do
  878. <<w := subs2 diffsq(simp z,svar);
  879. gg := !*multf(gg,quotf(denr w,gcdf(denr w,gg)))>>;
  880. gg := quotf(gg,gcdf(gg,denr integrand));
  881. unintegrand := (!*multf(gg,numr integrand)
  882. ./ !*multf(gg,denr integrand));
  883. if !*trint then <<
  884. printc "After unnormalization the integrand is ";
  885. printsq unintegrand >>
  886. end;
  887. divlist := findtrialdivs zlist;
  888. sqrtlist := findsqrts zlist;
  889. divlist := trialdiv(denr unintegrand,divlist);
  890. prim := sqfree(cdr divlist,zlist);
  891. jhd!-content := content;
  892. printfactors(prim,nil);
  893. eprim := sqmerge(countz car divlist,prim,nil);
  894. printfactors(eprim,t);
  895. sqfr := for each u in eprim collect multup u;
  896. if !*reverse then zlist := reverse zlist;
  897. indexlist := createindices zlist;
  898. dfu:=dfnumr(svar,car divlist);
  899. loglist := append(loglist,factorlistlist prim);
  900. loglist := mergein(xlogs,loglist);
  901. loglist := mergein(tanlist,loglist);
  902. cmap := createcmap();
  903. ccount := length cmap;
  904. if !*trint then <<printc "Loglist "; print loglist>>;
  905. dflogs := difflogs(loglist,denr unintegrand,svar);
  906. if !*trint
  907. then <<printc "************ 'Derivative' of logs is:";
  908. printsq dflogs>>;
  909. dflogs := addsq((numr unintegrand) ./ 1,negsq dflogs);
  910. gcdq := gcdf(denr dflogs,denr dfu);
  911. dfun := !*multf(numr dfu,denbad:=quotf(denr dflogs,gcdq));
  912. denbad := !*multf(denr dfu,denbad);
  913. denbad := !*multf(denr unintegrand,denbad);
  914. dflogs := !*multf(numr dflogs,quotf(denr dfu,gcdq));
  915. dfu := dfun;
  916. rhs!* := multbyarbpowers f2df dfu;
  917. if checkdffail(rhs!*,svar)
  918. then <<if !*trint then printsq checkdffail(rhs!*,svar);
  919. interr "Simplification fails on above expression">>;
  920. if !*trint then <<
  921. printc "Distributed Form of Numerator is:";
  922. printdf rhs!*>>;
  923. lhs!* := f2df dflogs;
  924. if !*trint then << printc "Distributed Form of integrand is:";
  925. printdf lhs!*;
  926. terpri()>>;
  927. cval := mkvect(ccount);
  928. for i := 0:ccount do putv(cval,i,nil ./ 1);
  929. power!-list!* := tansfrom(rhs!*,zlist,indexlist,0);
  930. lorder:=maxorder(power!-list!*,zlist,0);
  931. originalorder := for each x in lorder collect x;
  932. if !*trint then <<
  933. printc "Maximum order for variables determined as ";
  934. print lorder >>;
  935. if !*statistics then << !*number!*:=0;
  936. !*spsize!*:=1;
  937. foreach xx in lorder do
  938. !*spsize!*:=!*spsize!* * (xx+1) >>;
  939. dfun:=solve!-for!-u(rhs!*,lhs!*,nil);
  940. backsubst4cs(nil,orderofelim,cmatrix);
  941. if !*statistics then << prin2 !*number!*; prin2 " used out of ";
  942. printc !*spsize!* >>;
  943. badpart:=substinulist badpart;
  944. dfun:=df2q substinulist dfun;
  945. result:= !*multsq(dfun,!*invsq(denominator!* ./ 1));
  946. result:= !*multsq(result,!*invsq(jhd!-content ./ 1));
  947. dflogs:=logstosq();
  948. if not null numr dflogs then <<
  949. if !*seplogs and (not domainp numr result) then <<
  950. result:=mk!*sq result;
  951. result:=(mksp(result,1) .* 1) .+ nil;
  952. result:=result ./ 1 >>;
  953. result:=addsq(result,dflogs)>>;
  954. if !*trint
  955. then <<
  956. terpri();
  957. printc
  958. "*****************************************************";
  959. printc
  960. "************ THE INTEGRAL IS : **********************";
  961. printc
  962. "*****************************************************";
  963. terpri();
  964. printsq result;
  965. terpri()>>;
  966. if badpart then begin scalar n,oorder;
  967. if !*trint
  968. then printc "plus a part which has not been integrated";
  969. lhs!*:=badpart;
  970. lorder:=maxorder(power!-list!*,zlist,0);
  971. oorder:=originalorder;
  972. n:=length lorder;
  973. while lorder do <<
  974. if car lorder > car originalorder then
  975. wrongway:=t;
  976. if car lorder=car originalorder then n:= n-1;
  977. lorder:=cdr lorder;
  978. originalorder:=cdr originalorder >>;
  979. if !*trint and wrongway then printc "Went wrong way";
  980. dfun:=df2q badpart;
  981. dfun:= !*multsq(dfun,invsq(denbad ./ 1));
  982. badpart := dfun;
  983. if wrongway then <<
  984. if !*trint then printc "Resetting....";
  985. result:=nil ./ 1;
  986. dfun := integrand; badpart:=dfun >>;
  987. if rootcheckp(unintegrand,svar) then
  988. return simpint1(integrand . svar.nil) . (nil ./ 1)
  989. else if !*purerisch or allowedfns zlist then
  990. << badpart := dfun;
  991. dfun := nil ./ 1 >>
  992. else << !*purerisch:=t;
  993. if !*trint
  994. then <<printc " Applying transformations ...";
  995. printsq dfun>>;
  996. temp := get('tan,'opmtch);
  997. remprop('tan,'opmtch);
  998. denbad:=transform(dfun,svar);
  999. if denbad=dfun
  1000. then <<dfun:=nil ./ 1;
  1001. badpart:=denbad;
  1002. put('tan,'opmtch,temp)>>
  1003. else <<denbad:=errorset!*(list('integratesq,mkquote denbad,
  1004. mkquote svar,mkquote xlogs, nil),
  1005. !*backtrace);
  1006. put('tan,'opmtch,temp);
  1007. if not atom denbad then <<
  1008. denbad:=car denbad;
  1009. dfun:=untan car denbad;
  1010. if (dfun neq '(nil . 1)) then
  1011. badpart:=untan cdr denbad;
  1012. if car badpart and not(badpart=denbad) then <<
  1013. wrongway:=nil;
  1014. lhs!*:=f2df car badpart;
  1015. lorder:=maxorder(power!-list!*,zlist,0);
  1016. n:=length lorder;
  1017. while lorder do <<
  1018. if car lorder > car oorder then
  1019. wrongway:=t;
  1020. if car lorder=car oorder then n:= n-1;
  1021. lorder:=cdr lorder;
  1022. oorder:=cdr oorder >>;
  1023. if wrongway or (n=0) then <<
  1024. if !*trint then printc "Still backwards";
  1025. dfun := nil ./ 1;
  1026. badpart := integrand>>>>>>
  1027. else <<badpart := dfun; dfun := nil ./ 1 >>>>>>;
  1028. if !*failhard then rerror(int,9,"FAILHARD switch set");
  1029. if !*seplogs and not domainp result then <<
  1030. result:=mk!*sq result;
  1031. if not numberp result
  1032. then result:=(mksp(result,1) .* 1) .+ nil;
  1033. result:=result ./ 1>>;
  1034. result:=addsq(result,dfun) end
  1035. else badpart:=nil ./ 1;
  1036. return (sqrt2top result . badpart)
  1037. end;
  1038. endpatch;
  1039. unfluid '(indexlist); % For eds.
  1040. patch limits;
  1041. % 1 Jun 01.
  1042. symbolic procedure simplimit u;
  1043. begin scalar fn,exprn,var,val,old,v,!*precise,!*protfg;
  1044. if length u neq 4
  1045. then rerror(limit,1,
  1046. "Improper number of arguments to limit operator");
  1047. fn:= car u; exprn := cadr u; var := !*a2k caddr u; val := cadddr u;
  1048. !*protfg := t;
  1049. old := get('cot,'opmtch);
  1050. put('cot,'opmtch,
  1051. '(((!~x) (nil . t) (quotient (cos !~x) (sin !~x)) nil)));
  1052. v := errorset!*({'apply,mkquote fn,mkquote {exprn,var,val}},nil);
  1053. put('cot,'opmtch,old);
  1054. !*protfg := nil;
  1055. return if errorp v or (v := car v) = aeval 'failed then mksq(u,1)
  1056. else simp!* v
  1057. end;
  1058. endpatch;
  1059. % Matrix declarations.
  1060. fluid '(!*bezout);
  1061. patch matrix;
  1062. % 7 Aug 99, 23 Apr 01.
  1063. symbolic procedure quotfexf!*1(u,v);
  1064. if null u then nil
  1065. else (if x then x
  1066. else (if denr y = 1 then numr y
  1067. else if denr (y := (rationalizesq y
  1068. where !*rationalize = t))=1
  1069. then numr y
  1070. else rerror(matrix,11,
  1071. "Catastrophic division failure"))
  1072. where y=rationalizesq(u ./ v))
  1073. where x=quotf(u,v);
  1074. % 23 Jan 01.
  1075. symbolic procedure lnrsolve(u,v);
  1076. begin scalar temp,vlhs,vrhs,ok,
  1077. !*exp,!*solvesingular;
  1078. if !*ncmp then return clnrsolve(u,v);
  1079. !*exp := t;
  1080. if asymplis!* or wtl!* then
  1081. <<temp := asymplis!* . wtl!*;
  1082. asymplis!* := wtl!* := nil>>;
  1083. vlhs := for i:=1:length car u collect intern gensym();
  1084. vrhs := for i:=1:length car v collect intern gensym();
  1085. u := car normmat augment(u,v);
  1086. v := append(vlhs,vrhs);
  1087. ok := setkorder v;
  1088. u := foreach r in u collect prsum(v,r);
  1089. v := errorset!*({function solvebareiss, mkquote u,mkquote vlhs},t);
  1090. if caar v memq {'singular,'inconsistent} then
  1091. <<setkorder ok; rerror(matrix,13,"Singular matrix")>>;
  1092. v := pair(cadr s,car s) where s = cadar v;
  1093. u := foreach j in vlhs collect
  1094. coeffrow(negf numr q,vrhs,denr q) where q = cdr atsoc(j,v);
  1095. setkorder ok;
  1096. if temp then <<asymplis!* := car temp; wtl!* := cdr temp>>;
  1097. return for each j in u collect
  1098. for each k in j collect
  1099. if temp then resimp k else cancel k;
  1100. end;
  1101. % 23 Apr 01.
  1102. symbolic procedure extmult(u,v);
  1103. if null u or null v then nil
  1104. else (if x then cdr x .* (if car x then negf c!:subs2multf(lc u,lc v)
  1105. else c!:subs2multf(lc u,lc v))
  1106. .+ extadd(extmult(!*t2f lt u,red v),
  1107. extmult(red u,v))
  1108. else extadd(extmult(red u,v),extmult(!*t2f lt u,red v)))
  1109. where x = ordexn(car lpow u,lpow v);
  1110. % 14 Jan 01, 7 Aug 01.
  1111. symbolic procedure resultant(u,v,var);
  1112. if domainp u and domainp v then 1
  1113. else begin scalar x;
  1114. kord!* := var . kord!*;
  1115. if null domainp u and null(mvar u eq var) then u := reorder u;
  1116. if null domainp v and null(mvar v eq var) then v := reorder v;
  1117. x := if !*bezout then bezout_resultant(u,v,var)
  1118. else polyresultantf(u,v,var);
  1119. setkorder cdr kord!*;
  1120. return x
  1121. end;
  1122. % 21 Dec 01.
  1123. symbolic procedure resultantsq(u,v,var);
  1124. if domainp numr u and domainp numr v and denr u = 1 and denr v = 1
  1125. then 1 ./ 1
  1126. else begin scalar x,y,z;
  1127. kord!* := var . kord!*;
  1128. if null domainp numr u and null(mvar numr u eq var)
  1129. then u := reordsq u;
  1130. if null domainp numr v and null(mvar numr v eq var)
  1131. then v := reordsq v;
  1132. if (y := denr u) neq 1
  1133. and smember(var,y) then typerr(prepf y,'polynomial)
  1134. else if (z := denr v) neq 1
  1135. and smember(var,z) then typerr(prepf z,'polynomial);
  1136. u := numr u;
  1137. v := numr v;
  1138. if smember(var,coefflist(u,var)) then typerr(prepf u,'polynomial)
  1139. else if smember(var,coefflist(v,var))
  1140. then typerr(prepf v,'polynomial);
  1141. x := if !*bezout then bezout_resultant(u,v,var)
  1142. else polyresultantf(u,v,var);
  1143. if y neq 1 then y := exptf(y,degr(v,var));
  1144. if z neq 1 then y := multf(y,exptf(z,degr(u,var)));
  1145. setkorder cdr kord!*;
  1146. return x ./ y
  1147. end;
  1148. symbolic procedure coefflist(u,var);
  1149. begin scalar z;
  1150. while not domainp u and mvar u=var
  1151. do <<z := (ldeg u . lc u) . z; u := red u>>;
  1152. return if null u then z else (0 . u) . z
  1153. end;
  1154. % 30 Nov 01.
  1155. symbolic procedure polyresultantf(u,v,var);
  1156. begin scalar beta,cd,cn,delta,gam,r,s,temp,x;
  1157. cd := cn := r := s := 1;
  1158. gam := -1;
  1159. if domainp u or domainp v then return 1
  1160. else if ldeg u<ldeg v
  1161. then <<s := (-1)^(ldeg u*ldeg v); temp := u; u := v; v := temp>>;
  1162. while v do
  1163. <<delta := ldeg u-ldegr(v,var);
  1164. beta := negf(multf(r,exptf(gam,delta)));
  1165. r := lcr(v,var);
  1166. if delta neq 0
  1167. then gam := quotf!*(exptf(negf r,delta),exptf(gam,delta-1));
  1168. temp := u;
  1169. u := v;
  1170. if not evenp ldeg temp and not evenp ldegr(u,var) then s := -s;
  1171. v := quotf(pseudo_remf(temp,v,var),beta);
  1172. if v
  1173. then <<cn := multf(cn,exptf(beta,ldeg u));
  1174. cd := multf(cd,
  1175. exptf(r,(1+delta)*ldeg u-ldeg temp+ldegr(v,var)));
  1176. if (x := quotf(cd,cn)) then <<cn := 1; cd := x>>>>>>;
  1177. return if not domainp u and mvar u eq var then nil
  1178. else if ldeg temp neq 1
  1179. then quotf(multf(s,multf(cn,exptf(u,ldeg temp))),cd)
  1180. else u
  1181. end;
  1182. symbolic procedure lcr(u,var);
  1183. if domainp u or mvar u neq var then u else lc u;
  1184. symbolic procedure ldegr(u,var);
  1185. if domainp u or mvar u neq var then 0 else ldeg u;
  1186. symbolic procedure pseudo_remf(u,v,var);
  1187. !*q2f simp pseudo!-remainder {mk!*sq(u ./ 1),mk!*sq(v ./ 1),var};
  1188. symbolic procedure bezout_resultant(u,v,w);
  1189. begin integer n,nm; scalar ap,ep,uh,ut,vh,vt;
  1190. if domainp u or null(mvar u eq w)
  1191. then return if not domainp v and mvar v eq w
  1192. then exptf(u,ldeg v)
  1193. else 1
  1194. else if domainp v or null(mvar v eq w)
  1195. then return if mvar u eq w then exptf(v,ldeg u) else 1;
  1196. n := ldeg v - ldeg u;
  1197. if n < 0 then return multd((-1)**(ldeg u*ldeg v),
  1198. bezout_resultant(v,u,w));
  1199. ep := 1;
  1200. nm := ldeg v;
  1201. uh := lc u;
  1202. vh := lc v;
  1203. ut := if n neq 0 then multpf(w to n,red u) else red u;
  1204. vt := red v;
  1205. ap := addf(multf(uh,vt),negf multf(vh,ut));
  1206. ep := b!:extmult(!*sf2exb(ap,w),ep);
  1207. for j := (nm - 1) step -1 until (n + 1) do
  1208. <<if degr(ut,w) = j then
  1209. <<uh := addf(lc ut,multf(!*k2f w,uh));
  1210. ut := red ut>>
  1211. else uh := multf(!*k2f w,uh);
  1212. if degr(vt,w) = j then
  1213. <<vh := addf(lc vt,multf(!*k2f w,vh));
  1214. vt := red vt>>
  1215. else vh := multf(!*k2f w,vh);
  1216. ep := b!:extmult(!*sf2exb(addf(multf(uh,vt),
  1217. negf multf(vh,ut)),w),ep)>>;
  1218. if n neq 0
  1219. then <<ep := b!:extmult(!*sf2exb(u,w),ep);
  1220. for j := 1:(n-1) do
  1221. ep := b!:extmult(!*sf2exb(multpf(w to j,u),w),ep)>>;
  1222. return if null ep then nil else lc ep
  1223. end;
  1224. endpatch;
  1225. % Ncpoly declarations.
  1226. fluid '(!*complex !*trnc dipvars!*);
  1227. patch ncpoly;
  1228. % 9 Jan 01.
  1229. symbolic procedure nc_factsolve(s,vl,all);
  1230. begin scalar v,sb,ns,so,soa,sol,nz,w,q,z,r,abort;
  1231. v:= numr simp car vl;
  1232. ns:=for each e in s collect numr simp e;
  1233. r:=t;
  1234. while r do
  1235. <<r:=nil; s:=ns; ns:=nil;
  1236. for each e in s do if not abort then
  1237. <<e:=absf numr subf(e,sb);
  1238. while(q:=quotf(e,v)) do e:=q;
  1239. if null e then nil else
  1240. if domainp e or not(mvar e member vl) then abort:=t else
  1241. if null red e and domainp lc e then
  1242. <<w:=mvar e; sb:=(w . 0).sb; r:=t;
  1243. vl:=delete(w,vl)>>
  1244. else if not member(e,ns) then ns:=e.ns
  1245. >>;
  1246. >>;
  1247. if abort or null vl then return nil;
  1248. nc_factorize_timecheck();
  1249. if null ns and vl then
  1250. <<sol:={for each x in vl collect x.1};
  1251. goto done>>;
  1252. s:=for each e in ns collect prepf e;
  1253. if !*trnc then
  1254. <<prin2 "solving ";
  1255. prin2 length s; prin2 " polynomial equations for ";
  1256. prin2 length vl;
  1257. prin2t "variables";
  1258. for each e in s do writepri(mkquote e,'only);>>;
  1259. w:=(cdr solveeval{'list.s,'list.vl} where dipvars!*=nil);
  1260. loop:
  1261. nc_factorize_timecheck();
  1262. if null w then goto done;
  1263. so:= cdr car w; w:=cdr w; soa:=nil;
  1264. if smemq('i,so) and null !*complex then go to loop;
  1265. for each y in vl do if not smember(y,so) then
  1266. <<soa:=(y . 1) . soa; nz:=t>>;
  1267. for each y in so do
  1268. <<z:=nc_factorize_unwrap(reval caddr y,soa);
  1269. nz:=nz or z neq 0;
  1270. soa:=(cadr y . z).soa;
  1271. >>;
  1272. if not nz then goto loop;
  1273. q:=assoc(car vl,soa);
  1274. if null q or cdr q=0 then go to loop;
  1275. soa := for each j in soa collect (car j . sublis(soa,cdr j));
  1276. sol := soa . sol;
  1277. if all then go to loop;
  1278. done:
  1279. sol:=for each s in sol collect append(sb,s);
  1280. if !*trnc then
  1281. <<prin2t "solutions:";
  1282. for each w in sol do
  1283. writepri(mkquote('list.
  1284. for each s in w collect {'equal,car s,cdr s}),'only);
  1285. prin2t "-------------------------";
  1286. >>;
  1287. return sol
  1288. end;
  1289. endpatch;
  1290. % Plot declarations.
  1291. global '(!*plotpause !*plotusepipe dirchar!* opsys!* plotcleanup!*
  1292. plotcmds!* plotcommand!* plotdir!* plotdta!* plotheader!*
  1293. tempdir!*);
  1294. patch plot;
  1295. % 28 Jun 99.
  1296. symbolic procedure init_gnuplot();
  1297. <<
  1298. !*plotpause := -1;
  1299. plotcleanup!* := {};
  1300. tempdir!* := getenv 'tmp;
  1301. if null tempdir!* then tempdir!* := getenv 'temp;
  1302. dirchar!* := "/";
  1303. plotcommand!* := "gnuplot";
  1304. opsys!* := assoc('opsys, lispsystem!*);
  1305. if null opsys!* then opsys!* := 'unknown
  1306. else opsys!* := cdr opsys!*;
  1307. if getenv "gnuplot" then plotdir!* := getenv "gnuplot"
  1308. else if null plotdir!* and not (opsys!* = 'unix)
  1309. then plotdir!* := get!-lisp!-directory();
  1310. if opsys!* = 'win32 then <<
  1311. plotcommand!* := "wgnuplot";
  1312. plotheader!* := "";
  1313. dirchar!* := "\";
  1314. plotdta!* := for each n in
  1315. {"gnutmp.tm1", "gnutmp.tm2", "gnutmp.tm3", "gnutmp.tm4",
  1316. "gnutmp.tm5", "gnutmp.tm6", "gnutmp.tm7", "gnutmp.tm8"}
  1317. collect gtmpnam n;
  1318. plotcleanup!* := if null tempdir!* then {"erase gnutmp.tm*"}
  1319. else {bldmsg("erase %w\gnutmp.tm*", tempdir!*)} >>
  1320. else if opsys!* = 'msdos then <<
  1321. plotheader!* := ""; % ?? "set term vga";
  1322. dirchar!* := "\";
  1323. plotdta!* := for each n in
  1324. {"gnutmp.tm1", "gnutmp.tm2", "gnutmp.tm3", "gnutmp.tm4",
  1325. "gnutmp.tm5", "gnutmp.tm6", "gnutmp.tm7", "gnutmp.tm8"}
  1326. collect gtmpnam n;
  1327. plotcmds!*:= gtmpnam "gnutmp.tm0";
  1328. plotcleanup!* := if null tempdir!* then {"erase gnutmp.tm*"}
  1329. else {bldmsg("erase %w\gnutmp.tm*", tempdir!*)} >>
  1330. else if opsys!* = 'riscos then <<
  1331. plotheader!* := "";
  1332. dirchar!* := ".";
  1333. plotdta!* := for i:=1:10 collect tmpnam();
  1334. plotcmds!*:= tmpnam();
  1335. plotcleanup!* :=
  1336. bldmsg("remove %w", plotcmds!*) .
  1337. for each f in plotdta!* collect bldmsg("remove %w", f)
  1338. >>
  1339. else if opsys!* = 'unix then <<
  1340. plotheader!* := "set term x11";
  1341. plotdta!* := for i:=1:10 collect tmpnam();
  1342. plotcmds!*:= tmpnam();
  1343. plotcleanup!* :=
  1344. bldmsg("rm %w", plotcmds!*) .
  1345. for each f in plotdta!* collect bldmsg("rm %w", f) >>
  1346. else if opsys!* = 'finder then <<
  1347. plotcommand!* := "gnuplot";
  1348. plotcmds!*:= "::::gnuplot:reduce.plt";
  1349. plotheader!* := "";
  1350. dirchar!* := ":";
  1351. plotdta!* := for each n in
  1352. {"::::gnuplot:gnutmp.tm1", "::::gnuplot:gnutmp.tm2",
  1353. "::::gnuplot:gnutmp.tm3", "::::gnuplot:gnutmp.tm4",
  1354. "::::gnuplot:gnutmp.tm5", "::::gnuplot:gnutmp.tm6",
  1355. "::::gnuplot:gnutmp.tm7", "::::gnuplot:gnutmp.tm8"}
  1356. collect gtmpnam n;
  1357. plotcleanup!* := nil >>
  1358. else <<
  1359. rederr bldmsg("gnuplot for %w not available yet", opsys!*);
  1360. plotdta!* := for i:=1:10 collect tmpnam();
  1361. plotcmds!*:= tmpnam();
  1362. plotheader!* := "set term dumb" >>;
  1363. if 'pipes member lispsystem!* then !*plotusepipe:=t
  1364. else plotcommand!* := bldmsg("%w %w", plotcommand!*, plotcmds!*);
  1365. if plotdir!* then
  1366. plotcommand!* := bldmsg("%w%w%w",
  1367. plotdir!*, dirchar!*, plotcommand!*);
  1368. nil >>;
  1369. endpatch;
  1370. patch poly;
  1371. % 7 Aug 99.
  1372. symbolic procedure rationalizesq u;
  1373. begin scalar !*structure,!*sub2,v,x;
  1374. if x := get(dmode!*,'rationalizefn) then u := apply1(x,u);
  1375. powlis!* := '(i 2 (nil . t) -1 nil) . powlis!*;
  1376. v := subs2q u;
  1377. powlis!* := cdr powlis!*;
  1378. return if domainp denr v then v
  1379. else if (x := rationalizef denr v) neq 1
  1380. then <<v := multf(numr v,x) ./ multf(denr v,x);
  1381. if null !*algint and null !*rationalize
  1382. then v := gcdchk v;
  1383. subs2q v>>
  1384. else u
  1385. end;
  1386. % 6 Feb 00, 7 Sep 01.
  1387. symbolic procedure sqfrf u;
  1388. begin integer n; scalar !*gcd,units,v,w,x,y,z,!*msg,r;
  1389. !*gcd := t;
  1390. if (r := !*rounded) then
  1391. <<on rational; u := numr resimp !*f2q u>>;
  1392. n := 1;
  1393. x := mvar u;
  1394. v := gcdf(u,diff(u,x));
  1395. u := quotf(u,v);
  1396. if flagp(dmode!*,'field) and ((y := lnc u) neq 1)
  1397. then <<u := multd(!:recip y,u); v := multd(y,v)>>;
  1398. while degr(v,x)>0 do
  1399. <<w := gcdf(v,u);
  1400. if u neq w then z := (quotf(u,w) . n) . z;
  1401. v := quotf(v,w);
  1402. u := w;
  1403. n := n + 1>>;
  1404. if r then
  1405. <<on rounded;
  1406. u := numr resimp !*f2q u;
  1407. z := for each j in z
  1408. collect numr resimp !*f2q car j . cdr j>>;
  1409. if v neq 1 and assoc(v,units) then v := 1;
  1410. if v neq 1 then if n=1 then u := multf(v,u)
  1411. else if (w := rassoc(1,z)) then rplaca(w,multf(v,car w))
  1412. else if null z and ((w := rootxf(v,n)) neq 'failed)
  1413. then u := multf(w,u)
  1414. else if not domainp v then z := aconc(z,v . 1)
  1415. else errach {"sqfrf failure",u,n,z};
  1416. return (u . n) . z
  1417. end;
  1418. % 2 Aug 00.
  1419. symbolic procedure sqfrp u;
  1420. begin scalar !*ezgcd, dmode!*;
  1421. if null getd 'ezgcdf1 then load_package ezgcd;
  1422. !*ezgcd := t;
  1423. return domainp gcdf!*(u,diff(u,mvar u))
  1424. end;
  1425. % 13 Dec 00.
  1426. symbolic procedure gcdk(u,v);
  1427. begin scalar lclst,var,w,x;
  1428. if u=v then return u
  1429. else if domainp u or degr(v,(var := mvar u))=0 then return 1
  1430. else if ldeg u<ldeg v then <<w := u; u := v; v := w>>;
  1431. if quotf1(u,v) then return v
  1432. else if !*heugcd and (x := heu!-gcd(u,v)) then return x
  1433. else if ldeg v=1
  1434. or getd 'modular!-multicheck and modular!-multicheck(u,v,var)
  1435. or not !*mcd
  1436. then return 1;
  1437. a: w := remk(u,v);
  1438. if null w then return v
  1439. else if degr(w,var)=0 then return 1;
  1440. lclst := addlc(v,lclst);
  1441. if x := quotf1(w,lc w) then w := x
  1442. else for each y in lclst do
  1443. if atom y and not flagp(dmode!*,'field)
  1444. or not
  1445. (domainp y and (flagp(dmode!*,'field)
  1446. or ((x := get(car y,'units))
  1447. and y member (for each z in x collect car z))))
  1448. then while (x := quotf1(w,y)) do w := x;
  1449. u := v; v := prim!-part w;
  1450. if degr(v,var)=0 then return 1 else go to a
  1451. end;
  1452. % 19 Jan 01.
  1453. symbolic procedure quarticf pol;
  1454. begin scalar !*sub2,a,a2,a0,b,dsc,p,p1,p2,q,shift,var;
  1455. var := mvar pol;
  1456. p := shift!-pol pol;
  1457. a := coeffs car p;
  1458. shift := caddr p;
  1459. if cadr a then rerror(poly,16,list(pol,"not correctly shifted"))
  1460. else if cadddr a then return list(1,pol);
  1461. a2 := cddr a;
  1462. a0 := caddr a2;
  1463. a2 := car a2;
  1464. a := car a;
  1465. q := quadraticf1(a,a2,a0);
  1466. if not(q eq 'failed)
  1467. then <<a2 := car q; q := cdr q;
  1468. a := exptsq(addsq(!*k2q mvar pol,shift),2);
  1469. b := numr subs2q quotsq(addsq(multsq(!*f2q car q,a),
  1470. !*f2q cadr q),
  1471. !*f2q cadr p);
  1472. a := numr subs2q quotsq(addsq(multsq(!*f2q caddr q,a),
  1473. !*f2q cadddr q),
  1474. !*f2q cadr p);
  1475. a := quadraticf!*(a,var);
  1476. b := quadraticf!*(b,var);
  1477. return multf(a2,multf(car a,car b))
  1478. . nconc!*(cdr a,cdr b)>>
  1479. else if null !*surds or denr shift neq 1
  1480. then return list(1,pol);
  1481. shift := numr shift;
  1482. if knowndiscrimsign eq 'negative then go to complex;
  1483. dsc := powsubsf addf(exptf(a2,2),multd(-4,multf(a,a0)));
  1484. p2 := minusf a0;
  1485. if not p2 and minusf dsc then go to complex;
  1486. p1 := not a2 or minusf a2;
  1487. if not p1 then if p2 then p1 := t else p2 := t;
  1488. p1 := if p1 then 'positive else 'negative;
  1489. p2 := if p2 then 'negative else 'positive;
  1490. a := rootxf(a,2);
  1491. if a eq 'failed then return list(1,pol);
  1492. dsc := rootxf(dsc,2);
  1493. if dsc eq 'failed then return list(1,pol);
  1494. p := invsq !*f2q addf(a,a);
  1495. q := multsq(!*f2q addf(a2,negf dsc),p);
  1496. p := multsq(!*f2q addf(a2,dsc),p);
  1497. b := multf(a,exptf(addf(!*k2f mvar pol,shift),2));
  1498. a := powsubsf addf(b,q);
  1499. b := powsubsf addf(b,p);
  1500. knowndiscrimsign := p1;
  1501. a := quadraticf!*(a,var);
  1502. knowndiscrimsign := p2;
  1503. b := quadraticf!*(b,var);
  1504. knowndiscrimsign := nil;
  1505. return multf(car a,car b) . nconc!*(cdr a,cdr b);
  1506. complex:
  1507. a := rootxf(a,2);
  1508. if a eq 'failed then return list(1,pol);
  1509. a0 := rootxf(a0,2);
  1510. if a0 eq 'failed then return list(1,pol);
  1511. a2 := powsubsf addf(multf(2,multf(a,a0)),negf a2);
  1512. a2 := rootxf(a2,2);
  1513. if a2 eq 'failed then return list(1,pol);
  1514. p := addf(!*k2f mvar pol,shift);
  1515. q := addf(multf(a,exptf(p,2)),a0);
  1516. p := multf(a2,p);
  1517. a := powsubsf addf(q,p);
  1518. b := powsubsf addf(q,negf p);
  1519. knowndiscrimsign := 'negative;
  1520. a := quadraticf!*(a,var);
  1521. b := quadraticf!*(b,var);
  1522. knowndiscrimsign := nil;
  1523. return multf(car a,car b) . nconc!*(cdr a,cdr b)
  1524. end;
  1525. % 7 Apr 01.
  1526. symbolic procedure factorize u;
  1527. (begin scalar x,y;
  1528. x := simp!* u;
  1529. y := denr x;
  1530. if not domainp y then typerr(u,"polynomial");
  1531. u := numr x;
  1532. if u = 1 then return
  1533. {'list, if !*nopowers then 1 else {'list,1,1}}
  1534. else if fixp u then !*ifactor := t;
  1535. if !*force!-prime and not primep !*force!-prime
  1536. then typerr(!*force!-prime,"prime");
  1537. u := if dmode!* and not(dmode!* memq '(!:rd!: !:cr!:))
  1538. then if get(dmode!*,'factorfn)
  1539. then begin scalar !*factor;
  1540. !*factor := t;
  1541. return fctrf u
  1542. end
  1543. else rerror(poly,14,
  1544. list("Factorization not supported over domain",
  1545. get(dmode!*,'dname)))
  1546. else fctrf u;
  1547. return facform2list(u,y)
  1548. end) where !*ifactor = !*ifactor;
  1549. % 7 Apr 01, 24 Aug 01.
  1550. symbolic procedure factor!-prim!-sqfree!-f u;
  1551. begin scalar x,y,!*msg,r;
  1552. r := !*rounded;
  1553. if r and univariatep numr u and lc numr u=1 and denr u=1
  1554. then return unifactor u
  1555. else if r or !*complex or !*rational then
  1556. <<if r then on rational;
  1557. u := numr resimp !*f2q car u . cdr u>>;
  1558. if null !*limitedfactors
  1559. then <<if null dmode!* then y := 'factorf
  1560. else <<x := get(dmode!*,'sqfrfactorfn);
  1561. y := get(dmode!*,'factorfn);
  1562. if x and not(x eq y) then y := 'factorf>>;
  1563. if y
  1564. then <<y := apply1(y,car u);
  1565. u := (exptf(car y,cdr u) . for each j in cdr y
  1566. collect(car j . cdr u));
  1567. go to ret>>>>;
  1568. u := factor!-prim!-sqfree!-f!-1(car u,cdr u);
  1569. ret: if r then
  1570. <<on rounded;
  1571. u := car u . for each j in cdr u collect
  1572. (numr resimp !*f2q car j . cdr j)>>;
  1573. return u
  1574. end;
  1575. % 7 Apr 01.
  1576. symbolic procedure unifactor u;
  1577. if not eqcar(u := root_val list mk!*sq u,'list)
  1578. then errach {"unifactor1",u}
  1579. else 1 . for each j in cdr u collect
  1580. if not eqcar(j,'equal) then errach{"unifactor2",u}
  1581. else addsq(!*k2q cadr j,negsq simp caddr j);
  1582. % 11 Jun 01.
  1583. symbolic procedure noncomp u;
  1584. !*ncmp and noncomp1 u;
  1585. symbolic procedure noncomp1 u;
  1586. if null pairp u then nil
  1587. else if pairp car u then noncomfp u
  1588. else flagp(car u,'noncom) or noncomlistp cdr u;
  1589. symbolic procedure noncomlistp u;
  1590. pairp u and (noncomp1 car u or noncomlistp cdr u);
  1591. % 30 Nov 01.
  1592. symbolic procedure exptf(u,n);
  1593. if n<0 then errach {"exptf",u,n}
  1594. else if domainp u then !:expt(u,n)
  1595. else if !*exp or kernlp u then exptf1(u,n)
  1596. else mksfpf(u,n);
  1597. endpatch;
  1598. % Rlisp declarations.
  1599. fluid '(newrules!*);
  1600. patch rlisp;
  1601. % 9 Nov 99.
  1602. symbolic procedure load!-package u;
  1603. begin scalar x,y;
  1604. if stringp u then return load!-package intern compress explode2 u
  1605. else if null idp u then rederr list(u,"is not a package name")
  1606. else if memq(u,loaded!-packages!*)
  1607. then return u
  1608. else if or(atom(x:= errorset(list('evload,list('quote,list u)),
  1609. nil,!*backtrace)),
  1610. cdr x)
  1611. then rederr
  1612. list("error in loading package",u,"or package not found");
  1613. loaded!-packages!* := u . loaded!-packages!*;
  1614. x := get(u,'package);
  1615. if x then x := cdr x;
  1616. a: if null x then go to b
  1617. else if null atom get(car x,'package) then load!-package car x
  1618. else if or(atom(y := errorset(list('evload,
  1619. list('quote,list car x)),
  1620. nil,!*backtrace)),
  1621. cdr y)
  1622. then rederr list("module",car x,"of package",u,
  1623. "cannot be loaded");
  1624. x := cdr x;
  1625. go to a;
  1626. b: if (x := get(u,'patchfn))
  1627. then begin scalar !*usermode,!*redefmsg; eval list x end
  1628. end;
  1629. % 22 April 00.
  1630. symbolic procedure begin11 x;
  1631. begin scalar mode,result,newrule!*;
  1632. if cursym!* eq 'end
  1633. then if terminalp() and null !*lisp!_hook
  1634. then progn(cursym!* := '!*semicol!*, !*nosave!* := t,
  1635. return nil)
  1636. else progn(comm1 'end, return 'end)
  1637. else if eqcar((if !*reduce4 then x else cadr x),'retry)
  1638. then if programl!* then x := programl!*
  1639. else progn(lprim "No previous expression",return nil);
  1640. if null !*reduce4 then progn(mode := car x,x := cadr x);
  1641. program!* := x;
  1642. if eofcheck() then return 'c else eof!* := 0;
  1643. add2inputbuf(x,if !*reduce4 then nil else mode);
  1644. if null atom x
  1645. and car x memq '(bye quit)
  1646. then if getd 'bye
  1647. then progn(lispeval x, !*nosave!* := t, return nil)
  1648. else progn(!*byeflag!* := t, return nil)
  1649. else if null !*reduce4 and eqcar(x,'ed)
  1650. then progn((if getd 'cedit and terminalp()
  1651. then cedit cdr x
  1652. else lprim "ED not supported"),
  1653. !*nosave!* := t, return nil)
  1654. else if !*defn
  1655. then if erfg!* then return nil
  1656. else if null flagp(key!*,'ignore)
  1657. and null eqcar(x,'quote)
  1658. then progn((if x then dfprint x else nil),
  1659. if null flagp(key!*,'eval) then return nil);
  1660. if !*output and ifl!* and !*echo and null !*lessspace
  1661. then terpri();
  1662. result := errorset!*(x,t);
  1663. if errorp result or erfg!*
  1664. then progn(programl!* := list(mode,x),return 'err2)
  1665. else if !*defn then return nil;
  1666. if null !*reduce4
  1667. then if null(mode eq 'symbolic) then x := getsetvars x else nil
  1668. else progn(result := car result,
  1669. (if null result then result := mkobject(nil,'noval)),
  1670. mode := type result,
  1671. result := value result);
  1672. add2resultbuf((if null !*reduce4 then car result else result),
  1673. mode);
  1674. if null !*output then return nil
  1675. else if null(semic!* eq '!$)
  1676. then if !*reduce4 then (begin
  1677. terpri();
  1678. if mode eq 'noval then return nil
  1679. else if !*debug then prin2t "Value:";
  1680. rapply1('print,list list(mode,result))
  1681. end)
  1682. else if mode eq 'symbolic
  1683. then if null car result and null(!*mode eq 'symbolic)
  1684. then nil
  1685. else begin
  1686. terpri();
  1687. result:=
  1688. errorset!*(list('print,mkquote car result),t)
  1689. end
  1690. else if car result
  1691. then result := errorset!*(list('assgnpri,mkquote car result,
  1692. (if x then 'list . x else nil),
  1693. mkquote 'only),
  1694. t);
  1695. if null !*reduce4
  1696. then return if errorp result then 'err3 else nil
  1697. else if null(!*mode eq 'noval)
  1698. then progn(terpri(), prin2 "of type: ", print mode);
  1699. return nil
  1700. end;
  1701. endpatch;
  1702. % Roots declarations.
  1703. % fluid '(rootacc!#!# rootacc!#!# !*noeqns);
  1704. % patch roots;
  1705. % 10 Feb 00.
  1706. % Commented out since now solved another way (7 Apr 01).
  1707. % symbolic procedure root_val x;
  1708. % roots x
  1709. % where rootacc!#!#=p, iniprec!#=p where p=precision 0, !*msg=nil,
  1710. % !*noeqns=t;
  1711. % endpatch;
  1712. % Scope declarations.
  1713. global '(kvarlst prevlst varlst!*);
  1714. patch scope;
  1715. % 29 Aug 00.
  1716. symbolic procedure maxtype type;
  1717. if atom type then type
  1718. else if pairp cdr type then cadr type else car type;
  1719. % 8 Nov 00.
  1720. symbolic procedure prepmultmat(preprefixlist);
  1721. begin scalar tlcm,var,varexp,kvl,kfound,pvl,pfound,tel,ratval,ratlst,
  1722. newvarlst,hvarlst;
  1723. hvarlst:= nil;
  1724. while not null (varlst!*) do
  1725. <<var := car varlst!*; varlst!* := cdr varlst!*;
  1726. if flagp(var,'ratexp)
  1727. then
  1728. <<tlcm:=1;
  1729. remflag(list var,'ratexp);
  1730. foreach elem in get(var,'varlst!*) do
  1731. if pairp cdr elem then tlcm := lcm2(tlcm,cddr elem);
  1732. varexp:=fnewsym();
  1733. tel:=(varexp.(if tlcm = 2
  1734. then list('sqrt,var)
  1735. else list('expt,var,
  1736. if onep cdr(tel:=simpquot list(1,tlcm)) then
  1737. car tel
  1738. else
  1739. list('quotient,car tel,cdr tel))));
  1740. if assoc(var,kvarlst)
  1741. then
  1742. <<kvl:=kfound:=nil;
  1743. while kvarlst and not(kfound) do
  1744. if caar(kvarlst) eq var
  1745. then
  1746. << kvl:=tel.kvl; kfound:=t;
  1747. pvl:=pfound:=nil; prevlst:=reverse(prevlst);
  1748. while prevlst and not(pfound) do
  1749. if cdar(prevlst) eq var
  1750. then << pvl:=cons(caar prevlst,varexp).pvl;
  1751. pfound:=t
  1752. >>
  1753. else << pvl:=car(prevlst).pvl;
  1754. prevlst:=cdr(prevlst)
  1755. >>;
  1756. if pvl then
  1757. if prevlst then prevlst:=append(reverse prevlst,pvl)
  1758. else prevlst:=pvl
  1759. >>
  1760. else
  1761. << kvl:=car(kvarlst).kvl; kvarlst:=cdr kvarlst>>;
  1762. if kvl then
  1763. if kvarlst then kvarlst:=append(reverse kvl,kvarlst)
  1764. else kvarlst:=reverse kvl
  1765. >>
  1766. else preprefixlist:=tel.preprefixlist;
  1767. ratlst:=newvarlst:=nil;
  1768. foreach elem in get(var,'varlst!*) do
  1769. if pairp cdr elem
  1770. then
  1771. << ratval:=divide((tlcm * cadr elem)/(cddr elem),tlcm);
  1772. ratlst:=cons(car elem,cdr ratval).ratlst;
  1773. if car(ratval)>0
  1774. then newvarlst:=cons(car elem,car ratval).newvarlst
  1775. >>
  1776. else newvarlst:=elem.newvarlst;
  1777. if ratlst
  1778. then << put(varexp,'varlst!*,reverse ratlst);
  1779. hvarlst:=varexp.hvarlst
  1780. >>;
  1781. if newvarlst
  1782. then << put(var,'varlst!*,reverse newvarlst);
  1783. hvarlst:=var.hvarlst
  1784. >>
  1785. else remprop(var,'varlst!*)
  1786. >>
  1787. else hvarlst:=var.hvarlst
  1788. >>;
  1789. varlst!* := hvarlst;
  1790. return preprefixlist
  1791. end;
  1792. endpatch;
  1793. % Solve declarations.
  1794. fluid '(!*multiplicities vars!*);
  1795. global '(multiplicities!*);
  1796. patch solve;
  1797. % 9 Jan 01.
  1798. symbolic procedure !*solvelist2solveeqlist u;
  1799. begin scalar x,y,z;
  1800. u := for each j in u collect solveorder j;
  1801. for each j in u do
  1802. <<if caddr j=0 then rerror(solve,2,"zero multiplicity")
  1803. else if null cadr j
  1804. then x := for each k in car j collect
  1805. list('equal,!*q2a k,0)
  1806. else x := for each k in pair(cadr j,car j)
  1807. collect list('equal,car k,!*q2a cdr k);
  1808. if length vars!* > 1 then x := 'list . x else x := car x;
  1809. z := (caddr j . x) . z>>;
  1810. z := sort(z,function ordp);
  1811. x := nil;
  1812. if !*multiplicities
  1813. then <<for each k in z do for i := 1:car k do x := cdr k . x;
  1814. multiplicities!* := nil>>
  1815. else <<for each k in z do << x := cdr k . x; y := car k . y>>;
  1816. multiplicities!* := 'list . reversip y>>;
  1817. return 'list . reversip x
  1818. end;
  1819. % 9 Jan 01, 15 Jun 01.
  1820. symbolic procedure solveorder u;
  1821. begin scalar v,w,x,y,z;
  1822. v := vars!*;
  1823. x := cadr u;
  1824. if length x<length v then v := setdiff(v,setdiff(v,x));
  1825. if null x or x=v then return u;
  1826. y := car u;
  1827. while x do <<z := (car x . car y) . z; x := cdr x; y := cdr y>>;
  1828. w := v;
  1829. a: if null w then return reversip x . v . cddr u
  1830. else if null(y := depassoc(car w,z)) then return u
  1831. else x := cdr y . x;
  1832. w := cdr w;
  1833. go to a
  1834. end;
  1835. symbolic procedure depassoc(u,v);
  1836. if null v then nil
  1837. else if u = caar v then car v
  1838. else if depends(caar v,u) then nil
  1839. else depassoc(u,cdr v);
  1840. % 2 Feb 01.
  1841. symbolic procedure check!-solns(z,ex,var);
  1842. begin scalar x;
  1843. if errorp (x :=
  1844. errorset2 {'check!-solns1,mkquote z,mkquote ex,mkquote var})
  1845. then return
  1846. check!-solns1(z,(numr simp!* prepf ex where !*reduced=t),var)
  1847. else return car x
  1848. end;
  1849. symbolic procedure check!-solns1(z,ex,var);
  1850. begin scalar x,y,fv,sx,vs;
  1851. fv := freevarl(ex,var);
  1852. for each z1 in z do
  1853. fv := union(fv,union(freevarl(numr caar z1,var),
  1854. freevarl(denr caar z1,var)));
  1855. fv := delete('i,fv);
  1856. if fv then for each v in fv do
  1857. if not flagp(v,'constant) then
  1858. vs := (v . list('quotient,1+random 999,1000)) . vs;
  1859. sx := if vs then numr subf(ex,vs) else ex;
  1860. while z do
  1861. if null cadar z then <<z := nil; x := 'unsolved>>
  1862. else if
  1863. <<y := numr subf(ex,list(caadar z . mk!*sq caaar z));
  1864. null y
  1865. or fv and null(y := numr subf(sx,list(caadar z .
  1866. mk!*sq subsq(caaar z,vs))))
  1867. or null numvalue y>>
  1868. then <<x := car z . x; z := cdr z>>
  1869. else z := cdr z;
  1870. return if null x then 'unsolved else x
  1871. end;
  1872. % 7 Apr 01.
  1873. symbolic procedure solvequadratic(a2,a1,a0);
  1874. if !*rounded and numcoef a0 and numcoef a1 and numcoef a2
  1875. then for each z in cdr root_val list mkpolyexp2(a2,a1,a0)
  1876. collect simp!* (if eqcar(z,'equal) then caddr z
  1877. else errach {"Quadratic confusion",z})
  1878. else begin scalar d;
  1879. d := sqrtq subtrsq(quotsqf(exptsq(a1,2),4),multsq(a2,a0));
  1880. a1 := quotsqf(negsq a1,2);
  1881. return list(subs2!* quotsq(addsq(a1,d),a2),
  1882. subs2!* quotsq(subtrsq(a1,d),a2))
  1883. end;
  1884. endpatch;
  1885. % Sum declarations.
  1886. fluid '(sum_last_attempt_rules!* !*zeilberg);
  1887. patch sum;
  1888. % 28 Jul 00.
  1889. symbolic procedure freeof!-df(u, v);
  1890. if atom u then t
  1891. else if car(u) eq 'df
  1892. then freeof!-df(cadr u, v) and not smember(v,cddr u)
  1893. else freeof!-dfl(cdr u, v);
  1894. symbolic procedure freeof!-dfl(u, v);
  1895. if null u then t else freeof!-df(car u,v) and freeof!-dfl(cdr u,v);
  1896. symbolic procedure simp!-sum u;
  1897. begin scalar y;
  1898. y := cdr u;
  1899. u := car u;
  1900. if not atom y and not freeof!-df(u, car y) then
  1901. if atom y
  1902. then return !*p2f(car fkern(list('sum,u)) .* 1) ./ 1
  1903. else return sum!-df(u, y);
  1904. u := simp!* u;
  1905. return if null numr u then u
  1906. else if atom y
  1907. then !*p2f(car fkern(list('sum,prepsq u)) .* 1) ./ 1
  1908. else if !*zeilberg then gosper!*(mk!*sq u,y)
  1909. else simp!-sum0(u,y)
  1910. end;
  1911. symbolic procedure sum!-subst(u,x,a);
  1912. if u = x then a
  1913. else if atom u then u
  1914. else sum!-subst(car u, x,a) . sum!-subst(cdr u,x,a);
  1915. symbolic procedure sum!-df(u,y);
  1916. begin scalar w,z,upper,lower,dif;
  1917. if length(y) = 3 then <<
  1918. lower := cadr y;
  1919. upper := caddr y;
  1920. dif := addsq(simp!* upper, negsq simp!* lower);
  1921. if denr dif = 1 then
  1922. if null numr dif
  1923. then return simp!* sum!-subst(u, car y, upper)
  1924. else if fixp numr dif then dif := numr dif
  1925. else dif := nil
  1926. else dif := nil;
  1927. if dif and dif <= 0 then return nil ./ 1 >>;
  1928. if null dif then <<
  1929. z := 'sum . (u . y);
  1930. let sum_last_attempt_rules!*;
  1931. w:= opmtch z;
  1932. rule!-list (list sum_last_attempt_rules!*,nil);
  1933. return if w then simp w else mksq(z,1)>>;
  1934. z := nil ./ 1;
  1935. a: if dif < 0 then return z;
  1936. z := addsq(z,simp!* sum!-subst(u, car y, list('plus,lower,dif)));
  1937. dif := dif - 1;
  1938. go to a
  1939. end;
  1940. % 20 Nov 00.
  1941. symbolic procedure termlst(u,v,klst);
  1942. begin scalar x,kern,lst;
  1943. if null u then return nil
  1944. else if null klst or domainp u
  1945. then return list multsq(v,!*f2q u);
  1946. kern := car klst;
  1947. klst := cdr klst;
  1948. x := setkorder list kern;
  1949. u := reorder u;
  1950. v := reorder(numr v) ./ reorder(denr v);
  1951. while not domainp u and mvar u eq kern do <<
  1952. lst := nconc(termlst(lc u, multsq(!*p2q lpow u, v),klst),lst);
  1953. u := red u>>;
  1954. if u then lst := nconc(termlst(u,v,klst),lst);
  1955. setkorder x;
  1956. return lst
  1957. end;
  1958. endpatch;
  1959. % Taylor declarations.
  1960. fluid '(!*taylorautocombine);
  1961. patch taylor;
  1962. % 1 Jun 01.
  1963. symbolic procedure simptaylor u;
  1964. if remainder(length u,3) neq 1
  1965. then Taylor!-error('wrong!-no!-args,'taylor)
  1966. else if null subfg!* then mksq('taylor . u,1)
  1967. else begin scalar !*precise,arglist,degree,f,ll,result,var,var0;
  1968. if !*taylorautocombine and not ('taysimpsq memq mul!*)
  1969. then mul!* := aconc!*(mul!*,'taysimpsq);
  1970. f := simp!* car u;
  1971. u := revlis cdr u;
  1972. arglist := u;
  1973. while not null arglist do
  1974. << var := car arglist;
  1975. var := if eqcar(var,'list) then cdr var else {var};
  1976. for each el in var collect begin
  1977. el := simp!* el;
  1978. if kernp el then return mvar numr el
  1979. else typerr(prepsq el,'kernel)
  1980. end;
  1981. var0 := cadr arglist;
  1982. degree := caddr arglist;
  1983. if not fixp degree
  1984. then typerr(degree,"order of Taylor expansion");
  1985. arglist := cdddr arglist;
  1986. ll := {var,var0,degree,degree + 1} . ll>>;
  1987. result := taylorexpand(f,reversip ll);
  1988. return if smember('Taylor!*,result) then result
  1989. else mksq('taylor . prepsq f . u,1)
  1990. end;
  1991. endpatch;
  1992. endmodule;
  1993. end;