123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- module TaySubst;
- %*****************************************************************
- %
- % Interface to the substitution functions
- %
- %*****************************************************************
- exports subsubtaylor$
- imports
- % from the REDUCE kernel:
- addsq, denr, depends, domainp, eqcar, exptsq, invsq, lc, ldeg,
- mkrn, multsq, mvar, nlist, nth, numr, prepsq, red,
- replace!-nth!-nth, reval, reversip, simp!*, simprn, sort,
- subeval1, subs2!*, subsq, subtrsq, typerr,
- % from the header module:
- make!-Taylor!*, set!-TayCfSq, TayCfPl, TayCfSq, TayCoeffList,
- TayFlags, Taylor!:, Taylor!-error, TayVars, TayMakeCoeff,
- TayOrig, TayTemplate, TayTpElNext, TayTpElOrder, TayTpElPoint,
- TayTpElVars,
- % from module Tayintro:
- constant!-sq!-p, delete!-nth, delete!-nth!-nth, replace!-nth,
- Taylor!-error, Taylor!-error!*, var!-is!-nth,
- % from module Tayutils:
- enter!-sorted, rat!-kern!-pow;
- fluid '(!*taylorkeeporiginal);
- put ('taylor!*, 'subfunc, 'subsubtaylor);
- symbolic procedure subsubtaylor(l,v);
- begin scalar x,clist,delete_list,tp,pl;
- clist := for each u in TayCoeffList v collect
- TayMakeCoeff(TayCfPl u,subsq(TayCfSq u,l));
- tp := TayTemplate v;
- %
- % Substitute in expansion point
- %
- tp := for each quartet in tp collect
- {TayTpElVars quartet,
- reval subeval1(l,TayTpElPoint quartet),
- TayTpElOrder quartet,
- TayTpElNext quartet};
- pl := for each quartet in tp collect
- nlist(nil,length TayTpElVars quartet);
- %
- % Make x the list of substitutions of Taylor variables.
- %
- for each p in l do
- if car p member TayVars v
- %
- % The replacement of a Taylor variable must again be
- % a kernel. If it is a constant, we have to delete it
- % from the list of Taylor variables. Actually the main
- % problem is to distinguish kernels that are constant
- % expressions (e.g. sin (acos (4))) from others.
- %
- then begin scalar temp;
- temp := simp!* cdr p;
- if constant!-sq!-p temp
- then begin scalar about,ll,w,y,z; integer pos,pos1;
- %
- % Determine the position of the variable
- %
- w := var!-is!-nth(tp,car p);
- pos := car w;
- pos1 := cdr w;
- if not null nth(nth(pl,pos),pos1)
- then Taylor!-error('invalid!-subst,
- "multiple substitution for same variable");
- pl := replace!-nth!-nth(pl,pos,pos1,0);
- %
- % Calculate the difference (new_variable - expansion_point)
- %
- about := TayTpElPoint nth(tp,pos);
- if about eq 'infinity
- then if null numr temp
- then Taylor!-error!*('zero!-denom,"Taylor Substitution")
- else temp := invsq temp
- else temp := subtrsq(temp,simp!* about);
- %
- % Adjust for already deleted
- %
- foreach pp in delete_list do
- if car pp < pos then pos := pos - 1;
- delete_list := (pos . pos1) . delete_list;
- %
- % Substitute in every coefficient
- %
- Taylor!:
- for each cc in clist do begin scalar exponent;
- w := nth(TayCfPl cc,pos);
- w := if null cdr w then delete!-nth(TayCfPl cc,pos)
- else delete!-nth!-nth(TayCfPl cc,pos,pos1);
- exponent := nth(nth(TayCfPl cc,pos),pos1);
- z := if exponent = 0 then TayCfSq cc
- else if exponent < 0 and null numr temp
- then Taylor!-error!*('zero!-denom,
- "Taylor Substitution")
- else multsq(TayCfSq cc,exptsq(temp,exponent));
- y := assoc(w,ll);
- if y then set!-TayCfSq(y,subs2!* addsq(TayCfSq y,z))
- else if not null numr (z := subs2!* z)
- then ll := TayMakeCoeff(w,z) . ll
- end;
- %
- % Delete zero coefficients
- %
- clist := nil;
- while ll do <<
- if not null numr TayCfSq car ll
- then clist := enter!-sorted(car ll,clist);
- ll := cdr ll>>;
- end
- else if not (denr temp = 1 and
- (temp := rat!-kern!-pow(numr temp,t)))
- then typerr({'replaceby,car p,cdr p},
- "Taylor substitution")
- else begin scalar w,expo; integer pos,pos1;
- expo := cdr temp;
- temp := car temp;
- for each el in delete(car p,TayVars v) do
- if depends(temp,el)
- then Taylor!-error('invalid!-subst,
- {"dependent variables",cdr p,el});
- if not (expo = 1) then <<
- w := var!-is!-nth(tp,car p);
- pos := car w;
- pos1 := cdr w;
- if not null nth(nth(pl,pos),pos1)
- then Taylor!-error('invalid!-subst,
- "different powers in homogeneous template");
- pl := replace!-nth!-nth(pl,pos,pos1,expo)>>;
- x := (car p . temp) . x
- end
- end;
- for each pp in sort(delete_list,function sortpred) do
- <<if null cdr TayTpElVars u
- then <<tp := delete!-nth(tp,car pp);
- pl := delete!-nth(pl,car pp)>>
- else <<tp := replace!-nth(tp,car pp,
- {delete!-nth(TayTpElVars u,cdr pp),
- TayTpElPoint u,
- TayTpElOrder u,
- TayTpElNext u});
- pl := delete!-nth!-nth(pl,car pp,cdr pp)>>>>
- where u := nth(tp,car pp);
- if null tp
- then return if null clist then 0 else prepsq TayCfSq car clist;
- x := reversip x;
- pl := check!-pl pl;
- if null pl then Taylor!-error('invalid!-subst,
- "different powers in homogeneous template");
- return if pl = nlist(1,length tp)
- then make!-Taylor!*(clist,sublis(x,tp),
- if !*taylorkeeporiginal and TayOrig v
- then subsq(TayOrig v,l)
- else nil,
- TayFlags v)
- else make!-Taylor!*(change!-coefflist(clist,pl),
- change!-tp(sublis(x,tp),pl),
- if !*taylorkeeporiginal and TayOrig v
- then subsq(TayOrig v,l)
- else nil,
- TayFlags v)
- end;
- symbolic procedure sortpred(u,v);
- car u > car v or car u = car v and cdr u > cdr v;
- symbolic procedure check!-pl pl;
- Taylor!:
- if null pl then nil
- else ((if n=0 then check!-pl cdr pl
- else if n and n<0 then nil
- else n . check!-pl cdr pl)
- where n := check!-pl0(car car pl,cdr car pl));
- symbolic procedure check!-pl0(n,nl);
- if null nl then n else n=car nl and check!-pl0(n,cdr nl);
- symbolic procedure change!-coefflist(cflist,pl);
- for each cf in cflist collect
- TayMakeCoeff(change!-pl(TayCfPl cf,pl),TayCfSq cf);
- symbolic procedure change!-tp(tp,pl);
- if null tp then nil
- else (if null car pl then car tp
- else Taylor!:{TayTpElVars car tp,
- TayTpElPoint car tp,
- TayTpElOrder car tp * car pl,
- TayTpElNext car tp * car pl})
- . cdr tp;
- symbolic procedure change!-pl(pl,pl0);
- if null pl then nil
- else (if null car pl0 then car pl
- else for each n in car pl collect Taylor!:(car pl0 * n))
- . change!-pl(cdr pl,cdr pl0);
- endmodule;
- end;
|