Object Pascal (since Delphi 4) supports dynamic zero-based arrays. This library was developed for supporting dynamic arrays in Turbo Pascal and earlier versions of Delphi.
The algorithms collected in the library were translated from various languages, modified and developed by us. The references to the original publications are presented wherever they are available.
All arrays are 1-based (old good FORTRAN style). We employed the simplest and reliable approach (see the the unit MathTypes for details). However it requires some explanation. This is done below in a form of test application.
Some declarations from the unit MathTypes:
type
RealType = extended;
IntType = longint;
{ The dimension in declarations can be of any value }
Vector = array
[1..999] of RealType;
VcPtr = ^Vector;
Matrix = array
[1..999] of VcPtr;
MtPtr = ^Matrix;
And how it works
procedure MathTypesDemo;
var
Vp, Vc: VcPtr;
Mp: MtPtr;
K, L, i, j: IntType;
s: string;
// Example of Vector and Matrix declaration - this is recommended as more convinient
procedure MatTimesVec(var A: Vector; const B: Matrix; const C: Vector; N, M: IntType);
// A must be var because Vector is the array of RealType
// Vector access: A[i] or C[j]
// Matrix is the atrray of pointers and can be always declared as const
// Comment: Turbo-Pascal did not have const parameters and all variable were declared as var
// Matrix access: B[i]^[j] because B[i]^ is a Vector
// see declarations in the units MathTypes and ComplexType
var
i, j: IntType;
s: RealType;
begin
for i := 1 to N do
begin
s := 0.0;
for j := 1 to M do
s := s + B[i]^[j]*C[j]; // For comparison of static and dynamic arrays see the table below
A[i] := s;
end;
end;
// Example of pointer declarations - this is less convenient (one more '^' )but still OK
procedure InitMatVec(const A: VcPtr; const B: MtPtr; N, M: IntType);
// Both A and B are pointers and can be declared as const
// Vector access: A^[i]
// Matrix access: B^[i]^[j]
var
i, j: IntType;
begin
for i := 1 to N do
for j := 1 to M do
B^[i]^[j] := i*j; // pointer access
for j := 1 to M do
A^[j] := j; // pointer access
end;
begin
K := 2;
L := 3;
GetMatrixMemory(Mp, K, L);
GetVectorMemory(Vp, K);
GetVectorMemory(Vc, L);
InitMatVec(Vc, Mp, K, L); // Actual parameters are pointers
Memo3.Clear;
Memo3.Lines.Add('Mp:');
for i := 1 to K do
begin
s := '';
for j := 1 to L do
s := s +' [ '+ FloatToStr(Mp^[i]^[j])+' ] ';
Memo3.Lines.Add(s);
end;
Memo3.Lines.Add('-----------------------------------------------');
Memo3.Lines.Add('Vc:');
s := '';
for j := 1 to L do
s := s +' [ '+ FloatToStr(Vc^[j])+' ] ';
Memo3.Lines.Add(s);
Memo3.Lines.Add('-----------------------------------------------');
{ Vp^ is Vector, Mp^ is Matrix }
MatTimesVec(Vp^, Mp^, Vc^, K, L); // Actual parameters are Vector and Matrix
Memo3.Lines.Add('Vp:');
s := '';
for i := 1 to K do
s := s + ' [ '+ FloatToStr(Vp^[i])+' ] ';
Memo3.Lines.Add(s);
FreeVectorMemory(Vp, K);
FreeVectorMemory(Vc, L);
FreeMatrixMemory(Mp, K, L);
end;
Remarks
try
GetMatrixMemory((Mp, K, L);
. . .
finally
FreeMatrixMemory(Mp, K, L);
end;
| Dimension | Static | Dynamic |
| 1 | A[k] | A[k] |
| 2 | B[n,m] | B[n]^[m] |
| 3 | C[k,m,n] | C[k]^[m]^[n] |
Probably the notation in in the right column is less convenient (for dimensions > 1) but this is a small price for non-object dynamic arrays.
M: Matrix; vc: VcPtr; vc := M[j]; M[j] := M[i]; M[i] := vc; see Gram_Schmidt or SortTVec as an example.
Authors: Nikolai V. Shokhirev and Eugene B. Krissinel
Home | Back to Sample code | Back to PasMatLib
|
|
Please e-mail me at nikolai@shokhirev.com |
ŠNikolai V. Shokhirev, 2001-2002