Artifact 1074b810025a27d057131103fc0d538e67558890623016108afc4fa67c0147a9:
- Executable file
r37/packages/dipoly/a2dip.red
— part of check-in
[f2fda60abd]
at
2011-09-02 18:13:33
on branch master
— Some historical releases purely for archival purposes
git-svn-id: https://svn.code.sf.net/p/reduce-algebra/code/trunk/historical@1375 2bfe0521-f11c-4a00-b80e-6202646ff360 (user: arthurcnorman@users.sourceforge.net, size: 3535) [annotate] [blame] [check-ins using] [more...]
module a2dip; %/*Convert an algebraic (prefix) form to distributive polynomial*/ %/*Authors: R. Gebauer, A. C. Hearn, H. Kredel*/ % Modified by: H. Melenk. fluid '(dipvars!* dipzero !*vdpinteger); symbolic procedure a2dip u; % /*Converts the algebraic (prefix) form u to a distributive poly. % We assume that all variables used have been previously % defined in dipvars!*, but a check is also made for this*/ if atom u then a2dipatom u else if not atom car u or not idp car u then typerr(car u,"dipoly operator") % Handling expt separately because the exponents should % not be simplified as domain elements. else if car u = 'expt then dipfnpow(a2dip cadr u,caddr u) else (if x then apply(x,list for each y in cdr u collect a2dip y) else a2dipatom u) where x = get(car u,'dipfn); expr procedure a2dipatom u; % /*Converts the atom (or kernel) u into a distributive polynomial*/ if u=0 then dipzero else if numberp u or not(u member dipvars!*) then dipfmon(a2bc u,evzero()) else dipfmon(a2bc 1,mkexpvec u); expr procedure dipfnsum u; % /*U is a list of dip expressions. Result is the distributive poly % representation for the sum*/ (<<for each y in cdr u do x := dipsum(x,y); x>>) where x = car u; put('plus,'dipfn,'dipfnsum); put('plus2,'dipfn,'dipfnsum); expr procedure dipfnprod u; % /*U is a list of dip expressions. Result is the distributive poly % representation for the product*/ % /*Maybe we should check for a zero*/ (<<for each y in cdr u do x := dipprod(x,y); x>>) where x = car u; put('times,'dipfn,'dipfnprod); put('times2,'dipfn,'dipfnprod); expr procedure dipfndif u; % /*U is a list of two dip expressions. Result is the distributive % polynomial representation for the difference*/ dipsum(car u,dipneg cadr u); put('difference,'dipfn,'dipfndif); symbolic procedure dipfnpow(v,n); % V is a dip. Result is the distributive poly v**n. (if not fixp n or n<0 then typerr(n,"distributive polynomial exponent") else if n=0 then if dipzero!? v then rerror(dipoly,1,"0**0 invalid") else w else if dipzero!? v or n=1 then v else if dipzero!? dipmred v then dipfmon(bcpow(diplbc v,n),intevprod(n,dipevlmon v)) else <<while n>0 do <<if not evenp n then w := dipprod(w,v); n := n/2; if n>0 then v := dipprod(v,v)>>; w>>) where w := dipfmon(a2bc 1,evzero()); % put('expt,'dipfn,'dipfnpow); expr procedure dipfnneg u; % /*U is a list of one dip expression. Result is the distributive % polynomial representation for the negative*/ (if dipzero!? v then v else dipmoncomp(bcneg diplbc v,dipevlmon v,dipmred v)) where v = car u; put('minus,'dipfn,'dipfnneg); symbolic procedure dipfnquot u; % /*U is a list of two dip expressions. Result is the distributive % polynomial representation for the quotient*/ if dipzero!? cadr u or not dipzero!? dipmred cadr u or not evzero!? dipevlmon cadr u or (!*vdpinteger and not bcone!? diplbc cadr u) then typerr(dip2a cadr u,"distributive polynomial denominator") else dipfnquot1(car u,diplbc cadr u); expr procedure dipfnquot1(u,v); if dipzero!? u then u else dipmoncomp(bcquot(diplbc u,v), dipevlmon u, dipfnquot1(dipmred u,v)); put('quotient,'dipfn,'dipfnquot); endmodule; end;