123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- module xexcalc;
- % Modifications to Eberhard Schruefer's excalc
- % Author: David Hartley
- Comment. The core routines in EXCALC have symbols:
- wedgepf2: pf,wedgepf -> wedgepf
- wedgek2: lpow pf,lpow wedgepf -> wedgepf
- addpf: pf,pf -> pf
- addpf: wedgepf,wedgepf -> wedgepf
- The overloading on addpf makes it hard to modify to use a different
- order: the following routines cannot guarantee that ordering of terms
- in a polynomial will be the same in pf or wedgpf representation.
- endcomment;
- global '(dimex!*);
- symbolic procedure addpf(u,v);
- % change to use termordp!! rather than ordop
- if null u then v
- else if null v then u
- else if ldpf u = 1 then addmpf(u,v)
- else if ldpf v = 1 then addmpf(v,u)
- else if ldpf u = ldpf v then
- (lambda x,y;
- if null numr x then y else ldpf u .* x .+ y)
- (addsq(lc u,lc v),addpf(red u,red v))
- else if termordp!!(ldpf u,ldpf v) then lt u .+ addpf(red u,v)
- else lt v .+ addpf(u,red v);
- symbolic procedure termordp!!(u,v);
- % u,v:lpow pf|lpow wedgepf -> termordp!!:bool
- % as for termordp, but trying to accomodate wedgepf and pf terms
- u neq v and
- termordp(guesspftype u,guesspftype v);
- symbolic procedure guesspftype u;
- % u:lpow pf|lpow wedgepf -> guesspftype:lpow pf
- % if we have pform x=1,y=1,x(i)=1, then we can't tell whether
- % (x y) means x^y or x(y). Here we choose the former.
- if atom u then u
- else if car u memq '(wedge d partdf hodge innerprod liedf) then u
- else if assoc(length cdr u,get(car u,'ifdegree)) and
- not xvarlistp cdr u then u
- else mknwedge u;
- symbolic procedure xvarlistp x;
- % x:list of kernel -> xvarlistp:bool
- % heuristic to check if x is a list of pform variables
- null x or xvarp car x and xvarlistp cdr x;
- symbolic procedure addmpf(u,v);
- % add extra test for vanishing coefficient
- if null v then u
- else if ldpf v = 1 then
- (if numr x then 1 .* x .+ nil) where x = addsq(lc u,lc v)
- else lt v .+ addmpf(u,red v);
- symbolic procedure deg!*form u;
- %U is a prefix expression. Result is the degree of u;
- % add !*sq prefix forms
- if atom u then get!*fdeg u
- else (if flagp(x,'indexvar) then get!*ifdeg u
- else if x eq 'wedge then deg!*farg cdr u
- else if x eq 'd then addd(1,deg!*form cadr u)
- else if x eq 'hodge then addf(dimex!*,negf deg!*form cadr u)
- else if x eq 'partdf then if cddr u then nil else -1
- else if x eq 'liedf then deg!*form caddr u
- else if x eq 'innerprod then addd(-1,deg!*form caddr u)
- else if x memq '(plus minus difference quotient) then
- deg!*form cadr u
- else if x eq 'times then deg!*farg cdr u
- else if x eq '!*sq then deg!*form prepsq simp!* u
- else nil) where x = car u;
- % The following two routines are copied from the development version of
- % excalc to overcome an error message "+++ oddp nil" in the CSL version.
- symbolic procedure oddp m;
- if not fixp m then typerr(m,"integer") else remainder(m,2) neq 0;
- symbolic procedure wedgek2(u,v,w);
- if u eq car v and null eqcar(u,'wedge)
- then if (fixp n and oddp n) where n = deg!*form u then nil
- else multpfsq(wedgef(u . v),mksgnsq w)
- else if eqcar(car v,'wedge) then wedgek2(u,cdar v,w)
- else if eqcar(u,'wedge)
- then multpfsq(wedgewedge(cdr u,v),mksgnsq w)
- else if wedgeordp(u,car v)
- then multpfsq(wedgef(u . v),mksgnsq w)
- else if cdr v
- then wedgepf2(!*k2pf car v,
- wedgek2(u,cdr v,addf(w,multf(deg!*form u,
- deg!*form car v))))
- else multpfsq(wedgef list(car v,u),
- mksgnsq addf(w,multf(deg!*form u,deg!*form car v)));
- endmodule;
- end;
|