home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* DETTOOL.PAS *)
- (* (c) 1991 Jens Burmeister & TOOLBOX *)
- (* ------------------------------------------------------ *)
- UNIT DetTool;
-
- INTERFACE
-
- TYPE
- RealMatrixPtr = ^RealMatrix;
- RealMatrix = OBJECT
- Dim,
- RowSize,
- ColSize,
- RealSize : WORD;
- Buf : Pointer;
-
- CONSTRUCTOR Init(N : WORD );
- DESTRUCTOR Done; VIRTUAL;
- FUNCTION GetDimension : WORD;
- FUNCTION GetValue(i, j : WORD) : REAL;
- PROCEDURE SetValue(i, j : WORD; Value : REAL);
- FUNCTION Determinant : REAL;
- END;
-
- IMPLEMENTATION
-
- CONST
- MaxNrOfPtrs = 65520 DIV SizeOf(Pointer);
- MaxNrOfReals = 65520 DIV SizeOf(REAL);
-
- TYPE
- Pointers = ARRAY [1..MaxNrOfPtrs] OF Pointer;
- Reals = ARRAY [1..MaxNrOfReals] OF REAL;
-
- CONSTRUCTOR RealMatrix.Init(N : WORD);
- VAR
- i : WORD;
- BEGIN
- Dim := N;
- RealSize := SizeOf(REAL);
- ColSize := Dim * SizeOf(Pointer);
- RowSize := Dim * RealSize;
-
- GetMem(Buf, ColSize);
- FOR i := 1 TO GetDimension DO BEGIN
- GetMem(Pointers(Buf^)[i], RowSize);
- FillChar(Pointers(Buf^)[i]^, RowSize, 0);
- END;
- END;
-
- DESTRUCTOR RealMatrix.Done;
- VAR
- i : WORD;
- BEGIN
- FOR i := GetDimension DOWNTO 1 DO
- FreeMem(Pointers(Buf^)[i], RowSize);
- FreeMem(Buf, ColSize);
- END;
-
- FUNCTION RealMatrix.GetDimension : WORD;
- BEGIN
- GetDimension := Dim;
- END;
-
- FUNCTION RealMatrix.GetValue(i, j : WORD) : REAL;
- VAR
- Value : REAL;
- BEGIN
- Move(Reals(Pointers(Buf^)[i]^)[j], Value, RealSize);
- GetValue := Value;
- END;
-
- PROCEDURE RealMatrix.SetValue(i,j : WORD; Value : REAL);
- BEGIN
- Move(Value, Reals(Pointers(Buf^)[i]^)[j], RealSize);
- END;
-
- FUNCTION RealMatrix.Determinant : REAL;
- CONST
- Tol = 1.0e-16;
- VAR
- i, j, k, N : WORD;
- Beta, Diag,
- r, s, Sum,
- Sigma, Det : REAL;
- Singular : BOOLEAN;
-
- { Die Matrix wird mit HOUSEHOLDER - Transformationen }
- { auf Dreiecksgestalt gebracht. Die Originalelemente }
- { werden überschrieben. Die Determinante ist danach }
- { das Produkt der Diagonalelemente multipliziert mit }
- { dem Faktor (-1)**(n-1). (n=Dimension der Matrix) }
-
- BEGIN
- N := GetDimension;
- Det := 1.0;
- Singular := FALSE;
- i := 0;
- REPEAT
- Inc(i);
- Sum := 0.0;
- FOR j := i TO N DO
- Sum := Sum + Sqr(GetValue(i, j));
- Sigma := Sqrt(Sum);
- IF Sigma > Tol THEN BEGIN
- IF GetValue(i, i) < 0 THEN
- Sigma := -Sigma;
- r := Sigma + GetValue(i, i);
- Beta := 1.0 / (Sigma * r);
- Diag := -Sigma;
- SetValue(i, i, r);
- FOR j := i+1 TO N DO BEGIN
- Sum := 0.0;
- FOR k := i TO N DO
- Sum := Sum + GetValue(j, k) * GetValue(i, k);
- Sum := Sum * Beta;
- FOR k := i TO N DO
- SetValue(j, k, GetValue(j, k) -
- Sum * GetValue(i, k));
- END;
- SetValue(i, i, Diag);
- Det := Det * (-Diag);
- END ELSE
- Singular := TRUE;
- UNTIL (i = N) OR Singular;
- IF Singular THEN
- Determinant := 0.0
- ELSE
- Determinant := Det;
- END;
-
- BEGIN
- (* keine Initialisierung *)
- END.
- (* ------------------------------------------------------ *)
- (* Ende von DETTOOL.PAS *)