(* ---------------------------------------------------------------------------- * $Id: SACRPOL.mi,v 1.3 1992/10/15 16:28:44 kredel Exp $ * ---------------------------------------------------------------------------- * This file is part of MAS. * ---------------------------------------------------------------------------- * Copyright (c) 1989 - 1992 Universitaet Passau * ---------------------------------------------------------------------------- * $Log: SACRPOL.mi,v $ * Revision 1.3 1992/10/15 16:28:44 kredel * Changed rcsid variable * * Revision 1.2 1992/02/12 17:34:05 pesch * Moved CONST definition to the right place * * Revision 1.1 1992/01/22 15:14:20 kredel * Initial revision * * ---------------------------------------------------------------------------- *) IMPLEMENTATION MODULE SACRPOL; (* SAC Rational Polynomial Implementation Module. *) (* Import lists and declarations. *) FROM MASELEM IMPORT MASMIN, MASMAX; FROM MASSTOR IMPORT LIST, SIL, BETA, FIRST, RED, SRED, COMP, INV, ADV, LIST1; FROM SACLIST IMPORT AREAD, LIST2, COMP2, ADV2, SUFFIX, CLOUT, CINV, RED2, SECOND, EQUAL; FROM MASBIOS IMPORT CREAD, CREADB, CWRITE, BKSP, DIBUFF, LETTER, DIGIT, MASORD, BLINES, SWRITE; FROM SACI IMPORT IWRITE; FROM SACRN IMPORT RNWRIT, RNREAD, RNSUM, RNQ, RNPROD, RNSIGN, RNINT, RNDIF, RNNEG; FROM SACPOL IMPORT VREAD, PDEG, PLDCF, PRED; CONST rcsidi = "$Id: SACRPOL.mi,v 1.3 1992/10/15 16:28:44 kredel Exp $"; CONST copyrighti = "Copyright (c) 1989 - 1992 Universitaet Passau"; PROCEDURE RPDIF(RL,A,B: LIST): LIST; (*Rational polynomial difference. A and B are rational polynomials in r variables, r ge 0. C=A-B.*) VAR AL, AP, BL, BP, C, CL, CP, CPP, EL, FL, RLP: LIST; BEGIN (*1*) (*a or b zero.*) IF A = 0 THEN C:=RPNEG(RL,B); RETURN(C); END; IF B = 0 THEN C:=A; RETURN(C); END; (*2*) (*rl=0.*) IF RL = 0 THEN C:=RNDIF(A,B); RETURN(C); END; (*3*) (*general case.*) AP:=A; BP:=B; CP:=BETA; RLP:=RL-1; REPEAT EL:=FIRST(AP); FL:=FIRST(BP); IF EL > FL THEN ADV2(AP, EL,AL,AP); CP:=COMP2(AL,EL,CP); ELSE IF EL < FL THEN ADV2(BP, FL,BL,BP); IF RLP = 0 THEN CL:=RNNEG(BL); ELSE CL:=RPNEG(RLP,BL); END; CP:=COMP2(CL,FL,CP); ELSE ADV2(AP, EL,AL,AP); ADV2(BP, FL,BL,BP); IF RLP = 0 THEN CL:=RNDIF(AL,BL); ELSE CL:=RPDIF(RLP,AL,BL); END; IF CL <> 0 THEN CP:=COMP2(CL,EL,CP); END; END; END; UNTIL (AP = SIL) OR (BP = SIL); (*4*) (*finish.*) IF (AP = SIL) AND (BP = SIL) THEN CPP:=BETA; ELSE IF AP = SIL THEN CPP:=RPNEG(RL,BP); ELSE CPP:=AP; END; END; C:=INV(CP); IF C = SIL THEN C:=CPP; ELSE SRED(CP,CPP); END; IF C = SIL THEN C:=0; END; RETURN(C); (*7*) END RPDIF; PROCEDURE RPEMV(RL,A,BL: LIST): LIST; (*Rational polynomial evaluation, main variable. A is a rational polynomial in r variables, r gt 0. b is a rational number. C(x(1), ...,x(r-1))=A(x(1), ...,x(r-1),b).*) VAR AL, AP, C, EL, ELP, IL, RLP: LIST; BEGIN (*1*) (*a=0.*) IF A = 0 THEN C:=0; RETURN(C); END; (*2*) (*horner method.*) AP:=A; C:=0; RLP:=RL-1; REPEAT ADV2(AP, EL,AL,AP); IF AP = SIL THEN ELP:=0; ELSE ELP:=FIRST(AP); END; C:=RPSUM(RLP,C,AL); FOR IL:=1 TO EL-ELP DO C:=RPRNP(RLP,BL,C); END; UNTIL AP = SIL; RETURN(C); (*5*) END RPEMV; PROCEDURE RPFIP(RL,A: LIST): LIST; (*Rational polynomial from integral polynomial. A is an integral polynomial in r variables, r ge 0.*) VAR AL, AP, B, BL, EL, RLP: LIST; BEGIN (*1*) (*a=0.*) IF A = 0 THEN B:=0; RETURN(B); END; (*2*) (*rl=0.*) IF RL = 0 THEN B:=RNINT(A); RETURN(B); END; (*3*) (*recursion on rl.*) B:=BETA; AP:=A; RLP:=RL-1; REPEAT ADV2(AP, EL,AL,AP); BL:=RPFIP(RLP,AL); B:=COMP2(BL,EL,B); UNTIL AP = SIL; B:=INV(B); RETURN(B); (*6*) END RPFIP; PROCEDURE RPIMV(RL,A: LIST): LIST; (*Rational polynomial integration, main variable. A is a rational polynomial in r variables, r gt 0. B is the integral of A with respect to its main variable. The constant of integration is 0.*) VAR AL, AP, B, BL, EL, ELP, ELS, RLP: LIST; BEGIN (*1*) (*a=0.*) IF A = 0 THEN B:=0; RETURN(B); END; (*2*) (*a ne 0.*) AP:=A; RLP:=RL-1; B:=BETA; REPEAT ADV2(AP, EL,AL,AP); ELP:=EL+1; ELS:=LIST2(1,ELP); BL:=RPRNP(RLP,ELS,AL); B:=COMP2(BL,ELP,B); UNTIL AP = SIL; B:=INV(B); RETURN(B); (*5*) END RPIMV; PROCEDURE RPNEG(RL,A: LIST): LIST; (*Rational polynomial negative. A is an rational polynomial in r variables, r ge 0. B=-A.*) VAR AL, AP, B, BL, EL, RLP: LIST; BEGIN (*1*) (*a=0.*) IF A = 0 THEN B:=0; RETURN(B); END; (*2*) (*rl=0.*) IF RL = 0 THEN B:=RNNEG(A); RETURN(B); END; (*3*) (*general case.*) AP:=A; B:=BETA; RLP:=RL-1; REPEAT ADV2(AP, EL,AL,AP); IF RLP = 0 THEN BL:=RNNEG(AL); ELSE BL:=RPNEG(RLP,AL); END; B:=COMP2(BL,EL,B); UNTIL AP = SIL; B:=INV(B); RETURN(B); (*6*) END RPNEG; PROCEDURE RPPROD(RL,A,B: LIST): LIST; (*Rational polynomial product. A and B are rational polynomials in r variables, r ge 0. C=A*B.*) VAR AL, AP, AS, BL, BS, C, C1, CL, EL, FL, J1Y, RLP: LIST; BEGIN (*1*) (*a or b zero.*) IF (A = 0) OR (B = 0) THEN C:=0; RETURN(C); END; (*2*) (*rl=0.*) IF RL = 0 THEN C:=RNPROD(A,B); RETURN(C); END; (*3*) (*general case.*) AS:=CINV(A); BS:=CINV(B); C:=0; RLP:=RL-1; REPEAT ADV2(BS, BL,FL,BS); AP:=AS; C1:=BETA; REPEAT ADV2(AP, AL,EL,AP); IF RLP = 0 THEN CL:=RNPROD(AL,BL); ELSE CL:=RPPROD(RLP,AL,BL); END; J1Y:=EL+FL; C1:=COMP2(J1Y,CL,C1); UNTIL AP = SIL; C:=RPSUM(RL,C,C1); UNTIL BS = SIL; RETURN(C); (*6*) END RPPROD; PROCEDURE RPQR(RL,A,B: LIST; VAR Q,R: LIST); (*Rational polynomial quotient and remainder. A and B are rational polynomials in r variables with B non-zero. Q and R are the unique rational polynomials such that either B divides A, Q=A/B and R=0 or else B does not divide A and A=BQ+R with DEG(R) minimal.*) VAR AL, BL, BP, DL, ML, NL, Q1, QL, QP, RLP, RP, SL: LIST; BEGIN (*1*) (*initialize.*) NL:=PDEG(B); BL:=PLDCF(B); BP:=PRED(B); Q:=BETA; R:=A; RLP:=RL-1; (*2*) (*compute quotient terms.*) WHILE R <> 0 DO ML:=PDEG(R); DL:=ML-NL; IF DL < 0 THEN (*go to 3;*) IF Q = SIL THEN Q:=0; ELSE Q:=INV(Q); END; RETURN; END; AL:=PLDCF(R); IF RLP = 0 THEN QL:=RNQ(AL,BL); SL:=0; ELSE RPQR(RLP,AL,BL, QL,SL); END; IF SL <> 0 THEN (*go to 3;*) IF Q = SIL THEN Q:=0; ELSE Q:=INV(Q); END; RETURN; END; Q:=COMP2(QL,DL,Q); Q1:=LIST2(DL,QL); RP:=PRED(R); QP:=RPPROD(RL,BP,Q1); R:=RPDIF(RL,RP,QP); END; (*3*) (*finish.*) IF Q = SIL THEN Q:=0; ELSE Q:=INV(Q); END; RETURN; (*6*) END RPQR; PROCEDURE RPREAD( VAR RL,A,V: LIST); (*Rational polynomial read. The rational polynomial A is read from the input stream. r ge 0 is the number of variables of A and V is the variable list of A. Any number of preceding blanks are skipped.*) VAR AL, C, EL, IDUM, RLP, VL: LIST; BEGIN (*1*) (*rl=0.*) C:=CREADB(); IF C <> MASORD("(") THEN BKSP; A:=RNREAD(); RL:=0; V:=BETA; RETURN; END; (*2*) (*rl gt 0.*) A:=BETA; LOOP C:=CREADB(); IF C = MASORD(")") THEN (*go to 4;*) EXIT END; BKSP; RPREAD(RLP,AL,V); C:=CREADB(); IF C <> MASORD("*") THEN (*go to 3;*) SWRITE("error found by RPREAD."); DIBUFF; EXIT END; VL:=VREAD(); C:=CREADB(); IF C <> MASORD("*") THEN (*go to 3;*) SWRITE("error found by RPREAD."); DIBUFF; EXIT END; C:=CREAD(); IF C <> MASORD("*") THEN (*go to 3;*) SWRITE("error found by RPREAD."); DIBUFF; EXIT END; EL:=AREAD(); A:=COMP2(AL,EL,A); C:=CREADB(); IF C = MASORD(")") THEN (*go to 4;*) EXIT ELSE IF C = MASORD("-") THEN BKSP; ELSE IF C <> MASORD("+") THEN (*go to 3;*) SWRITE("error found by RPREAD."); DIBUFF; EXIT END; END; END; END; (*3 (*error.*) SWRITE("error found by RPREAD."); DIBUFF; *) (*4*) (*finish.*) A:=INV(A); RL:=RLP+1; V:=SUFFIX(V,VL); RETURN; (*7*) END RPREAD; PROCEDURE RPRNP(RL,AL,B: LIST): LIST; (*Rational polynomial rational number product. B is a rational polynomial in r variables, r ge 0. a is a rational number. C=a*B.*) VAR BL, BP, C, CL, EL, RLP: LIST; BEGIN (*1*) (*al=0 or b=0.*) IF (AL = 0) OR (B = 0) THEN C:=0; RETURN(C); END; (*2*) (*rl=0.*) IF RL = 0 THEN C:=RNPROD(AL,B); RETURN(C); END; (*3*) (*general case.*) C:=BETA; BP:=B; RLP:=RL-1; REPEAT ADV2(BP, EL,BL,BP); CL:=RPRNP(RLP,AL,BL); C:=COMP2(CL,EL,C); UNTIL BP = SIL; C:=INV(C); RETURN(C); (*6*) END RPRNP; PROCEDURE RPSUM(RL,A,B: LIST): LIST; (*Rational polynomial sum. A and B are rational polynomials in r variables, r ge 0. C=A+B.*) VAR AL, AP, BL, BP, C, CL, CP, EL, FL, RLP: LIST; BEGIN (*1*) (*a=0 or b=0.*) IF A = 0 THEN C:=B; RETURN(C); END; IF B = 0 THEN C:=A; RETURN(C); END; (*2*) (*rl=0.*) IF RL = 0 THEN C:=RNSUM(A,B); RETURN(C); END; (*3*) (*match coefficients.*) AP:=A; BP:=B; CP:=BETA; RLP:=RL-1; REPEAT EL:=FIRST(AP); FL:=FIRST(BP); IF EL > FL THEN ADV2(AP, EL,AL,AP); CP:=COMP2(AL,EL,CP); ELSE IF EL < FL THEN ADV2(BP, FL,BL,BP); CP:=COMP2(BL,FL,CP); ELSE ADV2(AP, EL,AL,AP); ADV2(BP, FL,BL,BP); IF RLP = 0 THEN CL:=RNSUM(AL,BL); ELSE CL:=RPSUM(RLP,AL,BL); END; IF CL <> 0 THEN CP:=COMP2(CL,EL,CP); END; END; END; UNTIL (AP = SIL) OR (BP = SIL); (*4*) (*finish.*) IF AP = SIL THEN AP:=BP; END; IF CP = SIL THEN C:=AP; ELSE C:=INV(CP); SRED(CP,AP); END; IF C = SIL THEN C:=0; END; RETURN(C); (*7*) END RPSUM; PROCEDURE RPWRIT(RL,A,V: LIST); (*Rational polynomial write. A is a rational polynomial in r variables, r ge 0. V is a variable list for A. A is written in the output stream in external canonical form.*) VAR AL, AP, EL, IL, RLP, V1, VB, VP: LIST; BEGIN (*1*) (*rl=0 or a=0.*) IF (RL = 0) OR (A = 0) THEN IWRITE(A); RETURN; END; (*2*) (*a ne 0.*) SWRITE("("); AP:=A; RLP:=RL-1; VB:=CINV(V); ADV(VB, V1,VP); VP:=INV(VP); IL:=0; REPEAT ADV2(AP, EL,AL,AP); IF (IL <> 0) AND ((RL > 1) OR (RNSIGN(AL) > 0)) THEN SWRITE("+"); END; IF RLP = 0 THEN RNWRIT(AL); ELSE RPWRIT(RLP,AL,VP); END; SWRITE("*"); CLOUT(V1); SWRITE("*"); SWRITE("*"); IWRITE(EL); IL:=1; UNTIL AP = SIL; SWRITE(")"); RETURN; (*5*) END RPWRIT; END SACRPOL. (* -EOF- *)