taysubst.red 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. module TaySubst;
  2. %*****************************************************************
  3. %
  4. % Interface to the substitution functions
  5. %
  6. %*****************************************************************
  7. exports subsubtaylor$
  8. imports
  9. % from the REDUCE kernel:
  10. addsq, denr, depends, domainp, eqcar, exptsq, invsq, lc, ldeg,
  11. mkrn, multsq, mvar, nlist, nth, numr, prepsq, red,
  12. replace!-nth!-nth, reval, reversip, simp!*, simprn, sort,
  13. subeval1, subs2!*, subsq, subtrsq, typerr,
  14. % from the header module:
  15. make!-Taylor!*, set!-TayCfSq, TayCfPl, TayCfSq, TayCoeffList,
  16. TayFlags, Taylor!:, Taylor!-error, TayVars, TayMakeCoeff,
  17. TayOrig, TayTemplate, TayTpElNext, TayTpElOrder, TayTpElPoint,
  18. TayTpElVars,
  19. % from module Tayintro:
  20. constant!-sq!-p, delete!-nth, delete!-nth!-nth, replace!-nth,
  21. Taylor!-error, Taylor!-error!*, var!-is!-nth,
  22. % from module Tayutils:
  23. enter!-sorted, rat!-kern!-pow;
  24. fluid '(!*taylorkeeporiginal);
  25. put ('taylor!*, 'subfunc, 'subsubtaylor);
  26. symbolic procedure subsubtaylor(l,v);
  27. begin scalar x,clist,delete_list,tp,pl;
  28. clist := for each u in TayCoeffList v collect
  29. TayMakeCoeff(TayCfPl u,subsq(TayCfSq u,l));
  30. tp := TayTemplate v;
  31. %
  32. % Substitute in expansion point
  33. %
  34. tp := for each quartet in tp collect
  35. {TayTpElVars quartet,
  36. reval subeval1(l,TayTpElPoint quartet),
  37. TayTpElOrder quartet,
  38. TayTpElNext quartet};
  39. pl := for each quartet in tp collect
  40. nlist(nil,length TayTpElVars quartet);
  41. %
  42. % Make x the list of substitutions of Taylor variables.
  43. %
  44. for each p in l do
  45. if car p member TayVars v
  46. %
  47. % The replacement of a Taylor variable must again be
  48. % a kernel. If it is a constant, we have to delete it
  49. % from the list of Taylor variables. Actually the main
  50. % problem is to distinguish kernels that are constant
  51. % expressions (e.g. sin (acos (4))) from others.
  52. %
  53. then begin scalar temp;
  54. temp := simp!* cdr p;
  55. if constant!-sq!-p temp
  56. then begin scalar about,ll,w,y,z; integer pos,pos1;
  57. %
  58. % Determine the position of the variable
  59. %
  60. w := var!-is!-nth(tp,car p);
  61. pos := car w;
  62. pos1 := cdr w;
  63. if not null nth(nth(pl,pos),pos1)
  64. then Taylor!-error('invalid!-subst,
  65. "multiple substitution for same variable");
  66. pl := replace!-nth!-nth(pl,pos,pos1,0);
  67. %
  68. % Calculate the difference (new_variable - expansion_point)
  69. %
  70. about := TayTpElPoint nth(tp,pos);
  71. if about eq 'infinity
  72. then if null numr temp
  73. then Taylor!-error!*('zero!-denom,"Taylor Substitution")
  74. else temp := invsq temp
  75. else temp := subtrsq(temp,simp!* about);
  76. %
  77. % Adjust for already deleted
  78. %
  79. foreach pp in delete_list do
  80. if car pp < pos then pos := pos - 1;
  81. delete_list := (pos . pos1) . delete_list;
  82. %
  83. % Substitute in every coefficient
  84. %
  85. Taylor!:
  86. for each cc in clist do begin scalar exponent;
  87. w := nth(TayCfPl cc,pos);
  88. w := if null cdr w then delete!-nth(TayCfPl cc,pos)
  89. else delete!-nth!-nth(TayCfPl cc,pos,pos1);
  90. exponent := nth(nth(TayCfPl cc,pos),pos1);
  91. z := if exponent = 0 then TayCfSq cc
  92. else if exponent < 0 and null numr temp
  93. then Taylor!-error!*('zero!-denom,
  94. "Taylor Substitution")
  95. else multsq(TayCfSq cc,exptsq(temp,exponent));
  96. y := assoc(w,ll);
  97. if y then set!-TayCfSq(y,subs2!* addsq(TayCfSq y,z))
  98. else if not null numr (z := subs2!* z)
  99. then ll := TayMakeCoeff(w,z) . ll
  100. end;
  101. %
  102. % Delete zero coefficients
  103. %
  104. clist := nil;
  105. while ll do <<
  106. if not null numr TayCfSq car ll
  107. then clist := enter!-sorted(car ll,clist);
  108. ll := cdr ll>>;
  109. end
  110. else if not (denr temp = 1 and
  111. (temp := rat!-kern!-pow(numr temp,t)))
  112. then typerr({'replaceby,car p,cdr p},
  113. "Taylor substitution")
  114. else begin scalar w,expo; integer pos,pos1;
  115. expo := cdr temp;
  116. temp := car temp;
  117. for each el in delete(car p,TayVars v) do
  118. if depends(temp,el)
  119. then Taylor!-error('invalid!-subst,
  120. {"dependent variables",cdr p,el});
  121. if not (expo = 1) then <<
  122. w := var!-is!-nth(tp,car p);
  123. pos := car w;
  124. pos1 := cdr w;
  125. if not null nth(nth(pl,pos),pos1)
  126. then Taylor!-error('invalid!-subst,
  127. "different powers in homogeneous template");
  128. pl := replace!-nth!-nth(pl,pos,pos1,expo)>>;
  129. x := (car p . temp) . x
  130. end
  131. end;
  132. for each pp in sort(delete_list,function sortpred) do
  133. <<if null cdr TayTpElVars u
  134. then <<tp := delete!-nth(tp,car pp);
  135. pl := delete!-nth(pl,car pp)>>
  136. else <<tp := replace!-nth(tp,car pp,
  137. {delete!-nth(TayTpElVars u,cdr pp),
  138. TayTpElPoint u,
  139. TayTpElOrder u,
  140. TayTpElNext u});
  141. pl := delete!-nth!-nth(pl,car pp,cdr pp)>>>>
  142. where u := nth(tp,car pp);
  143. if null tp
  144. then return if null clist then 0 else prepsq TayCfSq car clist;
  145. x := reversip x;
  146. pl := check!-pl pl;
  147. if null pl then Taylor!-error('invalid!-subst,
  148. "different powers in homogeneous template");
  149. return if pl = nlist(1,length tp)
  150. then make!-Taylor!*(clist,sublis(x,tp),
  151. if !*taylorkeeporiginal and TayOrig v
  152. then subsq(TayOrig v,l)
  153. else nil,
  154. TayFlags v)
  155. else make!-Taylor!*(change!-coefflist(clist,pl),
  156. change!-tp(sublis(x,tp),pl),
  157. if !*taylorkeeporiginal and TayOrig v
  158. then subsq(TayOrig v,l)
  159. else nil,
  160. TayFlags v)
  161. end;
  162. symbolic procedure sortpred(u,v);
  163. car u > car v or car u = car v and cdr u > cdr v;
  164. symbolic procedure check!-pl pl;
  165. Taylor!:
  166. if null pl then nil
  167. else ((if n=0 then check!-pl cdr pl
  168. else if n and n<0 then nil
  169. else n . check!-pl cdr pl)
  170. where n := check!-pl0(car car pl,cdr car pl));
  171. symbolic procedure check!-pl0(n,nl);
  172. if null nl then n else n=car nl and check!-pl0(n,cdr nl);
  173. symbolic procedure change!-coefflist(cflist,pl);
  174. for each cf in cflist collect
  175. TayMakeCoeff(change!-pl(TayCfPl cf,pl),TayCfSq cf);
  176. symbolic procedure change!-tp(tp,pl);
  177. if null tp then nil
  178. else (if null car pl then car tp
  179. else Taylor!:{TayTpElVars car tp,
  180. TayTpElPoint car tp,
  181. TayTpElOrder car tp * car pl,
  182. TayTpElNext car tp * car pl})
  183. . cdr tp;
  184. symbolic procedure change!-pl(pl,pl0);
  185. if null pl then nil
  186. else (if null car pl0 then car pl
  187. else for each n in car pl collect Taylor!:(car pl0 * n))
  188. . change!-pl(cdr pl,cdr pl0);
  189. endmodule;
  190. end;