by Nikolai Shokhirev
(Development . . . Please check later)
Linear algebra is about indexed objects (tensors, vectors, matrices). Pascal-type arrays with arbitrary low and high bounds (including zero and negative ones) would be ideal for this, except that they are not dynamic.
Starting with the version 4 Delphi has dynamic arrays of arbitrary type. However they all are zero-based.
Objects with indexed properties allow implementation of dynamic arrays with the arbitrary index range. This approach was realized in ObjMath library. The objects are based on the direct memory allocation (GetMem/FreeMem).
In the current version the objects are based on the Delphi dynamic arrays. They are light-weight objects, many functions and properties are moved to the stand-alone functions and procedures. It makes the creation of objects less expensive and the code more readable.
The objects support the arbitrary boundaries of arrays:
![]() |
![]() |
|
Column Vector: C[Lo1..Hi1] |
Row Vector R[Lo1..Hi1 |
|
|
2D Matrix [Lo1..Hi1,Lo2..Hi2] |
![]() |
|
3D Matrix |
(Pictures by Max Shokhirev)
The arbitrary indexing may be convenient, for example, in treatment of some problems in physics:
.
The default is the FORTRAN-like (one-based) indexing. This indexing is the most common in mathematics. The base can be changed dynamically.
In order to simplify the use of algebra objects and avoid memory leaks, the interface-based approach was chosen.
Below are several simplified examples (see the Examples directory).
// Simple sort of row-vectors
procedure TestSort;
var
i, j: TInt;
M: IFArr2D;
begin
// M := TFArr2D.Create(0,3,0,2); // Zero-based 2D array 4 x 3
M := TFArr2D.Create(4,3); // One-based 2D array 4 x 3
RandArr2D(M,-1.0,1.0,0); // Fill with random numbers r: -1 < r < 1
// RandMt(-1.0,1.0,M,0); can also be used
for i := M.Lo1 to M.Hi1-1 do // For One-based array it also can be: for i := 1 to M.Dim1-1 do
for j := i+1 to M.Hi1 do
if M.Norm2(i,_) > M.Norm2(j,_) then // |M.Row[i]|**2 > |M.Row[j]|**2
M.Swap(i, j, _Row);;
end; // no need to destroy M!
// Gram-Schmidt Orthonormalization
procedure TestGramSchmidt;
var
i, j, m: TInt;
t: TFloat;
D: IFArr2D;
begin
D := TFArr2D.Create(3,4); // One-based 2D array 3 x 4
m := D.Dim2;
RandArr2D(D,-1.0,1.0); // Fill with random numbers [-1 < r < 1]
// The algorithm itself
for i := 1 to D.Dim2 do // For arbitrary limits: for i := D.Lo2 to D.Hi2 do
begin
t := t := D.Norm2(_,i); // = |D.Col[i]|**2
if t > MinFloat then
begin
CxCol(D, i, 1.0/t); // = D.Col[i]/t
for j := i+1 to D.Dim2 do
begin
t := ColxCol(D, i, j); // = <D.Col[i]|D.Col[j]>
ColAddCol(D, j, i, -t); // = D.Col[j] - t*D.Col[i])
end;
end else
begin
m := i-1; // m is the number of linear independent vectors
break;
end;
end; // no need to destroy D!
end;
(see also DUnit tests)
IComment
|
ILim1D
|
ILim2D
|
ILim3D
ILim1D
|
+-------+-------+-------+-------+
| | | | |
ISArr1D IBArr1D IIArr1D IFArr1D ICArr1D
ILim2D
|
+-------+-------+-------+
| | | |
IBArr2D IIArr2D IFArr2D ICArr2D
ILim3D
|
+-------+-------+
| | |
IBArr3D IIArr3D IFArr3D
IComment
|
+----------+----------+
| | |
IEigenSys IHEigenSys ISVDSys
uMatTypes | uDynArrays | uDynArrUtils | +------------+--------------+ | | | uDynArrIO uDynArrUtilsX uDynLinAlg |
This is the hierarchy of interfaces for basic algebra objects:
|
Float |
Integer |
Boolean |
String | |
| 1D | IFArr1D |
IIArr1D |
IBArr1D |
ISArr1D |
| 2D | IFArr2D |
IIArr2D |
IBArr2D |
ISArr2D |
| 3D | IFArr3D |
IIArr3D |
- |
- |
For unified handling of the limits of indices all objects implement the corresponding ILimND interfaces (N = 1, 2, 3).
These objects are also defined in the unit uDynArrays. They consist of the objects defined above.
|
Compound Float |
||
| IEigenSys | IHEigenSys | ISVDSys |
The objects can be presented graphically as follows:
![]() |
![]() |
|
| IEigenSys | IHEigenSys | ISVDSys |
The unit tests are mainly self-explanatory. They can be used as examples as well.
More documentation and DUnit tests are still coming
The PasMatLib units are available in the Download section
|
|
Please e-mail me at nikolai@shokhirev.com |
ŠNikolai V. Shokhirev, 2002-2007