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. Objects with indexed properties allow implementation of such flexible and dynamic arrays.
In algebra the objects are treated on several levels of
abstraction. For example, a matrix as whole, as a collection of vectors, and as an ordered set of elements:

The modeling objects should provide access to the objects at various levels:
![]() |
![]() |
|
Column Vector: C[1..Dim] |
Row Vector |
![]() |
||
|
2D Matrix |
Matrix by Columns |
Matrix by Rows |
![]() |
|
3D Matrix |
The pictures above illustrate the the FORTRAN-like notation (one-based arrays).
This indexing is the most common in mathematics and is
the default indexing.
The objects also support the arbitrary boundaries of arrays:
![]() |
![]() |
|
Column Vector: C[Lo..Hi] |
Row Vector |
|
|
2D Matrix |
|
|
|
Matrix by Columns |
Matrix by Rows |
![]() |
|
3D Matrix |
(Pictures by Max Shokhirev)
The arbitrary indexing may be convenient, for example, in treatment of some problems in physics:
.
In order to simplify the use of algebra objects and avoid memory leaks, the interface-based approach was chosen.
Direct
pointer memory access was used for computational efficiency.
Below are several simplified examples.
// Simple sort of row-vectors
procedure TestSort;
var
i, j: TInt;
M: IMatrix;
begin
M := TMatrix.Create(4,3); // One-based 2D array
RandMt(-1.0,1.0,M,0); // Fill with random numbers r: -1 < r < 1
for i := 1 to M.Dim1-1 do // In general: for i := N.Lo1 to M.Hi1-1 do
for j := i+1 to M.Dim1 do
if M.Row[i].Norm > M.Row[i].Norm then // M.Row[i].Norm = |M.Row[j]|
M.SwapRows(i,j);
end;
// Gram-Schmidt Orthonormalization
procedure TestGramSchmidt;
var
i, j, m: TInt;
t: TFloat;
D: IMatrix;
begin
D := TMatrix.Create(3,4); // the same as D := TMatrix.Create(1,3,1,4);
RandMt(-1.0,1.0,D,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 := D.Col[i].Norm; // = |D.Col[i]|
if t > SqrtMinFloat then
begin
D.Col[i].CxSelf(1.0/t); // = D.Col[i][k]/t - default limits (1 <= k <= Dim) are used
for j := i+1 to D.Dim2 do
begin
t := D.Col[i].Dot(D.Col[j]); // = <D.Col[i]|D.Col[j]>
D.Col[j].Add(-t, D.Col[i]); // = D.Col[j] - t*D.Col[i]) - default limits are used
end;
end else
begin
m := i-1; // m is the number of linear independent vectors
break;
end;
end; // no need to destroy D!
end;
// Gauss elimination method for the system of linear equations
procedure TestGaussSLE;
var
i, j: TInt;
c: TFloat;
D: IArray2D;
W: IVector;
begin
D := TArray2D.Create('Test.dat'); // Create from File
for i := 1 to D.Dim1 do
begin
c := D[i,i]; // c := D.Row[i][i];
D.Row[i].CxSelf(1.0/c, i); // for k := i to D.Dim2 do D.Row[i][k] := D.Row[i][k]/c;
for j := 1 to D.Dim1 do
if j <> i then
begin
t := D.Row[j][i];
D.Row[j].Add(-t, D.Row[i], i); // for k := i to D.Dim2 do D[j,k] := D[j,k] - t*D[i,k];
end;
end;
W := D.Col[D.Dim2]; // W is the vector of solution; Assignment, no creation
end;
(see also DUnit tests)
This is the hierarchy of interfaces for basic algebra objects:
|
Float |
Integer |
Boolean |
String | |||||
| Base objects | ITensor1D | ITensor2D | ITensor3D | IIntTensor1D | IIntTensir2D | IBTensor1D | IBTensor2D | INames |
| Enhanced | IVector | IMatrix | IMatrix3D | IIntVector | IIntMatrix | (IBVector) | (IBMatrix) | |
| I/O support | IArray1D | IArray2D | IArray3D | IIntArray1D | IIntArray2D | |||
(see also the Help). Currently the implementation of the arrays with I/O support is very poor and needs to be reworked.
For unified handling of the limits of indices all objects implement the corresponding ILimitXD interfaces:

1D arrays

2D-Arrays

3D-Arrays
(made with Ess-Model http://sourceforge.net/projects/essmodel ).
These objects are defined in the unit uCompoundArrays. They consist of the objects defined above.
|
Compound Float |
||||
| Base | IEigen | ICVector | ICMatrix | ICEigen |
| I/O support | IEigenSystem | ICArray1D | ICArray2D | ICEigenSystem |
IEigen = {Names: INames, EigenValues: IVector, EigenVectors: IMatrix}
ICvector = {Re: IVector, Im: IVector}
ICMatrix = {Re: IMatrix, Im: IMatrix}
ICEigen = {Re: IEigen , Im: IEigen }
These objects can be accessed as arrays of complex float numbers defined in the unit uComplexType.
The top part of the hierarchy is shown below.

| Unit |
Brief description |
| uMatTypes | Basic Math Types, Interfaces, Constants and Math utilities |
| uComplexType | Complex Math Types, constants and routines |
| uTensors | Tensor (basic arrays) Interfaces and Objects |
| uTensorUtilities | Basic algebra utilities |
| uArrays | Interfaces for Enhanced Arrays and implementing objects |
| uCompoundArrays | interfaces and objects for compound arrays |
(see the Help for details)
Currently there are three sets of DUnit tests: TensorTests, LinAlgTests and ObjAlgTest in the corresponding subdirectories of ObjAlg. In the Project options, the search path is set to $(DELPHI)\Projects\ObjMath\ObjAlg.
User guide can be found here (in progress)
The Object Algebra units are available in Download section
Up (Object Math)
|
|
Please e-mail me at nikolai@shokhirev.com |
ŠNikolai V. Shokhirev, 2002-2003