unit uMatrix;
interface
uses
Classes;
type
TMatrixArray = array of array of Integer;
TMatrix = class;
TMatrix = class
private
FData: TMatrixArray;
function Get(Col, Row: Integer): Integer;
function GetColCount: Integer;
function GetRowCount: Integer;
procedure Put(Col, Row: Integer; const Value: Integer);
public
{ конструктор. если Rows = 0, создается квадратичная матрица Cols х Cols }
constructor Create(Cols: Integer; Rows: Integer = 0);
destructor Destroy; override;
{ Очистка (заполнение нолями ) }
procedure Clear;
{ Заполнение случайными значениями в диапазоне от min до max }
procedure RandomFill(min: Integer = 0; max: Integer = 20);
{ Транспонирование. Результат - новая матрица }
function Transpose: TMatrix;
{ Вычисление определителя }
function Determinant: Integer;
{ Минор - остаток матрицы после вычитания строки и столбца}
function Minor(Col,Row: Integer): TMatrix;
{ Сложение с другой матрицей. Результат - новая матрица }
function SummOnMatrix(iMatrix: TMatrix): TMatrix;
{ Умножение матрицы на скаляр. Результат - новая матрица }
function MultipleOnNumber(Number: Integer): TMatrix;
{ "печать" матрицы в строку }
function ToString: string;
property Elements[Col,Row: Integer]: Integer read Get write Put; default;
property ColCount: Integer read GetColCount;
property RowCount: Integer read GetRowCount;
end;
implementation
uses
SysUtils, Math;
{ TMatrix }
procedure TMatrix.Clear;
var
i,j: Integer;
begin
for i := 0 to ColCount-1 do
for j := 0 to RowCount-1 do
FData[i,j] := 0;
end;
constructor TMatrix.Create(Cols: Integer; Rows: Integer);
begin
if (Rows < 1) then
Rows := Cols;
SetLength(FData,Cols,Rows);
Clear;
end;
destructor TMatrix.Destroy;
begin
SetLength(FData,0,0);
inherited;
end;
function TMatrix.Determinant: Integer;
var
i,j : Integer;
tmp : TMatrix;
Sign: Integer;
begin
Result := 0;
if (ColCount <> RowCount) then //матрица не квадратная!
Exit;
if (ColCount = 1) then
Result := Self[0,0]
else
begin
Sign := 1;
for i := 0 to RowCount-1 do
begin
tmp := Self.Minor(0,i);
Result := Result + Sign * tmp.Determinant * Self[0,i];
Sign := - Sign;
tmp.Free;
end;
end;
end;
function TMatrix.Get(Col,Row: Integer): Integer;
begin
if (Col < ColCount) and (Row < RowCount) then
Result := FData[Col,Row]
else
Result := 0;
end;
function TMatrix.GetColCount: Integer;
begin
Result := Length(FData);
end;
function TMatrix.GetRowCount: Integer;
begin
if Length(FData) > 0 then
Result := Length(FData[0])
else
Result := 0;
end;
function TMatrix.Minor(Col, Row: Integer): TMatrix;
var
c, r, idc, idr : Integer;
begin
Result := TMatrix.Create(ColCount-1,RowCount-1);
for c := 0 to ColCount-1 do
for r := 0 to RowCount-1 do
if ( c <> Col) and ( r <> Row) then
begin
idc := c;
idr := r;
if c > Col then
dec(idc);
if r > Row then
dec(idr);
Result[idc,idr] := Self[c,r];
end;
end;
function TMatrix.MultipleOnNumber(Number: Integer): TMatrix;
var
tmp: TMatrix;
i,j: Integer;
begin
Result := TMatrix.Create(ColCount,RowCount);
for i := 0 to ColCount-1 do
for j := 0 to RowCount-1 do
Result[i,j] := Self[i,j] * Number;
end;
procedure TMatrix.Put(Col, Row: Integer; const Value: Integer);
begin
FData[Col,Row] := Value;
end;
procedure TMatrix.RandomFill(min, max: Integer);
var
i,j: Integer;
begin
Randomize;
for i := 0 to ColCount-1 do
for j := 0 to RowCount-1 do
FData[i,j] := RandomRange(min, max);
end;
function TMatrix.SummOnMatrix(iMatrix: TMatrix): TMatrix;
var
i,j: Integer;
begin
Result := TMatrix.Create(Max(ColCount,iMatrix.ColCount), Max(RowCount,iMatrix.RowCount));
for i:= 0 to Result.ColCount-1 do
for j:= 0 to Result.RowCount-1 do
Result[i,j] := Self[i,j] + iMatrix[i,j];
end;
function TMatrix.ToString: string;
var
i,j: Integer;
begin
Result := '';
for i:= 0 to ColCount-1 do
begin
if (i > 0) then
Result := Result + #13#10;
for j:= 0 to RowCount-1 do
begin
if (j > 0) then
Result := Result + #9;
Result := Result + IntToStr(Self[i,j]);
end;
end;
end;
function TMatrix.Transpose: TMatrix;
var
i,j: Integer;
begin
Result := TMatrix.Create(RowCount,ColCount);
for i := 0 to RowCount-1 do
for j := 0 to ColCount-1 do
Result[i,j] := Self[j,i];
end;
end.