patches.red 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029
  1. module patches; % Patches to correct problems in REDUCE 3.8.
  2. % Author: Anthony C. Hearn.
  3. % Copyright (c) 2004, 2005, 2006, 2007 Anthony C. Hearn. All Rights Reserved.
  4. global '(patch!-date!* patch!-url!-list!*);
  5. patch!-date!* := "11-Jan-2007";
  6. patch!-url!-list!* :=
  7. '("http://reduce-algebra.com/support/patches/patches.fsl");
  8. % Bugs fixed by these patches.
  9. % 26 Jun 04. With rounded arithmetic, solving some linear equation
  10. % problems could lead to a catastrophic error.
  11. % 8 Jul 04. Some non-zero integrals (e.g., int(e^(a^(1/3)*x)*sin x,x))
  12. % returned zero.
  13. % 5 Aug 04. Using RLFI with latex on could lead to invalid operator errors.
  14. % 2 Sep 04. In rare circumstances, floating point conversion could give
  15. % an extraneous error.
  16. % 6 Sep 04. With rational on, some non-zero factorizations could produce
  17. % a zero coefficient (e.g., on rational;
  18. % factorize(r^((1/4*n^2 - 1/4*n + 1)/(n - 1)));).
  19. % 28 Sep 04. Some integrals would not return a closed form solution
  20. % with algint on that would with algint off
  21. % (e.g., int(sqrt(x-1)/(sqrt x*(x-1)),x)).
  22. % 10 Dec 04. With dfprin on, some products and sums printed incorrectly.
  23. % 31 Jan 05. Some integrals involving square roots could run forever.
  24. % 12 Feb 05. SOLVE could produce a spurious recursive loop (e.g.,
  25. % solve((4*e^(y^3/3)*cte+2x^2+y^3+3)/e^(y^3/3),y)).
  26. % 20 Apr 05. int(e^(-a^(1/4)*(-1)^(1/4)*x),x); terminated with an error.
  27. % 2 May 05. int(e^(-a^(1/4)*(-1)^(1/4)*i*x)*b+(1/4)*e^(-a^(1/4)
  28. % *(-1)^(1/4)*i*x)*x,x); terminated with an error.
  29. % 22 May 05. Some integrals, e.g., int(e^((3sqrt 5+1)*x)*(sqrt 5+1)
  30. % +e^((3sqrt 5-1)*x)*(sqrt 5+1),x), never completed.
  31. % 30 May 05. SOLVE could produce a spurious "Zero divisor" error
  32. % (e.g., solve({log tan(y/2),y+1/x},{x,y})).
  33. % 4 Oct 05. DEG did not work with rational coefficients (e.g.,
  34. % deg(x**3/a-x/5+1/4,x)).
  35. % 5 Oct 05. Some SOLVE calculations could give a spurious "Zero Divisor"
  36. % error (e.g., ex0:= sqrt(a^2-y^2); solve((-log(( - x + a + y)
  37. % /ex0) + log((x + a + y)/ex0) + x - (a^2 - y^2)/ex0),y);
  38. % 16 Nov 05. System errors could occur with rounded and combineexpt on.
  39. % (E.g., on rounded,combineexpt; 0.183*e^x*t^4.39;).
  40. % 22 Nov 05. Some definite integrals with variables other than x could
  41. % give a wrong answer, e.g., int(e^(-y),y,0,x).
  42. % 9 Dec 05. With combineexpt on, expressions could be dropped (e.g.,
  43. % on combineexpt; 4*e^(-3*h/2) - 3*h*e^(-h) + 2*e^(-h)).
  44. % 4 Feb 06. Setcrackflags() was not set in crack, but needed to be.
  45. % 20 Feb 06. The rule for df(Jacobidn(~u,~m),~u) was wrong.
  46. % 21 Feb 06. Evaluating some integrals could suppress the printing of
  47. % the results.
  48. % 22 Feb 06. Some sub evaluations could include superfluous terms like
  49. % x = (x^(1/7))^7.
  50. % 23 May 06. Derivatives and integrals of matrices were not computed.
  51. % 18 Aug 06. After nospur, some traces were still evaluated.
  52. % 29 Sep 06. With dfprint on, derivatives of integrals would print in a
  53. % truncated form.
  54. % 11 Jan 07. With rounded arithmetic and factor on, a non-numeric
  55. % argument error could occur.
  56. % Alg declarations.
  57. fluid '(sublist!*);
  58. patch alg;
  59. % 16 Nov 05, 9 Dec 05.
  60. symbolic procedure exptunwind(u,v);
  61. begin scalar x,x1,x2,y,z,z2;
  62. a: if null v then return u;
  63. x := caar v;
  64. x1 := cadr x;
  65. x2 := caddr x;
  66. y := cdar v;
  67. v := cdr v;
  68. if !*combineexpt and null domainp u and null red u
  69. and (z2 := kernels u) and null cdr z2
  70. then u := {(({'expt,car z2,ldeg u} . 1) . lc u)};
  71. while (z := assocp1(x1,v)) and
  72. (z2 := simp {'plus,{'times,x2,y},{'times,caddar z,cdr z}})
  73. and (!*combineexpt or (fixp numr z2 and fixp denr z2))
  74. do <<if fixp numr z2 and fixp denr z2
  75. then <<x2 := divide(numr z2,denr z2);
  76. if car x2>0
  77. then <<if fixp x1 then u := multf(x1**car x2,u)
  78. else u := multpf(mksp(x1,car x2),u);
  79. z2 := cdr x2 ./ denr z2>>;
  80. y := numr z2>>
  81. else if domainp numr z2 then y := 1
  82. else <<y := lcoeffgcd cdr comfac numr z2;
  83. if not fixp y then y := 1>>;
  84. x2 := prepsq(quotf(numr z2,y) ./ denr z2);
  85. v := delete(z,v)>>;
  86. if !*combineexpt and y=1 and fixp x1 then
  87. <<while (z := assocp2(x2,v)) and cdr z=1 and fixp cadar z do
  88. <<x1 := cadar z * x1; v := delete(z,v)>>;
  89. if eqcar(x2,'quotient) and fixp cadr x2 and fixp caddr x2
  90. and cadr x2<caddr x2
  91. then <<z := nrootn(x1**cadr x2,caddr x2);
  92. if cdr z = 1 then u := multd(car z,u)
  93. else if car z = 1
  94. then u := multf(formsf(x1,x2,1),u)
  95. else <<u := multd(car z,u);
  96. v := (list('expt,cdr z,x2) . 1) . v>>>>
  97. else u := multf(formsf(x1,x2,y),u)>>
  98. else u := multf(formsf(x1,x2,y),u);
  99. go to a
  100. end;
  101. % 22 Feb 06.
  102. symbolic procedure subeval0 u;
  103. begin scalar x,y,z,ns;
  104. while cdr u do <<if not eqcar(car u,'equal) then x := car u . x
  105. else if not(cadar u = (y := reval caddar u))
  106. then x := {caar u,cadar u,y} . x;
  107. u := cdr u>>;
  108. if null x then return car u else u := nconc(reversip x,u);
  109. if u member sublist!* then return mk!*sq !*p2q mksp('sub . u,1)
  110. else sublist!* := u . sublist!*;
  111. if null(u and cdr u)
  112. then rederr "SUB requires at least 2 arguments";
  113. (while cdr u do
  114. <<x := reval car u;
  115. if getrtype x eq 'list then u := append(cdr x,cdr u)
  116. else <<if not eqexpr x then errpri2(car u,t);
  117. y := cadr x;
  118. if null getrtype y then y := !*a2kwoweight y;
  119. if getrtype caddr x then ns := (y . caddr x) . ns
  120. else z := (y . caddr x) . z;
  121. u := cdr u>>>>) where !*evallhseqp=nil;
  122. x := aeval car u;
  123. return subeval1(append(ns,z),x)
  124. end;
  125. symbolic procedure subsubf(l,expn);
  126. begin scalar x,y;
  127. for each j in l do if car j neq (y := prepsq!* simp!* cdr j)
  128. then x := (car j . y) . x;
  129. l := reversip x;
  130. if null l then return expn;
  131. y := nil;
  132. for each j in cddr expn do
  133. if (x := assoc(j,l)) then <<y := x . y; l := delete(x,l)>>;
  134. expn := sublis(l,car expn)
  135. . for each j in cdr expn collect subsublis(l,j);
  136. if null y then return expn;
  137. expn := aconc!*(for each j in reversip!* y
  138. collect list('equal,car j,aeval cdr j),expn);
  139. return if l then subeval expn
  140. else mk!*sq !*p2q mksp('sub . expn,1)
  141. end;
  142. % 23 May 06.
  143. symbolic procedure reval1(u,v);
  144. (begin scalar x,y;
  145. if null u then return nil
  146. else if stringp u then return u
  147. else if fixp u
  148. then return if flagp(dmode!*,'convert) then reval2(u,v) else u
  149. else if atom u
  150. then if null subfg!* then return u
  151. else if idp u and (x := get(u,'avalue))
  152. then if u memq varstack!* then recursiveerror u
  153. else <<varstack!* := u . varstack!*;
  154. return if y := get(car x,'evfn)
  155. then apply2(y,u,v)
  156. else reval1(cadr x,v)>>
  157. else nil
  158. else if not idp car u
  159. then errpri2(u,t)
  160. else if car u eq '!*sq
  161. then return if caddr u and null !*resimp
  162. then if null v then u else prepsqxx cadr u
  163. else reval2(u,v)
  164. else if flagp(car u,'remember) then return rmmbreval(u,v)
  165. else if flagp(car u,'opfn) then return reval1(opfneval u,v)
  166. else if x := get(car u,'psopfn)
  167. then <<u := apply1(x,cdr u);
  168. if x := get(x,'cleanupfn) then u := apply2(x,u,v);
  169. return u>>
  170. else if arrayp car u then return reval1(getelv u,v);
  171. return if x := getrtype u then
  172. if y := get(x,'evfn) then apply2(y,u,v)
  173. else rerror(alg,101,
  174. list("Missing evaluation for type",x))
  175. else if not atom u
  176. and not atom cdr u
  177. and (y := getrtype cadr u)
  178. and null(y eq 'list and cddr u)
  179. and (x := get(y,'aggregatefn))
  180. and (not(x eq 'matrixmap) or flagp(car u,'matmapfn))
  181. and not flagp(car u,'boolean)
  182. and not !*listargs and not flagp(car u,'listargp)
  183. then apply2(x,u,v)
  184. else reval2(u,v)
  185. end) where varstack!* := varstack!*;
  186. symbolic procedure getrtype2 u;
  187. begin scalar x;
  188. return if (x := get(car u,'rtype)) and (x := get(x,'rtypefn))
  189. then apply1(x,cdr u)
  190. else if x := get(car u,'rtypefn) then apply1(x,cdr u)
  191. else if flagp(car u,'matmapfn) and cdr u
  192. and getrtype cadr u eq 'matrix
  193. then 'matrix
  194. else nil
  195. end;
  196. endpatch;
  197. patch arith;
  198. % 2 Sep 04.
  199. symbolic procedure read!:num(n);
  200. if fixp n then make!:ibf(n, 0)
  201. else if not(numberp n or stringp n) then bflerrmsg 'read!:num
  202. else begin integer j,m,sign; scalar ch,u,v,l,appear!.,appear!/;
  203. j := m := 0;
  204. sign := 1;
  205. u := v := appear!. := appear!/ := nil;
  206. l := explode n;
  207. loop: ch := car l;
  208. if digit ch then << u := ch . u; j := j + 1 >>
  209. else if ch eq '!. then << appear!. := t; j := 0 >>
  210. else if ch eq '!/ then << appear!/ := t; v := u; u := nil >>
  211. else if ch eq '!- then sign := -1
  212. else if ch memq '(!E !D !B !e !d !b) then go to jump;
  213. if l := cdr l then goto loop else goto make;
  214. jump: while l := cdr l do
  215. <<if digit(ch := car l) or ch eq '!-
  216. then v := ch . v >>;
  217. l := reverse v;
  218. if car l eq '!- then m := - compress cdr l
  219. else m:= compress l;
  220. make: u := reverse u;
  221. v := reverse v;
  222. if appear!/ then
  223. return conv!:r2bf(make!:ratnum(sign*compress v,compress u),
  224. if !:bprec!: then !:bprec!: else 170);
  225. if appear!. then j := - j else j := 0;
  226. if sign = 1 then u := compress u else u := - compress u;
  227. return round!:mt (decimal2internal (u, j + m), !:bprec!:)
  228. where !:bprec!: := if !:bprec!: then !:bprec!:
  229. else msd!: abs u
  230. end;
  231. endpatch;
  232. patch crack;
  233. setcrackflags();
  234. endpatch;
  235. % Defint declarations.
  236. symbolic smacro procedure listsq(u);
  237. for each uu in u collect simp!* uu;
  238. patch defint;
  239. symbolic procedure new_meijer(u);
  240. begin scalar f,y,mellin,new_mellin,m,n,p,q,old_num,old_denom,temp,a1,
  241. b1,a2,b2,alpha,num,denom,n1,temp1,temp2,coeff,v,var,new_var,new_y,
  242. new_v,k;
  243. f := prepsq simp car u;
  244. y := caddr u;
  245. mellin := bastab(car f,cddr f);
  246. temp := car cddddr mellin;
  247. var := cadr f;
  248. if not idp VAR then RETURN error(99,'FAIL);
  249. temp := reval algebraic(sub(x=var,temp));
  250. mellin := {car mellin,cadr mellin,caddr mellin,cadddr mellin,temp};
  251. temp := reduce_var(cadr u,mellin,var);
  252. alpha := simp!* car temp;
  253. new_mellin := cdr temp;
  254. if car cddddr new_mellin neq car cddddr mellin then
  255. << k := car cddddr mellin;
  256. y := reval algebraic(sub(var=y,k));
  257. new_y := simp y>>
  258. else
  259. << new_var := car cddddr new_mellin;
  260. new_y := simp reval algebraic(sub(x=y,new_var))>>;
  261. n1 := addsq(alpha,'(1 . 1));
  262. temp1 := {'expt,y,prepsq n1};
  263. temp2 := cadddr new_mellin;
  264. coeff := simp!* reval algebraic(temp1*temp2);
  265. m := caar new_mellin;
  266. n := cadar new_mellin;
  267. p := caddar new_mellin;
  268. q := car cdddar new_mellin;
  269. old_num := cadr new_mellin;
  270. old_denom := caddr new_mellin;
  271. for i:=1 :n do
  272. << if old_num = nil then a1 := append(a1,{simp!* old_num })
  273. else << a1 := append(a1,{simp!* car old_num});
  274. old_num := cdr old_num>>;
  275. >>;
  276. for j:=1 :m do
  277. << if old_denom = nil then b1 := append(b1,{simp!* old_denom })
  278. else << b1 := append(b1,{simp!* car old_denom});
  279. old_denom := cdr old_denom>>;
  280. >>;
  281. a2 := listsq old_num;
  282. b2 := listsq old_denom;
  283. if a1 = nil and a2 = nil then
  284. num := list({negsq alpha})
  285. else if a2 = nil then num := list(append(a1,{negsq alpha}))
  286. else
  287. << num := append(a1,{negsq alpha}); num := append({num},a2)>>;
  288. if b1 = nil and b2 = nil then
  289. denom := list({subtrsq(negsq alpha,'(1 . 1))})
  290. else if b2 = nil then
  291. denom := list(b1,subtrsq(negsq alpha,'(1 . 1)))
  292. else
  293. << denom := list(b1,subtrsq(negsq alpha,'(1 . 1)));
  294. denom := append(denom,b2)>>;
  295. v := gfmsq(num,denom,new_y);
  296. if v = 'fail then return simp 'fail
  297. else v := prepsq subsq(v,list(prepsq new_y . y));
  298. if eqcar(v,'meijerg) then new_v := v else new_v := simp v;
  299. return multsq(new_v,coeff);
  300. end;
  301. endpatch;
  302. patch hephys;
  303. symbolic procedure nospur u; <<rmsubs(); !*nospurp := t; flag(u,'nospur)>>;
  304. endpatch;
  305. % Int declarations.
  306. fluid '(!*purerisch !*trdint gaussiani indexlist intvar sqrt!-places!-alist
  307. loglist !*intflag!* listofnewsqrts listofallsqrts sqrt!-intvar
  308. basic!-listofallsqrts basic!-listofnewsqrts !*precise dmode!*
  309. !*exp !*gcd !*keepsqrts !*limitedfactors !*mcd !*rationalize
  310. !*structure !*uncached kord!*);
  311. smacro procedure argof u; cadr u;
  312. patch int;
  313. % 8 Jul 04, 31 Jan 05, 20 Apr 05, 2 May 05.
  314. symbolic procedure df2q p;
  315. begin scalar n,d,w,x,y,z;
  316. if null p then return nil ./ 1;
  317. d:=denr lc p;
  318. w:=red p;
  319. while w do
  320. <<d := multf(d,quotf(denr lc w,gcdf(d,denr lc w)));
  321. w := red w>>;
  322. while p do begin
  323. w := sqrt2top lc p;
  324. x := multf(xl2f(lpow p,zlist,indexlist),multf(numr w,d));
  325. if null x then return (p := red p);
  326. y := denr w;
  327. z := quotf(x,y);
  328. if null z
  329. then <<z := rationalizesq(x ./ y);
  330. if denr z neq 1
  331. then <<d := multf(denr z,d); n := multf(denr z,n)>>;
  332. z := numr z>>;
  333. n := addf(n,z);
  334. p := red p
  335. end;
  336. return tidy!-powersq (n ./ d)
  337. end;
  338. % 8 Jul 04, 22 May 05.
  339. symbolic procedure tidy!-powersq x;
  340. begin scalar expts,!*precise,!*keepsqrts;
  341. !*keepsqrts := t;
  342. x := subs2q x;
  343. expts := find!-expts(numr x,find!-expts(denr x,nil));
  344. if null expts then return x;
  345. x := subsq(x,for each v in expts collect
  346. (car v . list('expt,cadr v,cddr v)));
  347. x := subsq(x,for each v in expts collect
  348. (cadr v
  349. . list('expt,car v,list('quotient,1,cddr v))));
  350. return x
  351. end;
  352. symbolic procedure find!-expts(ff,l);
  353. begin scalar w;
  354. if domainp ff then return l;
  355. l := find!-expts(lc ff,find!-expts(red ff, l));
  356. ff := mvar ff;
  357. if eqcar(ff,'sqrt)
  358. then ff := list('expt, cadr ff,'(quotient 1 2))
  359. else if eqcar(ff,'expt) and eqcar(caddr ff,'quotient)
  360. and numberp caddr caddr ff
  361. then <<w := assoc(cadr ff,l);
  362. if null w
  363. then <<w := cadr ff . gensym() . 1; l := w . l >>;
  364. rplacd(cdr w,lcm(cddr w,caddr caddr ff))>>;
  365. return l
  366. end;
  367. % 28 Sep 04.
  368. symbolic procedure look_for_quad(integrand, var, zz);
  369. begin
  370. if (car zz = 'sqrt and listp cadr zz and caadr zz = 'plus) or
  371. (car zz = 'expt and listp cadr zz and caadr zz = 'plus and
  372. listp caddr zz and car caddr zz = 'quotient
  373. and fixp caddr caddr zz)
  374. then <<
  375. zz := simp cadr zz;
  376. if (cdr zz = 1) then <<
  377. zz := cdr coeff1(prepsq zz, var, nil);
  378. if length zz = 2 then return begin
  379. scalar a, b;
  380. scalar nvar, res, ss;
  381. a := car zz; b := cadr zz;
  382. if (depends(a,var) or depends(b,var)) then return nil;
  383. nvar := gensym();
  384. if !*trint then <<
  385. prin2 "Linear shift suggested ";
  386. prin2 a; prin2 " "; prin2 b; terpri();
  387. >>;
  388. integrand := subsq(integrand,
  389. list(var . list('quotient,
  390. list('difference,
  391. list('expt,nvar,2),a),
  392. b)));
  393. integrand := multsq(integrand,
  394. simp list('quotient,list('times,nvar,2),
  395. b));
  396. if !*trint then <<
  397. prin2 "Integrand is transformed by substitution to ";
  398. printsq integrand;
  399. prin2 "using substitution "; prin2 var; prin2 " -> ";
  400. printsq simp list('quotient,
  401. list('difference,list('expt,nvar,2),a),
  402. b);
  403. >>;
  404. res := integratesq(integrand, nvar, nil, nil);
  405. ss := list(nvar . list('sqrt,list('plus,list('times,var,b),
  406. a)));
  407. res := subsq(car res, ss) .
  408. subsq(multsq(cdr res, simp list('quotient,b,
  409. list('times,nvar,2))), ss);
  410. return res;
  411. end
  412. else if length zz = 3 then return begin
  413. scalar a, b, c;
  414. a := car zz; b := cadr zz; c:= caddr zz;
  415. if (depends(a,var) or depends(b,var) or depends(c,var)) then
  416. return nil;
  417. a := simp list('difference, a,
  418. list('times,b,b,
  419. list('quotient,1,list('times,4,c))));
  420. if null numr a then return nil;
  421. b := simp list('quotient, b, list('times, 2, c));
  422. c := simp c;
  423. return
  424. if minusf numr c then <<
  425. if minusf numr a then begin
  426. scalar !*hyperbolic;
  427. !*hyperbolic := t;
  428. return
  429. look_for_invhyp(integrand,nil,var,a,b,c)
  430. end
  431. else look_for_asin(integrand,var,a,b,c)>>
  432. else <<
  433. if minusf numr a then look_for_invhyp(integrand,t,var,a,b,c)
  434. else look_for_invhyp(integrand,nil,var,a,b,c)
  435. >>
  436. end
  437. else if length zz = 5 then return begin
  438. scalar a, b, c, d, e, nn, dd, mm;
  439. a := car zz; b := cadr zz; c:= caddr zz;
  440. d := cadddr zz; e := car cddddr zz;
  441. if not(b = 0) or not(d = 0) then return nil;
  442. if (depends(a,var) or depends(c,var)) or depends(e,var) then
  443. return nil;
  444. nn := numr integrand; dd := denr integrand;
  445. if denr(mm :=quotsq(nn ./ 1, !*kk2q var)) = 1 and
  446. even_power(numr mm, var) and even_power(dd, var) then <<
  447. return sqrt_substitute(numr mm, dd, var);
  448. >>;
  449. if denr(mm :=quotsq(dd ./ 1, !*kk2q var)) = 1 and
  450. even_power(nn, var) and even_power(numr mm, var) then <<
  451. return sqrt_substitute(nn, multf(dd,!*kk2f var), var);
  452. >>;
  453. return nil;
  454. end;
  455. >>>>;
  456. return nil
  457. end;
  458. % 21 Feb 06.
  459. symbolic procedure simpint u;
  460. if atom u or null cdr u or cddr u and (null cdddr u or cddddr u)
  461. then rerror(int,1,"Improper number of arguments to INT")
  462. else if cddr u then simpdint u
  463. else begin scalar ans,dmod,expression,variable,loglist,oldvarstack,
  464. !*intflag!*,!*purerisch,cflag,intvar,listofnewsqrts,
  465. listofallsqrts,sqrtfn,sqrt!-intvar,sqrt!-places!-alist,
  466. basic!-listofallsqrts,basic!-listofnewsqrts,coefft,
  467. varchange,w,!*precise;
  468. !*intflag!* := t;
  469. variable := !*a2k cadr u;
  470. if not(idp variable or pairp variable and numlistp cdr variable)
  471. then <<varchange := variable . intern gensym();
  472. if !*trint
  473. then printc {"Integration kernel", variable,
  474. "replaced by simple variable", cdr varchange};
  475. variable := cdr varchange>>;
  476. intvar := variable;
  477. w := cddr u;
  478. if w then rerror(int,3,"Too many arguments to INT");
  479. listofnewsqrts:= list mvar gaussiani;
  480. listofallsqrts:= list (argof mvar gaussiani . gaussiani);
  481. sqrtfn := get('sqrt,'simpfn);
  482. put('sqrt,'simpfn,'proper!-simpsqrt);
  483. if dmode!* then
  484. <<
  485. if (cflag:=get(dmode!*, 'cmpxfn)) then onoff('complex, nil);
  486. if (dmod := get(dmode!*,'dname)) then
  487. onoff(dmod,nil)>> where !*msg := nil;
  488. begin scalar dmode!*,!*exp,!*gcd,!*keepsqrts,!*limitedfactors,!*mcd,
  489. !*rationalize,!*structure,!*uncached,kord!*,
  490. ans1,badbit,denexp,erfg,nexp,oneterm;
  491. !*keepsqrts := !*limitedfactors := t;
  492. !*exp := !*gcd := !*mcd := !*structure := !*uncached := t;
  493. dmode!* := nil;
  494. if !*algint
  495. then <<
  496. sqrt!-intvar:=!*q2f simpsqrti variable;
  497. if (red sqrt!-intvar) or (lc sqrt!-intvar neq 1)
  498. or (ldeg sqrt!-intvar neq 1)
  499. then interr "Sqrt(x) not properly formed"
  500. else sqrt!-intvar:=mvar sqrt!-intvar;
  501. basic!-listofallsqrts:=listofallsqrts;
  502. basic!-listofnewsqrts:=listofnewsqrts;
  503. sqrtsave(basic!-listofallsqrts,basic!-listofnewsqrts,
  504. list(variable . variable))>>;
  505. coefft := (1 ./ 1);
  506. expression := int!-simp car u;
  507. if varchange
  508. then <<depend1(car varchange,cdr varchange,t);
  509. expression := int!-subsq(expression,{varchange})>>;
  510. denexp := 1 ./ denr expression;
  511. nexp := numr expression;
  512. while not atom nexp and null cdr nexp and
  513. not depends(mvar nexp,variable) do
  514. <<coefft := multsq(coefft,(((caar nexp) . 1) . nil) ./ 1);
  515. nexp := lc nexp>>;
  516. ans1 := nil;
  517. while nexp do begin
  518. scalar x,zv,tmp;
  519. if atom nexp then <<x := !*f2q nexp; nexp := nil>>
  520. else <<x := !*t2q car nexp; nexp := cdr nexp>>;
  521. x := multsq(x,denexp);
  522. zv := zvars(getvariables x,zv,variable,t);
  523. tmp := ans1;
  524. while tmp do
  525. <<if zv=caar tmp
  526. then <<rplacd(car tmp,addsq(cdar tmp,x));
  527. tmp := nil; zv := nil>>
  528. else tmp := cdr tmp>>;
  529. if zv then ans1 := (zv . x) . ans1
  530. end;
  531. if length ans1 = 1 then oneterm := t;
  532. nexp := ans1;
  533. ans := nil ./ 1;
  534. badbit:=nil ./ 1;
  535. while nexp do
  536. <<u := cdar nexp;
  537. if !*trdint
  538. then <<princ "Integrate"; printsq u;
  539. princ "with Zvars "; print caar nexp>>;
  540. erfg := erfg!*;
  541. ans1 := errorset!*(list('integratesq,mkquote u,
  542. mkquote variable,mkquote loglist,
  543. mkquote caar nexp),
  544. !*backtrace);
  545. erfg!* := erfg;
  546. nexp := cdr nexp;
  547. if errorp ans1 then badbit := addsq(badbit,u)
  548. else <<ans := addsq(caar ans1, ans);
  549. badbit:=addsq(cdar ans1,badbit)>>>>;
  550. if !*trdint
  551. then <<prin2 "Partial answer="; printsq ans;
  552. prin2 "To do="; printsq badbit>>;
  553. if badbit neq '(nil . 1)
  554. then <<setkorder nil;
  555. badbit := reordsq badbit;
  556. ans := reordsq ans;
  557. coefft := reordsq coefft;
  558. if !*trdint then <<princ "Retrying..."; printsq badbit>>;
  559. if oneterm and ans = '(nil . 1) then ans1 := nil
  560. else ans1 := errorset!*(list('integratesq,mkquote badbit,
  561. mkquote variable,mkquote loglist,nil),
  562. !*backtrace);
  563. if null ans1 or errorp ans1
  564. then ans := addsq(ans,simpint1(badbit . variable . w))
  565. else <<ans := addsq(ans,caar ans1);
  566. if not smemq(variable, ans) then ans := nil ./ 1;
  567. if cdar ans1 neq '(nil . 1)
  568. then ans := addsq(ans,
  569. simpint1(cdar ans1 . variable . w))
  570. >>>>;
  571. end;
  572. ans := multsq(coefft,ans);
  573. if !*trdint then << printc "Resimp and all that"; printsq ans >>;
  574. put('int,'simpfn,'simpiden);
  575. put('sqrt,'simpfn,sqrtfn);
  576. << if dmod then onoff(dmod,t);
  577. if cflag then onoff('complex,t)>> where !*msg := nil;
  578. oldvarstack := varstack!*;
  579. varstack!* := nil;
  580. ans := errorset!*(list('int!-resub,mkquote ans,mkquote
  581. varchange),t);
  582. put('int,'simpfn,'simpint);
  583. varstack!* := oldvarstack;
  584. return if errorp ans then error1() else car ans
  585. end;
  586. endpatch;
  587. patch mathpr;
  588. % 10 Dec 04, 29 Sep 06.
  589. symbolic procedure dflayout u;
  590. (begin
  591. scalar op, args, w;
  592. w := car (u := cdr u);
  593. u := cdr u;
  594. if smemq('int,w) then !*noarg := nil;
  595. if !*noarg and (atom w or not get(car w, 'op)) then <<
  596. if atom w then <<
  597. op := w;
  598. args := assoc(op, depl!*);
  599. if args then args := cdr args >>
  600. else <<
  601. op := car w;
  602. args := cdr w >>;
  603. remember!-args(op, args);
  604. w := op >>;
  605. maprin w;
  606. if u then <<
  607. u := layout!-formula('!!dfsub!! . u, 0, nil);
  608. if null u then return 'failed;
  609. w := 1 + cddr u;
  610. putpline((update!-pline(0, -w, caar u) . cdar u) .
  611. ((cadr u - w) . (cddr u - w))) >>
  612. end) where !*noarg = !*noarg;
  613. endpatch;
  614. patch matrix;
  615. % 26 Jun 04.
  616. symbolic procedure sparse_backsub(exlis,varlis);
  617. begin scalar d,z,c;
  618. if null exlis then return nil;
  619. d := lc car exlis;
  620. foreach x in exlis do
  621. begin scalar s,p,v,r;
  622. p := lc x;
  623. v := mvar x;
  624. x := red x;
  625. while not domainp x and mvar x member varlis do
  626. <<if (c := atsoc(mvar x,z)) then
  627. s := addf(multf(lc x,cdr c),s)
  628. else r := addf(!*t2f lt x,r);
  629. x := red x>>;
  630. s := negf quotff(addf(multf(addf(r,x),d),s),p);
  631. z := (v . s) . z;
  632. end;
  633. for each p in z do cdr p := cancel(cdr p ./ d);
  634. return z
  635. end;
  636. symbolic procedure quotff(u,v);
  637. if null u then nil
  638. else (if x then x
  639. else (if denr y = 1 then numr y
  640. else rederr "Invalid division in backsub")
  641. where y=rationalizesq(u ./ v))
  642. where x=quotf(u,v);
  643. % 23 May 06.
  644. symbolic procedure matsm1 u;
  645. begin scalar x,y,z; integer n;
  646. a: if null u then return z
  647. else if eqcar(car u,'!*div) then go to d
  648. else if atom car u then go to er
  649. else if caar u eq 'mat then go to c1
  650. else if flagp(caar u,'matmapfn) and cdar u
  651. and getrtype cadar u eq 'matrix
  652. then x := matsm matrixmap(car u,nil)
  653. else <<x := lispapply(caar u,cdar u);
  654. if eqcar(x,'mat) then x := matsm x>>;
  655. b: z := if null z then x
  656. else if null cdr z and null cdar z then multsm(caar z,x)
  657. else multm(x,z);
  658. c: u := cdr u;
  659. go to a;
  660. c1: if not lchk cdar u then rerror(matrix,3,"Matrix mismatch");
  661. x := for each j in cdar u collect
  662. for each k in j collect xsimp k;
  663. go to b;
  664. d: y := matsm cadar u;
  665. if (n := length car y) neq length y
  666. then rerror(matrix,4,"Non square matrix")
  667. else if (z and n neq length z)
  668. then rerror(matrix,5,"Matrix mismatch")
  669. else if cddar u then go to h
  670. else if null cdr y and null cdar y then go to e;
  671. x := subfg!*;
  672. subfg!* := nil;
  673. if null z then z := apply1(get('mat,'inversefn),y)
  674. else if null(x := get('mat,'lnrsolvefn))
  675. then z := multm(apply1(get('mat,'inversefn),y),z)
  676. else z := apply2(get('mat,'lnrsolvefn),y,z);
  677. subfg!* := x;
  678. z := for each j in z collect for each k in j collect
  679. <<!*sub2 := t; subs2 k>>;
  680. go to c;
  681. e: if null caaar y then rerror(matrix,6,"Zero divisor");
  682. y := revpr caar y;
  683. z := if null z then list list y else multsm(y,z);
  684. go to c;
  685. h: if null z then z := generateident n;
  686. go to c;
  687. er: rerror(matrix,7,list("Matrix",car u,"not set"))
  688. end;
  689. symbolic procedure matrixmap(u,v);
  690. if flagp(car u,'matmapfn)
  691. then matsm!*1 for each j in matsm cadr u collect
  692. for each k in j collect simp!*(car u . mk!*sq k . cddr u)
  693. else if flagp(car u,'matfn) then reval2(u,v)
  694. else typerr(car u,"matrix operator");
  695. put('matrix,'aggregatefn,'matrixmap);
  696. flag('(int df taylor),'matmapfn);
  697. flag('(det trace),'matfn);
  698. endpatch;
  699. patch poly;
  700. % 6 Sep 04.
  701. symbolic procedure fctrf u;
  702. (begin scalar !*ezgcd,!*gcd,denom,x,y;
  703. if domainp u then return list u
  704. else if ncmp!* and not noncomfp u then ncmp!* := nil;
  705. !*gcd := t;
  706. if null !*limitedfactors and null dmode!* then !*ezgcd := t;
  707. if null !*mcd
  708. then rerror(poly,15,"Factorization invalid with MCD off")
  709. else if null !*exp
  710. then <<!*exp := t; u := !*q2f resimp !*f2q u>>;
  711. if dmode!* eq '!:rn!:
  712. then <<dmode!* := nil; alglist!* := nil . nil;
  713. x := simp prepf u;
  714. if atom denr x then <<denom := denr x; u := numr x>>
  715. else denom := 1>>;
  716. if null ncmp!*
  717. then <<x := sf2ss u;
  718. if homogp x
  719. then <<if !*trfac
  720. then prin2t
  721. "This polynomial is homogeneous - variables scaled";
  722. y := caaar x . listsum caaadr x;
  723. x := fctrf1 ss2sf(car(x)
  724. . (reverse subs0 cadr x . 1));
  725. x := rconst(y,x);
  726. return car x . sort!-factors cdr x>>>>;
  727. u := fctrf1 u;
  728. if denom
  729. then <<alglist!* := nil . nil;
  730. dmode!* := '!:rn!:; car u := quotf!*(car u,denom)>>;
  731. return car u . sort!-factors cdr u
  732. end) where !*exp = !*exp, ncmp!* = ncmp!*;
  733. % 4 Oct 05.
  734. symbolic procedure deg(u,kern);
  735. <<u := simp!* u; tstpolyarg2(u,kern); numrdeg(numr u,kern)>>
  736. where dmode!* = gdmode!*;
  737. symbolic procedure tstpolyarg2(u,kern);
  738. <<for each j in kernels numr u do
  739. if j=kern then nil
  740. else if depends(j,kern) then typerr(prepsq u,"polynomial");
  741. for each j in kernels denr u do
  742. if depends(j,kern) then typerr(prepsq u,"polynomial")>>;
  743. % 11 Jan 07.
  744. symbolic procedure rnfactor!: u;
  745. begin scalar x,y,dmode!*; integer m,n;
  746. x := subf(u,nil);
  747. if not domainp denr x then return {1,(u . 1)};
  748. y := factorf numr x;
  749. n := car y;
  750. dmode!* := '!:rn!:;
  751. y := for each j in cdr y collect
  752. <<n := n*(m := (lnc ckrn car j)**cdr j);
  753. quotfd(car j,m) . cdr j>>;
  754. return int!-equiv!-chk mkrn(n,denr x) . y
  755. end;
  756. endpatch;
  757. patch rlfi;
  758. put('tex,'simpfn,'simpcar);
  759. endpatch;
  760. % Solve declarations.
  761. fluid '(!*cramer bareiss!-step!-size!*);
  762. global '(assumptions);
  763. patch solve;
  764. % 26 Jun 04.
  765. symbolic procedure solvelnrsys(exlis,varlis);
  766. begin scalar w,x;
  767. if w := solvesparsecheck(exlis,varlis) then exlis := w
  768. else exlis := exlis . varlis;
  769. if null !*cramer
  770. and null errorp(x :=
  771. errorset2{'solvebareiss,mkquote car exlis, mkquote cdr exlis}
  772. where bareiss!-step!-size!* = if w then 4 else 2)
  773. then exlis := car x
  774. else exlis := solvecramer(car exlis,cdr exlis);
  775. return solvesyspost(exlis,varlis)
  776. end;
  777. % 12 Feb 05, 5 Oct 05.
  778. symbolic procedure solvesq (ex,var,mul);
  779. begin scalar r,x;
  780. r:= for each w in solvesq1(ex,var,mul) join
  781. if null cadr w
  782. or eqcar(x := prepsq caar w,'root_of)
  783. or numr subfx(denr ex,{caadr w . x}) then {w};
  784. if r and not domainp denr ex then
  785. assumptions:=append(assumptions,{prepf denr ex});
  786. return r
  787. end;
  788. % 5 Oct 05.
  789. symbolic procedure subfx(u,v);
  790. begin scalar x;
  791. x := errorset2 {'subf,mkquote u,mkquote v};
  792. return if errorp x then 1 ./ 1 else car x
  793. end;
  794. % 12 Feb 05
  795. symbolic procedure polypeval u;
  796. begin scalar bool,v;
  797. v := cadr u;
  798. u := simpcar u;
  799. if cdr u neq 1 then return nil else u := kernels car u;
  800. while u and null bool do
  801. <<if v neq car u and smember(v,car u) then bool := t;
  802. u := cdr u>>;
  803. return null bool
  804. end;
  805. put('polyp,'psopfn,'polypeval);
  806. (algebraic <<
  807. depend(!~p,!~x);
  808. clearrules
  809. {root_of(~p,~x,~tg)^~n =>
  810. sub(x=root_of(p,x,tg),
  811. -reduct(p,x)/coeffn(p,x,deg(p,x)))^(n-deg(p,x)+1)
  812. when fixp n and deg(p,x)>=1 and n>=deg(p,x)};
  813. let root_of(~p,~x,~tg)^~n =>
  814. sub(x=root_of(p,x,tg),
  815. -reduct(p,x)/coeffn(p,x,deg(p,x))) ^ (n-deg(p,x)+1)
  816. when polyp(p,x) and fixp n and deg(p,x)>=1 and n>=deg(p,x);
  817. nodepend(!~p,!~x);
  818. >>) where dmode!*=nil,!*modular=nil,!*rounded=nil,!*complex=nil;
  819. % 30 May 05.
  820. symbolic procedure solvenonlnrtansolve(u,x,w);
  821. begin scalar v,s,z,r,y;
  822. integer ar;
  823. ar:=!!arbint;
  824. v:=caar u;u:=prepf numr simp cdr u;
  825. s:=solveeval{u,'tg!-};
  826. !!arbint:=ar;
  827. for each q in cdr s do
  828. <<z:=reval caddr q;
  829. z:=reval sublis(solvenonlnrtansolve1 z,z);
  830. !!arbint:=ar;
  831. y:=solve0({'equal,{'tan,{'quotient,V,2}},z},x);
  832. r:=union(y,r)>>;
  833. y := errorset2 {'subf,mkquote w,mkquote{x . 'pi}};
  834. if null errorp y and null numr y
  835. then <<!!arbint:=ar; r:=union(solve0({'equal,{'cos,x},-1},x),r)>>;
  836. return t.r end;
  837. % 5 Oct 05.
  838. symbolic procedure check!-solns(z,ex,var);
  839. begin scalar x,y;
  840. if not errorp (x :=
  841. errorset2 {'check!-solns1,mkquote z,mkquote ex,mkquote var})
  842. then return car x
  843. else if ex = (y := (numr simp!* prepf ex where !*reduced=t))
  844. or errorp (x :=
  845. errorset2 {'check!-solns1,mkquote z,mkquote y,mkquote var})
  846. then return 'unsolved
  847. else return car x
  848. end;
  849. symbolic procedure check!-solns1(z,ex,var);
  850. begin scalar x,y,fv,sx,vs;
  851. fv := freevarl(ex,var);
  852. for each z1 in z do
  853. fv := union(fv,union(freevarl(numr caar z1,var),
  854. freevarl(denr caar z1,var)));
  855. fv := delete('i,fv);
  856. if fv then for each v in fv do
  857. if not flagp(v,'constant) then
  858. vs := (v . list('quotient,1+random 999,1000)) . vs;
  859. sx := if vs then numr subf(ex,vs) else ex;
  860. while z do
  861. if null cadar z
  862. or
  863. errorp(y := errorset2 {'check!-solns2,mkquote ex,mkquote z})
  864. then <<z := nil; x := 'unsolved>>
  865. else if null(y := car y)
  866. or fv and null(y := numr subf(sx,list(caadar z .
  867. mk!*sq subsq(caaar z,vs))))
  868. or null numvalue y
  869. then <<x := car z . x; z := cdr z>>
  870. else z := cdr z;
  871. return if null x then 'unsolved else x
  872. end;
  873. symbolic procedure check!-solns2(ex,z);
  874. if smemq('root_of,z) then rederr 'check!-solns
  875. else numr subf(ex,{caadar z . mk!*sq caaar z});
  876. endpatch;
  877. patch specfn;
  878. % 20 Feb 06.
  879. algebraic (for all u,m let df(Jacobidn(u,m),u)
  880. = -m^2 *Jacobisn(u,m)*Jacobicn(u,m));
  881. endpatch;
  882. patch rlisp;
  883. !#if (member 'psl lispsystem!*)
  884. symbolic procedure global idlist;
  885. fluid idlist;
  886. symbolic procedure global1 id1;
  887. if not get(id1,'vartype) then fluid1 id1;
  888. !#endif
  889. endpatch;
  890. endmodule;
  891. end;