(* ---------------------------------------------------------------------------- * $Id: LINALG.mi,v 1.1 1994/03/11 15:21:46 pesch Exp $ * ---------------------------------------------------------------------------- * This file is part of MAS. * ---------------------------------------------------------------------------- * Copyright (c) 1993 Universitaet Passau * ---------------------------------------------------------------------------- * $Log: LINALG.mi,v $ * Revision 1.1 1994/03/11 15:21:46 pesch * Counting real roots of multivariate polynomials, Diplomarbeit F. Lippold * * ---------------------------------------------------------------------------- *) IMPLEMENTATION MODULE LINALG; (* Linear algebra implementation module *) (* Import lists and declarations *) FROM MASSTOR IMPORT LIST, SIL, COMP, INV, ADV, LENGTH, FIRST, LIST1, RED; FROM SACLIST IMPORT LELT, SUFFIX; FROM MASADOM IMPORT ADFI, ADPROD, ADSUM, ADSIGN, ADNEG, ADQUOT, ADWRIT; FROM SACI IMPORT ISUM, IQ, ISIGNF, INEG; FROM MASBIOS IMPORT BLINES, SWRITE; FROM LINALGI IMPORT IVSPROD, IMPROD; FROM LINALGRN IMPORT MTRANS; FROM MASI IMPORT IPROD; CONST rcsidi = "$Id: LINALG.mi,v 1.1 1994/03/11 15:21:46 pesch Exp $"; CONST copyrighti = "Copyright (c) 1993 Universitaet Passau"; (* ---------------------------------------------------------------------- *) (* Arbitrary domain linear algebra *) PROCEDURE ADUM(D,n: LIST): LIST; (* Arbitrary domain unit matrix. n is an integer. The (n x n) unit matrix of domain D is returned. *) VAR C,c,i,j,e: LIST; BEGIN C := SIL; i := 0; WHILE i < n DO c := SIL; i := i + 1; j := 0; WHILE j < n DO j := j + 1; IF i = j THEN e := ADFI(D,1) ELSE e := ADFI(D,0) END; c := COMP(e,c); END; c := INV(c); C := COMP(c,C); END; C := INV(C); RETURN(C); END ADUM; PROCEDURE ADVSPROD(D,A,B: LIST): LIST; (* Arbitrary domain vector scalar product. A and B are vectors of the domain D. The arbitrary domain value C = a1*b1 + ... + an*bn is returned. *) VAR a,b,c,C: LIST; BEGIN C := ADFI(D,0); WHILE A <> SIL DO ADV(A, a, A); ADV(B, b, B); c := ADPROD(a,b); C := ADSUM(c,C); END; RETURN(C); END ADVSPROD; PROCEDURE ADVSVPROD(A,b: LIST): LIST; (* Arbitrary domain vector scalar vector product. A is an arbitrary domain vector and b is a number of the same domain. The arbitrary domain vector C = (a1*b, ..., an*b) is returned. *) VAR a,c,C: LIST; BEGIN C := SIL; WHILE A <> SIL DO ADV(A, a, A); c := ADPROD(a,b); C := COMP(c,C); END; C := INV(C); RETURN(C); END ADVSVPROD; PROCEDURE ADVVSUM(A,B: LIST): LIST; (* Arbitrary domain vector vector sum. A and B are arbitrary domain vectors. The arbitrary domain vector C = (a1+b1, ..., an+bn) is returned. *) VAR a,b,c,C: LIST; BEGIN C := SIL; WHILE A <> SIL DO ADV(A, a, A); ADV(B, b, B); c := ADSUM(a,b); C := COMP(c,C); END; C := INV(C); RETURN(C); END ADVVSUM; PROCEDURE ADSMPROD(A,b: LIST): LIST; (* Arbitrary domain scalar and matrix product. A is a arbitrary domain matrix. b is a arbitrary domain number. The arbitrary domain matrix C = A * b is returned. *) VAR a,c,C: LIST; BEGIN IF A = SIL THEN RETURN(A) END; C := SIL; WHILE A <> SIL DO ADV(A, a, A); c := ADVSVPROD(a,b); C := COMP(c,C); END; C := INV(C); RETURN(C); END ADSMPROD; PROCEDURE ADMSUM(A,B: LIST): LIST; (* Arbitrary domain matrix sum. A and B are arbitrary domain matrices. The arbitrary domain matrix C = A + B is returned. *) VAR a,b,c,C: LIST; BEGIN IF A = SIL THEN RETURN(B) END; IF B = SIL THEN RETURN(A) END; C := SIL; WHILE A <> SIL DO ADV(A, a, A); ADV(B, b, B); c := ADVVSUM(a,b); C := COMP(c,C); END; C := INV(C); RETURN(C); END ADMSUM; PROCEDURE ADMPROD(D,A,B: LIST): LIST; (* Arbitrary domain matrix product. A and B are matrices of domain D. The matrix C = A * B of domain D is returned, if the number of columns of A is equal to the number of rows of B, otherwise the empty matrix is returned. *) VAR H1,H2,C,C1,a,c,BP,BT,b: LIST; BEGIN C := SIL; IF A = SIL THEN RETURN(C) END; IF B = SIL THEN RETURN(C) END; H1 := LENGTH(FIRST(A)); H2 := LENGTH(B); IF H1 <> H2 THEN RETURN(C) END; BT:=MTRANS(B); WHILE A <> SIL DO ADV(A, a, A); C1:=SIL; BP:=BT; WHILE BP <> SIL DO ADV(BP,b,BP); c:=ADVSPROD(D,a,b); C1:=COMP(c,C1); END; C1 := INV(C1); C := COMP(C1,C); END; C := INV(C); RETURN(C); END ADMPROD; PROCEDURE ADVWRITE(A: LIST); (* Arbitrary domain vector write. A is an arbitrary domain vector. A is written to the output stream. *) VAR a : LIST; BEGIN SWRITE("("); WHILE A <> SIL DO ADV(A, a, A); ADWRIT(a); IF A <> SIL THEN SWRITE(",") END; END; SWRITE(")"); END ADVWRITE; PROCEDURE ADMWRITE(A: LIST); (*Arbitrary domain matrix write. A is an arbitrary domain matrix. A is written to the output stream. *) VAR a : LIST; BEGIN BLINES(0); SWRITE("("); WHILE A <> SIL DO ADV(A, a, A); ADVWRITE(a); IF A <> SIL THEN SWRITE(", "); BLINES(0) END; END; SWRITE(")"); BLINES(0); END ADMWRITE; PROCEDURE ADMTRACE(D,A: LIST): LIST; (* Arbitrary domain matrix trace. A is a matrix of domain D. The trace of A is returned. *) VAR tr,i,a: LIST; BEGIN tr := ADFI(D,0); i := 0; WHILE A <> SIL DO ADV(A,a,A); i := i + 1; tr := ADSUM(tr,LELT(a,i)); END; RETURN(tr); END ADMTRACE; PROCEDURE ADMPTRACE(D,A,B: LIST): LIST; (* Arbitrary domain matrix product trace. A and B are matrices of domain D. The trace of A*B is returned. *) VAR tr,a,b,H1,H2,BT: LIST; BEGIN tr := ADFI(D,0); IF (A = SIL) OR (B = SIL) THEN RETURN(tr) END; H1 := LENGTH(FIRST(A)); H2 := LENGTH(B); IF H1 <> H2 THEN RETURN(tr) END; BT:=MTRANS(B); WHILE A <> SIL DO ADV(A, a, A); ADV(BT,b,BT); tr := ADSUM(tr,ADVSPROD(D,a,b)); END; RETURN(tr); END ADMPTRACE; PROCEDURE ADCHARPOL(D,Q: LIST): LIST; (* Arbitrary domain characteristic polynomial. Q is a p x p Matrix of domain D. The list al=(a(0),...,a(p)) is created such that a(i) from D is the coefficient of X^(p-i) in det(XE-Q). *) VAR L,l,A,B,sl,s,al,a,k,p: LIST; BEGIN al := LIST1(ADFI(D,1)); IF Q = SIL THEN RETURN(al) END; p := LENGTH(Q); L := SIL; A := Q; k := 1; s := ADMTRACE(D,A); sl := LIST1(s); a := ADNEG(s); al := SUFFIX(al,a); WHILE k*k < p DO k := k+1; L := COMP(A,L); A := ADMPROD(D,A,Q); s := ADMTRACE(D,A); sl := COMP(s,sl); a := ADQUOT(ADVSPROD(D,sl,al), ADFI(D,-k)); al := SUFFIX(al,a); END; B := A; L := INV(L); l := L; WHILE k < p DO k := k+1; IF l = SIL THEN B := ADMPROD(D,B,A); s := ADMTRACE(D,B); l := L; ELSE s := ADMPTRACE(D,B,FIRST(l)); l := RED(l); END; sl := COMP(s,sl); a := ADQUOT(ADVSPROD(D,sl,al), ADFI(D,-k)); al := SUFFIX(al,a); END; RETURN(al); END ADCHARPOL; PROCEDURE ADSIG(D,Q: LIST): LIST; (* Arbitrary domain signature. Q is a symmetric p x p Matrix of domain D. The signature of Q ist returned. ADCHARPOL is used. *) VAR al,p,n,a,s,sp,sn,t: LIST; BEGIN p := 0; n := 0; al := ADCHARPOL(D,Q); ADV(al,a,al); sp := ADSIGN(a); sn := sp; t := 1; WHILE al <> SIL DO ADV(al,a,al); t := -t; s := ADSIGN(a); IF s <> 0 THEN IF sp <> s THEN p := p + 1; sp := s END; IF sn <> s*t THEN n := n + 1; sn := s*t END; END; END; RETURN(p-n); END ADSIG; (* ---------------------------------------------------------------------- *) (* Integer linear algebra *) PROCEDURE IMTRACE(A: LIST): LIST; (* Integral matrix trace. A is an integral matrix. The trace of A is returned. *) VAR tr,i,a: LIST; BEGIN tr := 0; i := 0; WHILE A <> SIL DO ADV(A,a,A); i := i + 1; tr := ISUM(tr,LELT(a,i)); END; RETURN(tr); END IMTRACE; PROCEDURE IMPTRACE(A,B: LIST): LIST; (* Integral matrix product trace. A and B are integral matrices. The trace of the matrix A*B is returned. *) VAR tr,a,b,H1,H2,BT: LIST; BEGIN tr := 0; IF (A = SIL) OR (B = SIL) THEN RETURN(tr) END; H1 := LENGTH(FIRST(A)); H2 := LENGTH(B); IF H1 <> H2 THEN RETURN(tr) END; BT:=MTRANS(B); WHILE A <> SIL DO ADV(A, a, A); ADV(BT,b,BT); tr := ISUM(tr,IVSPROD(a,b)); END; RETURN(tr); END IMPTRACE; PROCEDURE ICHARPOL(Q: LIST): LIST; (* Integral matrix characteristic polynomial. Q is an integral p x p Matrix. The list al = (a(0),...,a(p)) of integers is created with a(i) is the coefficient of X^(p-i) in det(XE-Q). *) VAR L,l,A,B,sl,s,al,a,k,p: LIST; BEGIN al := LIST1(1); IF Q = SIL THEN RETURN(al) END; p := LENGTH(Q); L := SIL; A := Q; k := 1; s := IMTRACE(A); sl := LIST1(s); a := INEG(s); al := SUFFIX(al,a); WHILE k*k < p DO k := k+1; L := COMP(A,L); A := IMPROD(A,Q); s := IMTRACE(A); sl := COMP(s,sl); a := IQ(IVSPROD(sl,al),-k); al := SUFFIX(al,a); END; B := A; L := INV(L); l := L; WHILE k < p DO k := k+1; IF l = SIL THEN B := IMPROD(B,A); s := IMTRACE(B); l := L; ELSE s := IMPTRACE(B,FIRST(l)); l := RED(l); END; sl := COMP(s,sl); a := IQ(IVSPROD(sl,al),-k); al := SUFFIX(al,a); END; RETURN(al); END ICHARPOL; PROCEDURE ISIG(Q: LIST): LIST; (* Integral matrix signature. Q is a symmetric integral p x p Matrix. The signature of Q ist returned. ICHARPOL is used *) VAR al,p,n,a,s,sp,sn,t: LIST; BEGIN p := 0; n := 0; al := ICHARPOL(Q); ADV(al,a,al); sp := ISIGNF(a); sn := sp; t := 1; WHILE al <> SIL DO ADV(al,a,al); t := -t; s := ISIGNF(a); IF s <> 0 THEN IF sp <> s THEN p := p + 1; sp := s END; IF sn <> s*t THEN n := n + 1; sn := s*t END; END; END; RETURN(p-n); END ISIG; PROCEDURE IMRTPROD(A,B: LIST): LIST; (* Integral matrix right tensor product. A and B are integral matrices. The matrix C is constructed by replacing every entry a(i,j) of A by the matrix a(i,j)*B. *) VAR C,c,a,ar,ars,Bs,b,br,brs: LIST; BEGIN C := SIL; IF (A = SIL) OR (B = SIL) THEN RETURN(C) END; WHILE A <> SIL DO ADV(A,ar,A); Bs := B; WHILE Bs <> SIL DO ADV(Bs,br,Bs); c := SIL; ars := ar; WHILE ars <> SIL DO ADV(ars,a,ars); brs := br; WHILE brs <> SIL DO ADV(brs,b,brs); c := COMP(IPROD(a,b),c); END; END; c := INV(c); C := COMP(c,C); END; END; C := INV(C); RETURN(C); END IMRTPROD; END LINALG. (* -EOF- *)