Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- unit Unit1;
- Interface
- uses SysUtils,Math;
- // Объявление типов
- Type
- // Опережающая декларация интерфейса матрицы
- IMatrix = Interface;
- IVector = Interface;
- // Интерфейс вектора
- IVector = Interface
- // Функция получения значения элемента
- function GetItem(i: Integer): Extended;
- // Процедура установки значения элемента
- procedure SetItem(i: Integer; value: Extended);
- // Функция получения размера вектора
- function GetSize: Integer;
- // Функция получения индекса последнего элемента
- function GetHigh: Integer;
- // Функция создания копии объекта
- function Clone: IVector;
- // Процедура изменения размера вектора
- procedure Resize(n: Integer);
- // Функция сложения векторов
- function Add( a: IVector ): IVector;
- // Функция вычитания векторов
- function Sub( a: IVector ): IVector;
- // Функция умножения вектора на число
- function Mult( a: Extended ): IVector; overload;
- // Функция умножения вектора на матрицу
- function Mult( a: IMatrix ): IMatrix; overload;
- // Функция скалярного произведения векторов
- function Mult( a: IVector ): Extended; overload;
- // Функция векторного произведения векторов
- function Cross( a: IVector ): IVector;
- // Функция получения модуля вектора
- function Length: Extended;
- // Процедура нормирования вектора
- procedure Norm;
- // Свойство для чтения и изменения размера вектора
- property Size: Integer read GetSize write Resize;
- // Свойство для чтения индекса последнего элемента
- property High: Integer read GetHigh;
- // Свойство для доступа к элементам вектора
- property Item[i: Integer]: Extended read GetItem write SetItem; default;
- end;
- // Интерфейс матрицы
- IMatrix = Interface
- // Функция получения значения элемента
- function GetItem(i,j: Integer): Extended;
- // Процедура установки значение элемента
- procedure SetItem(i,j: Integer; value: Extended);
- // Функция получения кол-ва строк
- function GetRowCount: Integer;
- // Функция получения кол-ва столбцов
- function GetColCount: Integer;
- // Функция получения индекса последней строки
- function GetRowHigh: Integer;
- // Функция получения индекса последнего столбца
- function GetColHigh: Integer;
- // Функция создания копии объекта
- function Clone: IMatrix;
- // Процедура изменения размерности
- procedure Resize(n, m: Integer);
- // Функция сложения матриц
- function Add( a: IMatrix ): IMatrix;
- // Функция вычитания матриц
- function Sub( a: IMatrix ): IMatrix;
- // Функция умножения матрицы на матрицу
- function Mult( a: IMatrix ): IMatrix; overload;
- // Функция умножения матрицы на число
- function Mult( a: Extended ): IMatrix; overload;
- // Функция умножения матрицы на вектор
- function Mult( a: IVector ): IVector; overload;
- // Функция вычисления определителя
- function Det: Extended;
- // Функция обращения матрицы
- function Inv: IMatrix;
- // Функция транспонирования матрицы
- function T: IMatrix;
- // Процедура перестановки строк
- procedure SwapRows(i, j: Integer);
- // Свойство для достуа к элементам матрицы
- property Item[i,j: Integer]: Extended read GetItem write SetItem; default;
- // Свойство для чтения количества строк
- property RowCount: Integer read GetRowCount;
- // Свойство для чтения количества столбцов
- property ColCount: Integer read GetColCount;
- // Свойство для чтения индекса последней строки
- property RowHigh: Integer read GetRowHigh;
- // Свойство для чтения индекса последнего столбца
- property ColHigh: Integer read GetColHigh;
- end;
- // Объявление класса векторов
- TVector = class( TInterfacedObject, IVector )
- protected
- data: array of Extended;
- public
- // Конструктор по умолчанию
- constructor Create; overload;
- // Конструктор по количеству элементов
- constructor Create(n: Integer); overload;
- // Конструктор на основе обычного массива
- constructor Create(a: array of Extended); overload;
- // Деструктор
- destructor Destroy;
- // Функция получения значения элемента
- function GetItem(i: Integer): Extended;
- // Процедура установки значения элемента
- procedure SetItem(i: Integer; value: Extended);
- // Функция получения размера вектора
- function GetSize: Integer;
- // Функция получения индекса последнего элемента
- function GetHigh: Integer;
- // Функция создания копии объекта
- function Clone: IVector;
- // Функция изменения размера вектора
- procedure Resize(n: Integer);
- // Функция сложения векторов
- function Add( a: IVector ): IVector;
- // Функция вычитания векторов
- function Sub( a: IVector ): IVector;
- // Функция умножения вектора на число
- function Mult( a: Extended ): IVector; overload;
- // Функция умножения вектора на матрицу
- function Mult( a: IMatrix ): IMatrix; overload;
- // Функция скалярного произведения векторов
- function Mult( a: IVector ): Extended; overload;
- // Функция векторного произведения векторов
- function Cross( a: IVector ): IVector;
- // Функция получения модуля вектора
- function Length: Extended;
- // Процедура нормирования вектора
- procedure Norm;
- // Свойство для чтения и изменения размера вектора
- property Size: Integer read GetSize write Resize;
- // Свойство для чтения индекса последнего элемента
- property High: Integer read GetHigh;
- // Свойство для доступа к элементам вектора
- property Item[i: Integer]: Extended read GetItem write SetItem; default;
- end;
- // Объявление класса матриц
- TMatrix = class( TInterfacedObject, IMatrix )
- protected
- data: array of array of Extended;
- public
- // Конструктор по умолчанию
- constructor Create; overload;
- // Конструктор по количеству элементов
- constructor Create(n, m: Integer); overload;
- // Деструктор
- destructor Destroy;
- // Функция получения значения элемента
- function GetItem(i,j: Integer): Extended;
- // Процедура установки значение элемента
- procedure SetItem(i,j: Integer; value: Extended);
- // Функция получения кол-ва строк
- function GetRowCount: Integer;
- // Функция получения кол-ва столбцов
- function GetColCount: Integer;
- // Функция получения индекса последней строки
- function GetRowHigh: Integer;
- // Функция получения индекса последнего столбца
- function GetColHigh: Integer;
- // Функция создания копии объекта
- function Clone: IMatrix;
- // Функция изменения размерности
- procedure Resize(n, m: Integer);
- // Функция сложения матриц
- function Add( a: IMatrix ): IMatrix;
- // Функция вычитания матриц
- function Sub( a: IMatrix ): IMatrix;
- // Функция умножения матрицы на матрицу
- function Mult( a: IMatrix ): IMatrix; overload;
- // Функция умножения матрицы на число
- function Mult( a: Extended ): IMatrix; overload;
- // Функция умножения матрицы на вектор
- function Mult( a: IVector ): IVector; overload;
- // Функция вычисления определителя
- function Det: Extended;
- // Функция обращения матрицы
- function Inv: IMatrix;
- // Функция транспонирования матрицы
- function T: IMatrix;
- // Процедура перестановки строк
- procedure SwapRows(i, j: Integer);
- // Порождающая функция для формирования единичной матрицы
- class function E(n: Integer): IMatrix; static;
- // Свойство для достуа к элементам матрицы
- property Item[i,j: Integer]: Extended read GetItem write SetItem; default;
- // Свойство для чтения количества строк
- property RowCount: Integer read GetRowCount;
- // Свойство для чтения количества столбцов
- property ColCount: Integer read GetColCount;
- // Свойство для чтения индекса последней строки
- property RowHigh: Integer read GetRowHigh;
- // Свойство для чтения индекса последнего столбца
- property ColHigh: Integer read GetColHigh;
- end;
- // Объявление класса симметричных матриц
- TSymmetricMatrix = class( TMatrix );
- // Процедура установки значения элемента
- procedure SetItem(i,j: Integer; value: Extended);
- implementation
- constructor TVector.Create;
- begin
- Resize(1);
- end;
- constructor TVector.Create(n: Integer);
- begin
- Resize(n);
- end;
- constructor TVector.Create(a: array of Extended);
- begin
- Resize(System.Length(data));
- end;
- destructor TVector.Destroy;
- begin
- data:=nil;
- end;
- function TVector.GetItem(i: Integer): Extended;
- begin
- Result := data[i];
- end;
- procedure TVector.SetItem(i: Integer; value: Extended);
- begin
- data[i] := value ;
- end;
- function TVector.GetSize: Integer;
- begin
- Result := System.Length(data);
- end;
- function TVector.GetHigh: Integer;
- begin
- Result := System.High(data);
- end;
- function TVector.Clone: IVector;
- begin
- Result := TVector.Create;
- (Result as TVector).data := self.data;
- Result.Resize(self.Size);
- end;
- procedure TVector.Resize(n: Integer);
- begin
- SetLength(data, n);
- end;
- function TVector.Add( a: IVector ): IVector;
- var
- i: Integer;
- begin
- {$IFDEF Debug}
- if System.Length(data) <> a.Size then
- raise Exception.Create('Несовместимые размерности');
- {$ENDIF}
- Result:= TVector.Create(a.Size);
- for i := 0 to a.High do begin
- Result[i] := a[i] + data[i];
- end;
- end;
- function TVector.Sub( a: IVector ): IVector;
- var
- i: Integer;
- begin
- {$IFDEF Debug}
- if System.Length(data) <> a.Size then
- raise Exception.Create('Несовместимые размерности');
- {$ENDIF}
- Result:= TVector.Create(a.Size);
- for i := 0 to a.High do begin
- Result[i] := data[i] - a[i];
- end;
- end;
- function TVector.Mult( a: Extended ): IVector;
- var
- i: Integer;
- begin
- for i := 0 to System.Length(data)-1 do begin
- data[i] := data[i] * a;
- end;
- end;
- function TVector.Mult( a: IMatrix ): IMatrix;
- var
- i,j: Integer;
- begin
- {$IFDEF Debug}
- if 1 <> a.RowCount then
- raise Exception.Create('Несовместимые размерности');
- {$ENDIF}
- Result:= TMatrix.Create(System.Length(data),a.ColCount);
- for i := 0 to System.Length(data)-1 do begin
- for j := 0 to a.ColHigh do
- Result[i,j] := data[i]*a[0,j];
- end;
- end;
- function TVector.Mult( a: IVector ): Extended;
- var
- i:integer;
- begin
- {$IFDEF Debug}
- if System.Length(data) <> a.Size then
- raise Exception.Create('Несовместимые размерности');
- {$ENDIF}
- for i := 0 to a.High do begin
- Result := Result + data[i]*a[i];
- end;
- end;
- function TVector.Cross( a: IVector ): IVector;
- var
- i,j,k,l,n:integer;
- Matrix,MatrixD: TMatrix;
- begin
- {$IFDEF Debug}
- if (System.Length(data) <> a.Size) then
- raise Exception.Create('Несовместимые размерности');
- {$ENDIF}
- Result:= TVector.Create(a.Size);
- Matrix:= TMatrix.Create(System.Length(data)-1,System.Length(data)-1);
- MatrixD := TMatrix.Create(System.Length(data),System.Length(data));
- for i := 0 to a.High do begin
- MatrixD[0,i]:=1;
- MatrixD[1,i]:=data[i];
- MatrixD[2,i]:=a[i];
- end;
- for i := 0 to System.High(data) do begin
- l:=0;
- for j := 1 to System.High(data) do begin
- n:=0;
- for k:=0 to System.High(data) do begin
- if (k<>i) then begin
- Matrix[l,n]:=MatrixD[j,k];//Матрица после разложения
- inc(n);
- end;
- end;
- inc(l);
- end;
- Result[i]:=power(-1,i+2)*MatrixD[0,i]*Matrix.Det;//Считаем с помощью рекурсии
- end;
- end;
- function TVector.Length: Extended;
- var
- i: Integer;
- begin
- Result:=0;
- for i := 0 to System.Length(data)-1 do begin
- Result := Result+ data[i]*data[i];
- end;
- Result := sqrt(Result);
- end;
- procedure TVector.Norm;
- var
- i: integer;
- modul : Extended;
- begin
- modul := Length();
- for i := 0 to System.Length(data)-1 do begin
- data[i] := data[i]/modul;
- end;
- end;
- constructor TMatrix.Create;
- begin
- Resize(1,1);
- end;
- constructor TMatrix.Create(n, m: Integer);
- begin
- Resize(n,m);
- end;
- destructor TMatrix.Destroy;
- begin
- data:=nil;
- end;
- function TMatrix.GetItem(i,j: Integer): Extended;
- begin
- Result := data[i,j];
- end;
- procedure TMatrix.SetItem(i,j: Integer; value: Extended);
- begin
- data[i,j] := value ;
- end;
- function TMatrix.GetRowCount: Integer;
- begin
- Result:= System.Length(data);
- end;
- function TMatrix.GetColCount: Integer;
- begin
- Result:= System.Length(data[0]);
- end;
- function TMatrix.GetRowHigh: Integer;
- begin
- Result:= System.High(data);
- end;
- function TMatrix.GetColHigh: Integer;
- begin
- Result:= System.High(data[0]);
- end;
- function TMatrix.Clone: IMatrix;
- begin
- Result := TMatrix.Create;
- (Result as TMatrix).data := self.data;
- Result.Resize(self.RowCount,self.ColCount);
- end;
- procedure TMatrix.Resize(n, m: Integer);
- begin
- SetLength(data, n,m);
- end;
- function TMatrix.Add( a: IMatrix ): IMatrix;
- var
- i,j: Integer;
- begin
- {$IFDEF Debug}
- if (System.Length(data[0]) <> a.ColCount) and (System.Length(data) <> a.RowCount) then
- raise Exception.Create('Несовместимые размерности');
- {$ENDIF}
- Result:= TMatrix.Create(a.RowCount,a.ColCount);
- for i := 0 to a.RowHigh do begin
- for j := 0 to a.ColHigh do
- Result[i,j] := a[i,j] + data[i,j];
- end;
- end;
- function TMatrix.Sub( a: IMatrix ): IMatrix;
- var
- i,j: Integer;
- begin
- {$IFDEF Debug}
- if (System.Length(data[0]) <> a.ColCount) and (System.Length(data) <> a.RowCount) then
- raise Exception.Create('Несовместимые размерности');
- {$ENDIF}
- Result:= TMatrix.Create(a.RowCount,a.ColCount);
- for i := 0 to a.RowHigh do begin
- for j := 0 to a.ColHigh do
- Result[i,j] := a[i,j] - data[i,j];
- end;
- end;
- function TMatrix.Mult( a: IMatrix ): IMatrix;
- var
- j,l,m: Integer;
- begin
- {$IFDEF Debug}
- if (System.Length(data) <> a.ColCount) and (System.Length(data[0]) <> a.RowCount) then
- raise Exception.Create('Несовместимые размерности');
- {$ENDIF}
- Result:= TMatrix.Create(System.Length(data),a.ColCount);
- for l := 0 to System.High(data) do
- for m := 0 to a.ColHigh do
- for j := 0 to a.RowHigh do
- Result[l,m] :=Result[l,m]+ data[l,j] * a[j,m];
- end;
- function TMatrix.Mult( a: Extended ): IMatrix;
- var
- i,j:integer;
- begin
- Result:= TMatrix.Create(System.Length(data),System.Length(data[0]));
- for i := 0 to System.High(data) do
- for j := 0 to System.High(data[0]) do
- Result[i,j]:=data[i,j]*a;
- end;
- function TMatrix.Mult( a: IVector ): IVector;
- var
- i,j:integer;
- begin
- {$IFDEF Debug}
- if (System.Length(data[0]) <> a.Size) then
- raise Exception.Create('Несовместимые размерности');
- {$ENDIF}
- Result:= TVector.Create(System.Length(data));
- for i := 0 to System.High(data) do
- for j := 0 to System.High(data[0]) do
- Result[i]:=Result[i]+data[i,j]*a[j];
- end;
- function TMatrix.Det: Extended;
- var
- i,j,k,l,n:integer;
- Matrix: TMatrix;
- begin
- {$IFDEF Debug}
- if (System.Length(data[0]) <> System.Length(data)) then
- raise Exception.Create('Несовместимые размерности');
- {$ENDIF}
- //Разложим определитель по первой строке
- Result:=0;
- if System.Length(data)=1 then
- Result:=data[0,0] //Если определитель 1Х1
- else if System.Length(data)=2 then
- Result:=data[0,0]*data[1,1]-data[0,1]*data[1,0]//Если определитель 2Х2
- else if System.Length(data)>=3 then begin
- Matrix:= TMatrix.Create(System.Length(data)-1,System.Length(data)-1);
- for i := 0 to System.High(data) do begin
- l:=0;
- for j := 1 to System.High(data) do begin
- n:=0;
- for k:=0 to System.High(data) do begin
- if (k<>i) then begin
- Matrix[l,n]:=data[j,k];//Матрица после разложения
- inc(n);
- end;
- end;
- inc(l);
- end;
- Result:=Result+power(-1,i+2)*data[0,i]*Matrix.Det;//Считаем с помощью рекурсии
- end;
- end;
- //Реализуем методом Гаусса
- {for i := 0 to System.High(data)-1 do begin
- for j := 1+i to System.High(data) do begin // индекс строки
- Temp:=data[j,i]/data[i,i];//число которое будем онтимать от след строки для приведения к треугл виду
- Writeln('++',Temp);
- for k := 0+i to System.High(data) do // индекс столбца
- data[j,k]:=data[j,k]-data[i,k]*temp;
- end;
- end;}
- end;
- function TMatrix.Inv: IMatrix; //Метод Гаусса Йордана
- var
- Temp: Extended;
- i,j,k,per: integer;
- begin
- {$IFDEF Debug}
- if (System.Length(data[0]) <> System.Length(data)) then
- raise Exception.Create('Несовместимые размерности');
- {$ENDIF}
- Result:= TMatrix.Create(System.Length(data[0]),System.Length(data));
- //Проверка условия существования обратной матрицы.
- for i := 0 to Result.RowHigh do
- for j := 0 to Result.ColHigh do
- Result[i,j]:=data[i,j];
- {$IFDEF Debug}
- if (Result.Det =0) then
- raise Exception.Create('Матрица вырождена');
- {$ENDIF}
- Result:=TMatrix.E(System.Length(data));
- //приводим матрицу к треуголному ввиду, чтобы элементы ниже гл диаганали были равны 0
- i:=0;
- While i <= System.High(data[0])-1 do begin
- if data[i,i]<>0 then begin
- for k := 1+i to System.High(data[0]) do begin
- Temp:=data[k,i]/data[i,i];
- for j := 0 to System.High(data) do begin
- data[k,j]:=data[k,j]-Temp*data[i,j];
- Result[k,j]:=Result[k,j]-Temp*Result[i,j];
- end;
- end;
- end
- else if data[i,i]=0 then begin
- for j := i to System.High(data) do
- if data[j,i]<>0 then begin
- per:=j;
- break;
- end;
- for j := 0 to System.High(data) do begin
- Temp:=data[i,j];
- data[i,j]:=data[per,j];
- data[per,j]:=Temp;
- Temp:=Result[i,j];
- Result[i,j]:=Result[per,j];
- Result[per,j]:=Temp;
- end;
- i:=i-1;
- end;
- inc(i);
- end;
- //проверка 2 этапа
- {for i := 0 to System.High(data[0]) do begin
- for j := 0 to System.High(data[0]) do begin
- Write(data[i,j]:10:3, ' ');
- end;
- Writeln(' ');
- end;
- Writeln(' ');}
- //приводим матрицу к треуголному ввиду, чтобы элементы выше гл диаганали были равны 0
- i:=System.High(data[0]);
- While i >= 1 do begin
- for k := i-1 downto 0 do begin
- Temp:=data[k,i]/data[i,i];
- for j := 0 to System.High(data) do begin
- data[k,j]:=data[k,j]-Temp*data[i,j];
- Result[k,j]:=Result[k,j]-Temp*Result[i,j];
- end;
- end;
- i:=i-1;
- end;
- //проверка 2 этапа
- {for i := 0 to System.High(data[0]) do begin
- for j := 0 to System.High(data[0]) do begin
- Write(data[i,j]:10:3, ' ');
- end;
- Writeln(' ');
- end;
- Writeln(' ');}
- //делим строки чтобы получить 1 на главной оси
- for i := 0 to System.High(data) do
- if data[i,i]<>1 then begin
- Temp:=data[i,i];
- data[i,i]:=data[i,i]/Temp;
- for j := 0 to Result.ColHigh do begin
- Result[i,j]:=Result[i,j]/Temp;
- end;
- end;
- //проверка заключительного этапа по составлению единичный матрице
- {for i := 0 to System.High(data[0]) do begin
- for j := 0 to System.High(data[0]) do begin
- Write(data[i,j]:10:3, ' ');
- end;
- Writeln(' ');
- end;
- Writeln(' ');}
- end;
- function TMatrix.T: IMatrix;
- var i,j: integer;
- begin
- Result:= TMatrix.Create(System.Length(data[0]),System.Length(data));
- for i := 0 to System.High(data) do
- for j := 0 to System.High(data[0]) do
- Result[j,i]:=data[i,j];
- end;
- procedure TMatrix.SwapRows(i, j: Integer);
- var
- n:integer;
- temp:extended;
- begin
- for n := 0 to System.High(data[0]) do begin
- temp:=data[j,n];
- data[j,n]:=data[i,n];
- data[i,n]:=temp;
- end;
- end;
- class function TMatrix.E(n: Integer): IMatrix;
- var
- i,j:integer;
- begin
- Result:= TMatrix.Create(n,n);
- for i := 0 to n-1 do
- Result[i,i]:= 1;
- end;
- procedure SetItem(i,j: Integer; value: Extended);
- begin
- end;
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement