contents.red 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. module contents;
  2. % Authors: Mary Ann Moore and Arthur C. Norman.
  3. fluid '(content indexlist sqfr varlist zlist); % clogflag
  4. exports contents,contentsmv,dfnumr,difflogs,factorlistlist, % multsqfree
  5. multup,sqfree,sqmerge;
  6. imports int!-fac,fquotf,gcdf,interr,!*multf,partialdiff,quotf,ordop,
  7. addf,negf,domainp,difff,mksp,negsq,invsq,addsq,!*multsq,diffsq;
  8. comment we assume no power substitution is necessary in this module;
  9. symbolic procedure contents(p,v);
  10. % Find the contents of the polynomial p wrt variable v;
  11. % Note that v may not be the main variable of p;
  12. if domainp(p) then p
  13. else if v=mvar p then contentsmv(p,v,nil)
  14. else if ordop(v,mvar p) then p
  15. else contentsmv(makemainvar(p,v),v,nil);
  16. symbolic procedure contentsmv(p,v,sofar);
  17. % Find contents of polynomial P;
  18. % V is main variable of P;
  19. % SOFAR is partial result;
  20. if sofar=1 then 1
  21. else if domainp p then gcdf(p,sofar)
  22. else if not(v=mvar p) then gcdf(p,sofar)
  23. else contentsmv(red p,v,gcdf(lc p,sofar));
  24. symbolic procedure makemainvar(p,v);
  25. % Bring v up to be the main variable in polynomial p.
  26. % Note that the reconstructed p must be used with care since
  27. % it does not conform to the normal REDUCE ordering rules.
  28. if domainp p then p
  29. else if v=mvar p then p
  30. else mergeadd(mulcoeffsby(makemainvar(lc p,v),lpow p,v),
  31. makemainvar(red p,v),v);
  32. symbolic procedure mulcoeffsby(p,pow,v);
  33. % Multiply each coefficient in p by the standard power pow;
  34. if null p then nil
  35. else if domainp p or not(v=mvar p) then ((pow .* p) .+ nil)
  36. else (lpow p .* ((pow .* lc p) .+ nil)) .+ mulcoeffsby(red p,pow,v);
  37. symbolic procedure mergeadd(a,b,v);
  38. % Add polynomials a and b given that they have same main variable v;
  39. if domainp a or not(v=mvar a) then
  40. if domainp b or not(v=mvar b) then addf(a,b)
  41. else lt b .+ mergeadd(a,red b,v)
  42. else if domainp b or not(v=mvar b) then
  43. lt a .+ mergeadd(red a,b,v)
  44. else (lambda xc;
  45. if xc=0 then (lpow a .* addf(lc a,lc b)) .+
  46. mergeadd(red a,red b,v)
  47. else if xc>0 then lt a .+ mergeadd(red a,b,v)
  48. else lt b .+ mergeadd(a,red b,v))
  49. (tdeg lt a-tdeg lt b);
  50. symbolic procedure sqfree(p,vl);
  51. if (null vl) or (domainp p) then
  52. <<content:=p; nil>>
  53. else begin scalar w,v,dp,gg,pg,dpg,p1,w1;
  54. w:=contents(p,car vl); % content of p ;
  55. p:=quotf(p,w); % make p primitive;
  56. w:=sqfree(w,cdr vl); % process content by recursion;
  57. if p=1 then return w;
  58. v:=car vl; % pick out variable from list;
  59. while not (p=1) do <<
  60. dp:=partialdiff(p,v);
  61. gg:=gcdf(p,dp);
  62. pg:=quotf(p,gg);
  63. dpg:=negf partialdiff(pg,v);
  64. p1:=gcdf(pg,addf(quotf(dp,gg),dpg));
  65. w1:=p1.w1;
  66. p:=gg>>;
  67. return sqmerge(reverse w1,w,t)
  68. end;
  69. symbolic procedure sqmerge(w1,w,simplew1);
  70. % w and w1 are lists of factors of each power. if simplew1 is true
  71. % then w1 contains only single factors for each power. ;
  72. if null w1 then w
  73. else if null w then if car w1=1 then nil.sqmerge(cdr w1,w,simplew1)
  74. else (if simplew1 then list car w1 else car w1).
  75. sqmerge(cdr w1,w,simplew1)
  76. else if car w1=1 then (car w).sqmerge(cdr w1,cdr w,simplew1) else
  77. append(if simplew1 then list car w1 else car w1,car w).
  78. sqmerge(cdr w1,cdr w,simplew1);
  79. symbolic procedure multup l;
  80. % l is a list of s.f.'s. result is s.f. for product of elements of l;
  81. begin scalar res;
  82. res:=1;
  83. for each j in l do res := multf(res,j);
  84. % while not null l do <<
  85. % res:=multf(res,car l);
  86. % l:=cdr l >>;
  87. return res
  88. end;
  89. symbolic procedure diflist(l,cl,x,rl);
  90. % Differentiates l (list of s.f.'s) wrt x to produce the sum of
  91. % terms for the derivative of numr of 1st part of answer. cl is
  92. % coefficient list (s.f.'s) & rl is list of derivatives we have
  93. % dealt with so far. Result is s.q.;
  94. if null l then nil ./ 1
  95. else begin scalar temp;
  96. temp:=!*multf(multup rl,multup cdr l);
  97. temp:=!*multsq(difff(car l,x),!*f2q temp);
  98. temp:=!*multsq(temp,(car cl) ./ 1);
  99. return addsq(temp,diflist(cdr l,cdr cl,x,(car l).rl))
  100. end;
  101. %symbolic procedure multsqfree w;
  102. %% W is list of sqfree factors. result is product of each list in w
  103. %% to give one polynomial for each sqfree power.
  104. % if null w then nil
  105. % else (multup car w) . multsqfree cdr w;
  106. symbolic procedure l2lsf l;
  107. % L is a list of kernels. result is a list of same members as s.f.'s;
  108. if null l then nil
  109. else ((mksp(car l,1) .* 1) .+ nil).l2lsf cdr l;
  110. symbolic procedure dfnumr(x,dl);
  111. % Gives the derivative of the numr of the 1st part of answer.
  112. % dl is list of any exponential or 1+tan**2 that occur in integrand
  113. % denr. these are divided out from result before handing it back.
  114. % result is s.q., ready for printing.
  115. begin scalar temp1,temp2,coeflist,qlist,count;
  116. if not null sqfr then <<
  117. count:=0;
  118. qlist:=cdr sqfr;
  119. coeflist:=nil;
  120. while not null qlist do <<
  121. count:=count+1;
  122. coeflist:=count.coeflist;
  123. qlist:=cdr qlist >>;
  124. coeflist:=reverse coeflist >>;
  125. temp1:=!*multsq(diflist(l2lsf zlist,l2lsf indexlist,x,nil),
  126. !*f2q multup sqfr);
  127. if not null sqfr and not null cdr sqfr then <<
  128. temp2:=!*multsq(diflist(cdr sqfr,coeflist,x,nil),
  129. !*f2q multup l2lsf zlist);
  130. temp2:=!*multsq(temp2,(car sqfr) ./ 1) >>
  131. else temp2:=nil ./ 1;
  132. temp1:=addsq(temp1,negsq temp2);
  133. temp2:=cdr temp1;
  134. temp1:=car temp1;
  135. qlist:=nil;
  136. while not null dl do <<
  137. if not(car dl member qlist) then qlist:=(car dl).qlist;
  138. dl:=cdr dl >>;
  139. while not null qlist do <<
  140. temp1:=quotf(temp1,car qlist);
  141. qlist:=cdr qlist >>;
  142. return temp1 ./ temp2
  143. end;
  144. symbolic procedure difflogs(ll,denm1,x);
  145. % LL is list of log terms (with coeffts), den is common denominator
  146. % over which they are to be put. Result is s.q. for derivative of all
  147. % these wrt x.
  148. if null ll then nil ./ 1
  149. else begin scalar temp,qu,cvar,logoratan,arg;
  150. logoratan:=caar ll;
  151. cvar:=cadar ll;
  152. arg:=cddar ll;
  153. temp:=!*multsq(cvar ./ 1,diffsq(arg,x));
  154. if logoratan='iden then qu:=1 ./ 1
  155. else if logoratan='log then qu:=arg
  156. else if logoratan='atan then qu:=addsq(1 ./ 1,!*multsq(arg,arg))
  157. else interr "Logoratan=? in difflogs";
  158. %Note call to special division routine;
  159. qu:=fquotf(!*multf(!*multf(denm1,numr temp),
  160. denr qu),numr qu);
  161. %*MUST* GO EXACTLY;
  162. temp:=!*multsq(!*invsq (denr temp ./ 1),qu);
  163. %result of fquotf is a s.q;
  164. return !*addsq(temp,difflogs(cdr ll,denm1,x))
  165. end;
  166. symbolic procedure factorlistlist w;
  167. % W is list of lists of sqfree factors in s.f. Result is list of log
  168. % terms required for integral answer. the arguments for each log fn
  169. % are in s.q.
  170. begin scalar res,x,y;
  171. while not null w do <<
  172. x:=car w;
  173. while not null x do <<
  174. y:=facbypp(car x,varlist);
  175. while not null y do <<
  176. res:=append(int!-fac car y,res);
  177. y:=cdr y >>;
  178. x:=cdr x >>;
  179. w:=cdr w >>;
  180. return res
  181. end;
  182. symbolic procedure facbypp(p,vl);
  183. % Use contents/primitive parts to try to factor p.
  184. if null vl then list p
  185. else begin scalar princilap!-part,co;
  186. co:=contents(p,car vl);
  187. vl:=cdr vl;
  188. if co=1 then return facbypp(p,vl); %this var no help.
  189. princilap!-part:=quotf(p,co); %primitive part.
  190. if princilap!-part=1 then return facbypp(p,vl); % again no help
  191. return nconc(facbypp(princilap!-part,vl),facbypp(co,vl))
  192. end;
  193. endmodule;
  194. end;