ð¹Syntax10.Scn.FntSyntax10i.Scn.Fnt‹Syntax10b.Scn.Fnt 3ÿÿÿÿ€8ÀÔFoldElemsNew«ÿÿÿÿ€8ÀÔ 8ÿÿÿÿ€8ÀÔE!Jÿÿÿÿ€8ÀÔ 8ÿÿÿÿ€8ÀÔŽÿÿÿÿ€8ÀÔ 8ÿÿÿÿ€8ÀÔÂÿÿÿÿ€8ÀÔ  4ÿÿÿÿ€8ÀÔ:ÿÿÿÿ€8ÀÔ /ÿÿÿÿ€8ÀÔ'ÿÿÿÿ€8ÀÔ  4ÿÿÿÿ€8ÀÔtÿÿÿÿ€8ÀÔZÿÿÿÿ€8ÀÔVÿÿÿÿ€8ÀÔIÿÿÿÿ€8ÀÔ’ÿÿÿÿ€8ÀÔ  Eÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔ  Uÿÿÿÿ€8ÀÔQÿÿÿÿ€8ÀÔ Aÿÿÿÿ€8ÀÔnÿÿÿÿ€8ÀÔ <ÿÿÿÿ€8ÀÔVÿÿÿÿ€8ÀÔ 2ÿÿÿÿ€8ÀÔ>ÿÿÿÿ€8ÀÔôMODULE MatrixL; (* JFS 05/01/99 Version 0.1 *) IMPORT Out; VAR Status: INTEGER; Line, Row, Line1, Line2, Row1, Row2, Index: LONGINT; Buffer: LONGREAL; DimMatch: BOOLEAN; PROCEDURE ScalMult* (VAR M: ARRAY OF ARRAY OF LONGREAL; K: LONGREAL);  BEGIN Line1 := LEN(M, 0); Row1 := LEN(M, 1); FOR Line := 0 TO Line1 - 1 DO FOR Row := 0 TO Row1 - 1 DO M[Line, Row] := K * M[Line, Row] END; END END ScalMult;  PROCEDURE Add* (VAR M1, M2, R : ARRAY OF ARRAY OF LONGREAL): BOOLEAN;  BEGIN DimMatch := FALSE; Line1 := LEN(M1, 0); Line2 := LEN(M2, 0); Row1 := LEN(M1, 1); Row2 := LEN(M2, 1); IF (Line1 = Line2) & (Line2 = LEN(R, 0)) & (Row1 = Row2) & (Row2 = LEN(R, 1)) THEN DimMatch := TRUE; FOR Line := 0 TO Line1 - 1 DO FOR Row := 0 TO Row1 - 1 DO Buffer := M1[Line][Row] + M2[Line][Row]; (*Well known limitation of iOP2*) R[Line][Row] := Buffer END; END END; RETURN DimMatch END Add;  PROCEDURE Sub* (VAR M1, M2, R : ARRAY OF ARRAY OF LONGREAL): BOOLEAN;  BEGIN DimMatch := FALSE; Line1 := LEN(M1, 0); Line2 := LEN(M2, 0); Row1 := LEN(M1, 1); Row2 := LEN(M2, 1); IF (Line1 = Line2) & (Line2 = LEN(R, 0)) & (Row1 = Row2) & (Row2 = LEN(R, 1)) THEN DimMatch := TRUE; FOR Line := 0 TO Line1 - 1 DO FOR Row := 0 TO Row1 - 1 DO Buffer := M1[Line][Row] - M2[Line][Row]; R[Line][Row] := Buffer END; END END; RETURN DimMatch END Sub;  PROCEDURE Mult* (VAR M1, M2, R : ARRAY OF ARRAY OF LONGREAL): BOOLEAN;  VAR i, j, k: LONGINT; BEGIN DimMatch := FALSE; Line1 := LEN(M1, 0); Line2 := LEN(M2, 0); Row1 := LEN(M1, 1); Row2 := LEN(M2, 1); IF (Row1 = Line2) & (LEN(R, 0) = Line1) & (LEN(R, 1) = Row2) THEN DimMatch := TRUE; FOR i := 0 TO Line1 - 1 DO FOR j := 0 TO Row2 - 1 DO Buffer := 0; FOR k := 0 TO Row1 - 1 DO Buffer := Buffer + M1[i, k] * M2[k, j] END; R[i, j] := Buffer END; END END; RETURN DimMatch END Mult;  PROCEDURE Transpose* (VAR M1, R : ARRAY OF ARRAY OF LONGREAL): BOOLEAN;  BEGIN DimMatch := FALSE; Line1 := LEN(M1, 0); Line2 := LEN(R, 0); Row1 := LEN(M1, 1); Row2 := LEN(R, 1); IF (Line1 = Row2) & (Line2 = Row1) THEN DimMatch := TRUE; FOR Line := 0 TO Line1 - 1 DO FOR Row := 0 TO Row1 - 1 DO R[Row, Line] := M1[Line, Row] END END; END; RETURN DimMatch END Transpose;  PROCEDURE Unity* (VAR R: ARRAY OF ARRAY OF LONGREAL): BOOLEAN;  BEGIN DimMatch := FALSE; Line1 := LEN(R, 0); Row1 := LEN(R, 1); IF Line1 = Row1 THEN DimMatch := TRUE; FOR Line := 0 TO Line1 - 1 DO FOR Row := 0 TO Row1 - 1 DO IF Line = Row THEN R[Line, Row] := 1.D0 ELSE R[Line, Row] := 0.D0 END END; END END; RETURN DimMatch END Unity;  PROCEDURE Display* (VAR M: ARRAY OF ARRAY OF LONGREAL; Acc: INTEGER);  VAR NbElmnt: LONGINT; BEGIN Line1 := LEN(M, 0); Row1 := LEN(M, 1); NbElmnt := Line1 * Row1; Index := 0; Out.Ln; WHILE (Index < NbElmnt) DO IF (Index MOD Row1 = 0) THEN Out.Ln; Out.String("Line: "); Out.Int(Index DIV Row1, 5); Out.Ln END; Out.LongReal(M[Index DIV Row1, Index MOD Row1], Acc); Out.String(" "); INC(Index) END; END Display;  PROCEDURE Find (VAR M: ARRAY OF ARRAY OF LONGREAL; Rinit: LONGINT; VAR Lswap: LONGINT);  BEGIN WHILE (Lswap < Line1 - 1) & (M[Lswap, Rinit] = 0) DO INC(Lswap) END END Find;  PROCEDURE Swap (VAR M: ARRAY OF ARRAY OF LONGREAL; Up, Down: LONGINT);  BEGIN FOR Index := 0 TO LEN(M, 1) - 1 DO Buffer := M[Up, Index]; M[Up, Index] := M[Down, Index]; M[Down, Index] := Buffer END; END Swap;  PROCEDURE GaussMod* (VAR A, R: ARRAY OF ARRAY OF LONGREAL; VAR Rank: INTEGER): BOOLEAN;  VAR i, j, k, Lswap: LONGINT; Pivot, PseudoPivot: LONGREAL; BEGIN Rank := 0; DimMatch := FALSE; Line1 := LEN(A, 0); Row1 := LEN(A, 1); Line2 := LEN(R, 0); Row2 := LEN(R, 1); IF (Row1 = Line2) THEN DimMatch := TRUE END; IF DimMatch THEN FOR k := 0 TO Line1 - 1 DO IF A[k, k] = 0 THEN Lswap := k; Find(A, k, Lswap); Swap(A, k, Lswap); Swap(R, k, Lswap) END; IF A[k, k] = 0 THEN RETURN FALSE ELSE INC(Rank); Pivot := 1.D+0 / A[k, k]; A[k, k] := 1.D+0; FOR j := k + 1 TO Row1 - 1 DO A[k, j] := A[k, j] * Pivot END; FOR j := 0 TO Row2 - 1 DO R[k, j] := R[k, j] * Pivot END; FOR i := 0 TO Line1 - 1 DO IF (i # k) THEN PseudoPivot := A[i, k]; A[i, k] := 0.D+0; FOR j := k + 1 TO Row1 - 1 DO Buffer := PseudoPivot * A[k, j]; A[i, j] := A[i, j] - Buffer END; FOR j := 0 TO Row2 - 1 DO Buffer := PseudoPivot * R[k, j]; R[i, j] := R[i, j] - Buffer END; END END; END END; ELSE END; RETURN DimMatch END GaussMod;  PROCEDURE Determinant* (VAR A: ARRAY OF ARRAY OF LONGREAL; VAR Det: LONGREAL; VAR Rank: LONGINT): BOOLEAN;  VAR i, j, k, Lswap: LONGINT; Pivot, PseudoPivot: LONGREAL; BEGIN Line1 := LEN(A, 0); Row1 := LEN(A, 1); Rank := 0; Det := 0.D+0; IF Line1 = Row1 THEN DimMatch := TRUE; Det := 1.D+0; FOR k := 0 TO Line1 - 1 DO IF A[k, k] = 0 THEN Lswap := k; Find(A, k, Lswap); Swap(A, k, Lswap); Det := - Det END; IF A[k, k] = 0 THEN Det := 0; RETURN FALSE ELSE Det := Det * A[k, k]; INC(Rank); Pivot := 1.D+0 / A[k, k]; A[k, k] := 1.D+0; FOR j := k + 1 TO Row1 - 1 DO A[k, j] := A[k, j] * Pivot END; FOR i := k + 1 TO Line1 - 1 DO PseudoPivot := A[i, k]; A[i, k] := 0.D+0; FOR j := k + 1 TO Row1 - 1 DO Buffer := PseudoPivot * A[k, j]; A[i, j] := A[i, j] - Buffer END; END END; END ELSE DimMatch := FALSE END; RETURN DimMatch END Determinant;  PROCEDURE Invert* (VAR A, R: ARRAY OF ARRAY OF LONGREAL; Rank: INTEGER): BOOLEAN;  BEGIN DimMatch := Unity(R); IF DimMatch THEN RETURN GaussMod(A, R, Rank) END; RETURN DimMatch END Invert;  PROCEDURE PseudoInvert* (VAR A, At, P, I, R: ARRAY OF ARRAY OF LONGREAL): BOOLEAN;  VAR Rank: INTEGER; BEGIN DimMatch := FALSE; IF LEN(A, 0) >= LEN(A, 1) THEN DimMatch := TRUE END; IF DimMatch THEN DimMatch := Transpose(A, At) END; IF DimMatch THEN DimMatch := Mult(At, A, P) END; IF DimMatch THEN DimMatch := Invert(P, I, Rank) END; IF DimMatch THEN DimMatch := Mult(I, At, R) END; RETURN DimMatch END PseudoInvert;  PROCEDURE Copy* (VAR A, B: ARRAY OF ARRAY OF LONGREAL): BOOLEAN;  VAR i, j: LONGINT; BEGIN Line1 := LEN(A, 0); Line2 := LEN(B, 0); Row1 := LEN(A, 1); Row2 := LEN(B, 1); DimMatch := FALSE; IF (Line1 = Line2) & (Row1 = Row2) THEN DimMatch := TRUE; FOR i := 0 TO Line1 - 1 DO FOR j := 0 TO Row1 - 1 DO B[i, j] := A[i, j] END; END END; RETURN DimMatch END Copy;  END MatrixL.