123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- MODULE HACKSQRT; % Routines for manipulation of sqrt expressions.
- % Author: James H. Davenport.
- FLUID '(NESTEDSQRTS THISPLACE);
- EXPORTS SQRTSINTREE,SQRTSINSQ,SQRTSINSQL,SQRTSINSF,SQRTSIGN;
- EXPORTS DEGREENEST,SORTSQRTS;
- IMPORTS MKVECT,INTERR,GETV,DEPENDSP,UNION;
- SYMBOLIC PROCEDURE SQRTSINTREE(U,VAR,SLIST);
- % Adds to slist all the sqrts in the prefix-type tree u.
- IF ATOM U
- THEN SLIST
- ELSE IF CAR U EQ '!*SQ
- THEN UNION(SLIST,SQRTSINSQ(CADR U,VAR))
- ELSE IF CAR U EQ 'SQRT
- THEN IF DEPENDSP(ARGOF U,VAR)
- THEN <<
- SLIST:=SQRTSINTREE(ARGOF U,VAR,SLIST);
- % nested square roots
- IF MEMBER(U,SLIST)
- THEN SLIST
- ELSE U.SLIST >>
- ELSE SLIST
- ELSE SQRTSINTREE(CAR U,VAR,SQRTSINTREE(CDR U,VAR,SLIST));
- SYMBOLIC PROCEDURE SQRTSINSQ(U,VAR);
- % Returns list of all sqrts in sq.
- SQRTSINSF(DENR U,SQRTSINSF(NUMR U,NIL,VAR),VAR);
- SYMBOLIC PROCEDURE SQRTSINSQL(U,VAR);
- % Returns list of all sqrts in sq list.
- IF NULL U
- THEN NIL
- ELSE SQRTSINSF(DENR CAR U,
- SQRTSINSF(NUMR CAR U,SQRTSINSQL(CDR U,VAR),VAR),VAR);
- SYMBOLIC PROCEDURE SQRTSINSF(U,SLIST,VAR);
- % Adds to slist all the sqrts in sf.
- IF DOMAINP U OR NULL U
- THEN SLIST
- ELSE <<
- IF EQCAR(MVAR U,'SQRT) AND
- DEPENDSP(ARGOF MVAR U,VAR) AND
- NOT MEMBER(MVAR U,SLIST)
- THEN BEGIN
- SCALAR SLIST2;
- SLIST2:=SQRTSINTREE(ARGOF MVAR U,VAR,NIL);
- IF SLIST2
- THEN <<
- NESTEDSQRTS:=T;
- SLIST:=UNION(SLIST2,SLIST) >>;
- SLIST:=(MVAR U).SLIST
- END;
- SQRTSINSF(LC U,SQRTSINSF(RED U,SLIST,VAR),VAR) >>;
- SYMBOLIC PROCEDURE EASYSQRTSIGN(SLIST,THINGS);
- % This procedure builds a list of all substitutions for all possible
- % combinations of square roots in list.
- IF NULL SLIST
- THEN THINGS
- ELSE EASYSQRTSIGN(CDR SLIST,
- NCONC(MAPCONS(THINGS,(CAR SLIST).(CAR SLIST)),
- MAPCONS(THINGS,
- LIST(CAR SLIST,'MINUS,CAR SLIST))));
- SYMBOLIC PROCEDURE HARDSQRTSIGN(SLIST,THINGS);
- % This procedure fulfils the same role for nested sqrts
- % ***assumption: the simpler sqrts come further up the list.
- IF NULL SLIST
- THEN THINGS
- ELSE BEGIN
- SCALAR THISPLACE,ANSWERS,POS,NEG;
- THISPLACE:=CAR SLIST;
- ANSWERS:= for each u in THINGS collect SUBLIS(U,THISPLACE) . U;
- POS := for each u in ANSWERS collect (THISPLACE . CAR U) . CDR U;
- % pos is sqrt(f) -> sqrt(innersubst f)
- NEG := for each u in ANSWERS
- collect {THISPLACE,'MINUS,CAR U} . CDR U;
- % neg is sqrt(f) -> -sqrt(innersubst f)
- RETURN HARDSQRTSIGN(CDR SLIST,NCONC(POS,NEG))
- END;
- SYMBOLIC PROCEDURE DEGREENEST(PF,VAR);
- % Returns the maximum degree of nesting of var
- % inside sqrts in the prefix form pf.
- IF ATOM PF
- THEN 0
- ELSE IF CAR PF EQ 'SQRT
- THEN IF DEPENDSP(CADR PF,VAR)
- THEN IADD1 DEGREENEST(CADR PF,VAR)
- ELSE 0
- ELSE IF CAR PF EQ 'EXPT
- THEN IF DEPENDSP(CADR PF,VAR)
- THEN IF EQCAR(CADDR PF,'QUOTIENT)
- THEN IADD1 DEGREENEST(CADR PF,VAR)
- ELSE DEGREENEST(CADR PF,VAR)
- ELSE 0
- ELSE DEGREENESTL(CDR PF,VAR);
- SYMBOLIC PROCEDURE DEGREENESTL(U,VAR);
- %Returns max degreenest from list of pfs u.
- IF NULL U
- THEN 0
- ELSE MAX(DEGREENEST(CAR U,VAR),
- DEGREENESTL(CDR U,VAR));
- SYMBOLIC PROCEDURE SORTSQRTS(U,VAR);
- % Sorts list of sqrts into order required by hardsqrtsign
- % (and many other parts of the package).
- BEGIN
- SCALAR I,V;
- V:=MKVECT(10); %should be good enough!
- WHILE U DO <<
- I:=DEGREENEST(CAR U,VAR);
- IF I IEQUAL 0
- THEN INTERR "Non-dependent sqrt found";
- IF I > 10
- THEN INTERR
- "Degree of nesting exceeds 10 (recompile with 10 increased)";
- PUTV(V,I,(CAR U).GETV(V,I));
- U:=CDR U >>;
- U:=GETV(V,10);
- FOR I :=9 STEP -1 UNTIL 1 DO
- U:=NCONC(GETV(V,I),U);
- RETURN U
- END;
- SYMBOLIC PROCEDURE SQRTSIGN(SQRTS,X);
- IF NESTEDSQRTS THEN HARDSQRTSIGN(SORTSQRTS(SQRTS,X),LIST NIL)
- ELSE EASYSQRTSIGN(SQRTS,LIST NIL);
- ENDMODULE;
- END;
|