Теорема (формула Бине-Коши)
Пусть , - и -матрицы соответственно, и
Тогда
Другими словами, при определитель матрицы является суммой произведений всевозможных миноров порядка в на соответствующие миноры матрицы того же самого порядка.
Упражнение1. Покажем на примере
Пусть , , и , тогда по формуле Коши-Бине:
Доказательство теоремы:
Так как , то можно записать
Определитель-это аддитивная и однородная функция каждого из своих столбцов. Используя этот факт для каждого из столбцов в , выражаем в виде суммы определителей:
Те члены в суммировании, которые имеют совпадающие два или более индексов , равны нулю, так как в этих случаях миноры будут иметь по крайней мере два совпадающих столбца. Таким образом, нужно рассматривать лишь те членов суммирования, в которых индексы различны. Мы распределяем эти остающиеся члены на групп по членов в каждой таким образом, чтобы в каждой группе члены отличаются лишь порядком индексов . Отметим также, что можно написать
, где . Следовательно, сумма по членам, в которых -перестановка чисел , задается выражением:
Переставляя элементы так, чтобы первые индексы в возрастающем порядке, приводим это выражение к виду:
где -перестановка чисел , как очевидно . Из определителя функции определителя теперь следует, что это выражение есть просто:
Следствие. Определитель произведения двух кратных матриц равен произведению определителй множителей.
Это следует из Теоремы при
Заключение
В данной работе рассмотрена основная теория матриц и доказательство теоремы Коши-Бине. Также представлено применение данной теоремы при нахождении определителя произведения двух прямоугольных матриц в программе написанной на языке программирования Дельфи с возможностью ввода матриц вручную и подгрузкой из файла.
Данная теорема Коши-Бине:
Пусть , - и -матрицы соответственно, и
Тогда
На примере можно рассмотреть работу программы реализующей алгоритм нахождения определителя прямоугольных матриц на основе формулы Коши-Бине.
Будем искать миноры 2 порядка:
1)
Пусть A m = 2 n = 3
1 0 2
-1 1 1
B m = 3 n = 2
-1 -1
-2 0
1 1
получаем матрицу C m = 2 n = 2
1 1
0 2
Итого: Det C = 2
2)
Переборы:
1A) 1 2
1 0
-1 1
DetA = 1
1B) 1 2
-1 -1
-2 0
DetB = -2
2A) 1 3
1 2
-1 1
DetA = 3
2B) 1 3
-1 -1
1 1
DetB = 0
3A) 2 3
0 2
1 1
DetA = -2
3B) 2 3
-2 0
1 1
DetB = -2
C = (1)*(-2) + (3)*(0) + (-2)*(-2)
Итого по формуле Коши - Бине: 2
Данная программа наглядно показывает нахождение миноров порядка m, где m-это количество строк в матрице .
Список литературы
1. Гантмахер Ф.Р. Теория матриц. – 4-е изд. – М.: Наука. Гл.ред. физ. – мат. мет., 1988. с. 13-32.
2. Фаддеев Д.К. Лекции по алгебре.- М.:Наука. Гл.ред. физ. – мат. мет., 1984.-с.216.
3. Курош А.Г. Курс высшей алгебры. – 14 - е изд. - Спб.: Лань, 2005. -с.322
4. Ланкастер П. Теория матриц– М.: Наука. Гл.ред. физ. – мат. мет., 1973, с.17-44
5. Маркус М., Минк Х. Обзор по теории матриц и матричных неравенств. – М.: Наука. Гл.ред. физ. – мат. мет., 1972, с.232
6. Большакова И.В. Высшая математика - Учебное издание, 2003, с.5-10
Приложение
Внешний вид программы:
Исходный код:
unit MainUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Menus, Math, cdet;
Const
MaxN = 10; //Максимальное число столбцов в массиве
MaxM = 10; //Максимальное число строк в массиве
DefValueMas = 3; //Значение по умолчанию (размерность)
type
TVS_MAssPerebor = Array of Real; //Массив переборов
TVS_Mass = array of array of Real; //Описали 2х мерный динамический массив
TVS_MassData = Record //Создаем запись - массив, в котором:
Mass: TVS_Mass; //Массив
M, //Строки массива
N: Integer; //Столцы массива
Name: Char; //Название матрицы для вывода информации (A, B, C)
end; {TVS_MassData = Record}
TMainForm = class(TForm)
MainMenu1: TMainMenu;
N1: TMenuItem;
NMultiplication: TMenuItem;
N2: TMenuItem;
InputMassB: TMenuItem;
N3: TMenuItem;
N4: TMenuItem;
nDetA: TMenuItem;
NDetB: TMenuItem;
ResultMemo: TMemo;
N5: TMenuItem;
DetC: TMenuItem;
nmbn1: TMenuItem;
N6: TMenuItem;
N7: TMenuItem;
N8: TMenuItem;
N9: TMenuItem;
N10: TMenuItem;
OpenDialog: TOpenDialog;
procedure InputMassAClick(Sender: TObject);
procedure NMultiplicationClick(Sender: TObject);
procedure VS_MultiplicMass (Var inMassA, InMassB, MassOut: TVS_MassData);
procedure InputMassBClick(Sender: TObject);
procedure VS_InputMass(Var InMass: TVS_MassData);
procedure VS_ShowMass (inCaption: String; inMass: TVS_MassData);
procedure FormShow(Sender: TObject);
procedure N3Click(Sender: TObject);
procedure nDetAClick(Sender: TObject);
function VS_Det(InMass: TVS_MassData): Real;
procedure NDetBClick(Sender: TObject);
procedure VS_ShowMassToMemo(Caption: String; InMass: TVS_MassData; ShowRazm: Boolean = True);
procedure N5Click(Sender: TObject);
procedure DetCClick(Sender: TObject);
Procedure AssignMass(InMAss: TVS_MassData; Var OutMass: TVS_MassData);
Procedure VS_VerMass(Var Massin1, MAssIn2: TVS_MassData);
Procedure VS_LoadData(Var InMAss: TVS_MassData);
Procedure VS_GetRazmOnFile(FileName: String; Var Col, Row: Integer);
Function VS_GetColOnFile(InStr: String): Integer;
//Миноры
function VS_Minor(II, Jj: Integer; InMass: TVS_MassData): REal;
Procedure VS_InitMassInStr(InStr: String; CurRow: Integer; Var InMass: TVS_MassData);
Procedure VS_InitMassPErebor;
Procedure VS_Init2xMassPerebot;
Procedure VS_SortMassPerebor;
Procedure VS_GetMAssForDet;
Function VS_IfMassEq(Massin1, MAssIn2: TVS_MassData): Boolean;
Function VS_GetKoshi_Bine: Real;
procedure VS_GenerateColMinorData(CurCol, Col: Integer; Var inMass: TVS_MassData);
procedure VS_GenerateRowMinorData(CurCol, Col: Integer; Var InMass: TVS_MassData);
Procedure VS_MinorMass(InMass: TVS_MassData; Var OutMass: TVS_MassData);
procedure N6Click(Sender: TObject);
procedure N7Click(Sender: TObject);
procedure N8Click(Sender: TObject);
procedure lll1Click(Sender: TObject);
procedure N9Click(Sender: TObject);
procedure N10Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
MainForm: TMainForm;
MassP: TVS_MAssPerebor;
MassPer,
MassA,
MassB, MassC: TVS_MassData;
DetB,
DetA: TVS_MAssPerebor; //Массив детерминант А
implementation
uses InRazmUnit, InMassUnit;
{$R *.dfm}
function TMainForm.VS_Det(InMass: TVS_MassData): Real;
var
Temp, A: TVS_MassData;
Cols, Rows, Count: Word;
i, j, k: Integer;
begin
Result:= 1; //Результат функции по умолчанию
If InMass.N <> InMass.M Then Exit; //если матрица не квадратная - уходим, так как решение методом диагонали
Count:= InMass.M; // Получили размерность исходного массива
SetLength(A.Mass, Count, Count);//Установили размер матрицы
SetLength(Temp.Mass, 1, Count); //Установили размер мартицы
AssignMass(InMass, A); //Во временный массив заносим данные из исходного, чтобы не портить исходный массив
//Поиск и решение
for i:= 0 to Count - 2 do {Начало преобразования к верхнему треугольному виду}
begin
for j:= i to Count - 1 do {* Поиск }
begin {* нулевых }
Rows:= 0; {* строк }
Cols:= 0; {* и }
for k:= i to Count - 1 do {* столбцов }
begin {* в }
Rows:= Rows + Ord(A.Mass[j, k] = 0); {* матрице }
Cols:= Cols + Ord(A.Mass[k, j] = 0); {* }
end;{for k:= i to Count - 1 do} {* }
if Rows + Cols = 0 then {* }
Break; {* }
if (Cols = Count - i) or (Rows = Count - i) then {* }
begin {* }
Result:= 0; {* }
Exit {* }
end {if (Cols = Count - i) or (Rows = Count - i) then }
end; {for j:= i to Count - 1 do } {* }
if A.Mass[i, i] = 0 then
for j:= i + 1 to Count - 1 do
if A.Mass[j, i] <> 0 then
begin
Result:= -Result; {* меняем строку }
Temp.Mass[0]:= A.Mass[i]; {* на строку с }
A.Mass[i]:= A.Mass[j]; {* первым }
A.Mass[j]:= Temp.Mass[0]; {* ненулевым }
Break {* элементом }
end;
for j:= i + 1 to Count - 1 do
if A.Mass[j, i] <> 0 then
begin
for k:= i + 1 to Count - 1 do
A.Mass[j, k]:= A.Mass[j, k] - A.Mass[i, k] * A.Mass[j, i] / A.Mass[i, i];
A.Mass[j, i]:= 0
end
end; {Конец преобразования}
for i:= 0 to Count - 1 do { Определитель как произведение }
Result:= Result * A.Mass[i, i]; { элементов на главной диагонали}
end;
procedure TMainForm.InputMassAClick(Sender: TObject);
begin
If InRazmForm = Nil Then Application.CreateForm(TInRazmForm, InRazmForm);
With InRazmForm do
Begin
Caption:= 'Ввод размерности ряда А';
Hint:= Caption; //
ShowHint:= True; //Разрешаем быстрые подсказки
lbPrompt1.Caption:= 'Размерность N ';
//Настройка эелемента ввода для размерности массива по строкам - М
sedtRazmA.MinValue:= 1; //Установили минимальное знаечение для ввода-переключателя
sedtRazmA.MaxValue:= MaxN; //Установили максимальное значение для ввода - переключателя
sedtRazmA.Value:= MassA.N; //Установили значение, выводимое на экран
//Настройка эелемента ввода для размерности массива по столбцам - N
sedtRazmB.MinValue:= 1; //Установили минимальное знаечение для ввода-переключателя
sedtRazmB.MaxValue:= MaxM; //Установили максимальное значение для ввода - переключателя
sedtRazmB.Value:= MassA.M; //Установили значение, выводимое на экран
lbPrompt2.Caption:= 'Размерность M ';
btnNext.Caption:= 'Далее';
btnCancel.Caption:= 'Отмена';
If InRazmForm.ShowModal = Mrok Then //если пользователь нажал кнопку "Далее"
Begin
MassA.N:= sedtRazmA.Value; //Сохраняем размерность массива
MassA.M:= sedtRazmB.Value; //Сохраняем размерность массива
VS_InputMass(MassA); //Выводим сетку для ввода масива
end; {If ShowModal = Mrok Then}
end; {With InRazmForm do}
end; {procedure TMainForm.InputMassAClick(Sender: TObject);}
procedure TMainForm.NMultiplicationClick(Sender: TObject);
//Умножение матриц
begin
VS_MultiplicMass(MassA, MassB, MassC); //Умножаем матрицы
VS_ShowMassToMemo('Результат произведения A*B получился ', MassC); //Результат выводим в Мемо
VS_ShowMass('Итоговый результат ', MassC); //Выводим результаты расчета
end;
procedure TMainForm.VS_MultiplicMass(var inMassA, InMassB, MassOut: TVS_MassData);
//Умножаем матрицы
//N, M - размерность матрицы, где
//N - стоблец
//M - строка
//inMassA - массив А
//inMassB - массив Б
//MassOut - массив С / выходной массив
Var P, i, j: Integer;
S: Real;
begin
For I:= 0 to inMassA.M - 1 do // i = 1.. m
For J:= 0 to inMassB.N - 1 do // j = 1.. k
begin
S:= 0; //Сбнуляем счетчик
For P:= 0 to inMassA.N -1 do // p = 1..n
S:= S + inMassA.Mass[i, p] * InMassB.Mass[p, j]; //Вычисляем по формуле (Cij = Ep (Aip *Bpj)? где i=1..m, j = 1..k)
MassOut.Mass[I, J]:= s; //Сохраняем результат в массив С
end;
MassOut.N:= inMassB.N; //Сохраняем получившиюся размерность массива С
MassOut.M:= inMassA.M; //Сохраняем получившиюся размерность массива С
end;
procedure TMainForm.InputMassBClick(Sender: TObject);
begin
If InRazmForm = Nil Then Application.CreateForm(TInRazmForm, InRazmForm);
With InRazmForm do
Begin
Caption:= 'Ввод размерности ряда Б';
Hint:= Caption;
ShowHint:= True; //Разрешаем быстрые подсказки на форме
lbPrompt1.Caption:= 'Размерность N ';
sedtRazmA.MinValue:= 1; //Установили минимальное знаечение для ввода-переключателя
sedtRazmA.MaxValue:= MaxN; //Установили максимальное значение для ввода - переключателя
sedtRazmA.Value:= MassB.N; //Установили значение, выводимое на экран
sedtRazmB.MinValue:= 1; //Установили минимальное знаечение для ввода-переключателя
sedtRazmB.MaxValue:= MaxM; //Установили максимальное значение для ввода - переключателя
sedtRazmB.Value:= MassB.M; //Установили значение, выводимое на экран
lbPrompt2.Caption:= 'Размерность M ';
btnNext.Caption:= 'Далее';
btnCancel.Caption:= 'Отмена';
If ShowModal = Mrok Then //если пользователь нажал "Далее"
Begin
MassB.N:= sedtRazmA.Value; //Сохраняем размерность массива
MassB.M:= sedtRazmB.Value; //Сохраняем размерность массива
VS_InputMass(MassB); //Выводи окно с сеткой для ввода массива
end{If ShowModal = Mrok Then}
end; {With InRazmForm do}
end;
procedure TMainForm.VS_ShowMass(inCaption: String; inMass: TVS_MassData);
//Выводим массив
//N, M - размерность матрицы, где
//N - стоблец
//M - строка
//inMass - массив, который выводим
Var
I, K: Integer;
begin
If InMassForm = Nil Then Application.CreateForm(TInMassForm, InMassForm);
with InMassForm do
Begin
Caption:= 'Вывод массива';
strGrid.RowCount:= InMass.M+1;
strGrid.ColCount:= inMAss.N+1;
For I:= 0 To inMAss.N -1 do //Выводим шапку для столбцов
strGrid.Cells[I + 1, 0]:= 'N = ' + IntToStr(I + 1);
For I:= 0 To inMAss.M -1 do //Выводим шапку для строк
strGrid.Cells[0, I + 1]:= 'M = ' + IntToStr(I + 1);
btnNext.Caption:= 'Ok';
btnCancel.Visible:= False; //Выключаем кнопку "Отмена". Она нам не нужна
For I:= 0 To inMAss.N -1 do //Пробегаемся по строкам
For K:= 0 To inMAss.M -1 do //Пробегаемся по столбцам
InMassForm.strGrid.Cells[I +1,K +1]:= FloatToStr(inMass.Mass[K, I]); //Выводим в сетку ранее сохраненный массив
ShowModal; //Выводим окно, ждем реакции пользователя
btnCancel.Visible:= True; //Не забываем включить кнопку "Отмена", иначе ее не увидят в других нужных нам метсах
end; {with InMassForm do}
End;
procedure TMainForm.FormShow(Sender: TObject);
//Обрабатываемся прри вызове формы
Var I, J: Integer;
begin
//Обнуляем массивы, во избежание шаманских действий программы
SetLength(MassA.Mass, MaxM, MaxN); //Установили размер массива в памяти
SetLength(MassB.Mass, MaxM, MaxN); //Установили размер массива в памяти
SetLength(MassC.Mass, MaxM, MaxN); //Установили размер массива в памяти
For I:= 0 to MaxM - 1 Do //Пробегаемся по строкам
For J:= 0 to MaxN - 1 do //Пробегаемся по столбцам
Begin
MassA.Mass[I, J]:= 0;
MassB.Mass[I, J]:= 0;
MassC.Mass[I, J]:= 0;
end; {For J:= 1 to MaxN do}
//Обнуляем переменные размерностей массивов
MassA.N:= DefValueMas; //Устанавливаем размерность матрицы по умолчанию
MassA.M:= MassA.N;
MassB.N:= MassA.N;
MassB.M:= MassA.N;
MassC.N:= MassA.N;
MassC.M:= MassA.N;
MassA.Name:= 'A';
MassB.Name:= 'B';
MassC.Name:= 'C';
ResultMemo.Clear; //Очищаем Мемо-поле.
end;
procedure TMainForm.VS_InputMass(var InMass: TVS_MassData);
//Вводим Элементы массива
Var
I, K: Integer;
begin
If InMassForm = Nil Then Application.CreateForm(TInMassForm, InMassForm);
with InMassForm do
Begin
Caption:= 'Ввод массива';
strGrid.RowCount:= InMass.M+1; //указали количество строк рамным М
strGrid.ColCount:= InMass.N+1; //Указали количество столбцов, равным N
For I:= 0 To InMass.N -1 do //Делаем шапку для столбцов
strGrid.Cells[I +1, 0]:= 'N = ' + IntToStr(I +1);
For I:= 0 To InMass.M -1 do //Делаем шапку для строк
strGrid.Cells[0, I +1]:= 'M = ' + IntToStr(I +1);
//Заносим результаты массива в сетку, если вводили ранее
For I:= 0 to InMass.M -1 do //Пробегаемся по строкам массива
For K:= 0 to InMass.N -1 do //Пробегаемся по столбцам массива
Try
strGrid.Cells[I+1, K+1]:= FloatToStr (InMass.Mass[K, I]); //Выводим массив в сетку
except
strGrid.Cells[I+1, K+1]:= '0';
end;
btnNext.Caption:= 'Далее';
btnCancel.Caption:= 'Отмена';
If ShowModal = Mrok Then //Выводим форму, ждем реакции пользователя
Begin
SetLength(MassA.Mass, InMass.M +1, InMass.N +1); //Установили размер массива в памяти
For I:= 0 To InMass.N -1 do //Пробегаемся по строкам массива
For K:= 0 To InMass.M -1 do //Пробегаемся по столбцам массива
Try //Включаем обработку ошибок
InMass.Mass[K, I]:= StrToInt(InMassForm.strGrid.Cells[I +1,K +1]); // Заносим элемент из сетки в массив
except //Если произошла ошибка, например с переводом строки в число
InMass.Mass[I, K]:= 0; //Если ошибка - заносим в массив 0
end; {except}
VS_ShowMassToMemo('Успешно введена матрица ',InMass); //Выводим матрицу в Мемо
end;{If ShowModal = Mrok Then}
end;
end;
procedure TMainForm.N3Click(Sender: TObject);
//Выводим результат. Просто выводим массив
begin
VS_ShowMass('', MassC)
end;
procedure TMainForm.nDetAClick(Sender: TObject);
//Определяем определитель матрицы А
Var Det: Real;
begin
Det:= VS_Det(MassA); //ВЫчисляем определитель
ResultMemo.Lines.Add('Определитель матрицы А равен ' + FloattoStr(Det)); //Выводим результат в Мемо
ShowMessage(FloatToStr(Det)); //Выводим результат в диалоговое окно
end;
procedure TMainForm.NDetBClick(Sender: TObject);
//Определяем определитель матрицы B
Var Det: Real;
begin
Det:= VS_Det(MassB); //Вычисляем определитель
ResultMemo.Lines.Add('Определитель матрицы B равен ' + FloattoStr(Det)); //Результат вычислений выводим в МЕмо
ShowMessage(FloatToStr(Det)); //Результат выводим в диалоговое окно
end;
procedure TMainForm.VS_ShowMassToMemo(Caption: String; InMass: TVS_MassData; ShowRazm: Boolean = True);
//Выводим массив в МЕмо
Var S: String;
I, J: Integer;
begin
If ShowRazm Then ResultMemo.Lines.Add(Caption + InMass.Name + ' m = ' + IntToStr(InMass.M) + ' n = ' + IntToStr(InMass.n))
Else ResultMemo.Lines.Add(Caption);
For I:= 0 to InMass.M - 1 do //Пробегаемся по строкам
Begin
S:= ''; //Готовимся к формированию строки
For J:= 0 To InMass.N -1 Do //Пробегаемся по столбцам
S:= S + FloatToStr(InMass.Mass[i,j]) + ' '; //Формируем строку элементов
ResultMemo.Lines.Add(S); //Выводим строку в Мемо
end;{For I:= 0 to InMass.M - 1 do //Пробегаемся по строкам}
end;
procedure TMainForm.N5Click(Sender: TObject);
Var DetA, DetB, Det: Real;
begin
ResultMemo.Clear;
//Решаем det C обычным способом
VS_VerMass(MAssA, MAssB); //Проверяем массивы. Если в первом массиве число столбцов меньше, чем во втором, меняем матрицы местами
ResultMemo.Lines.Add('1)');
VS_ShowMassToMemo('Пусть ', MassA); //Выводим матрицу А
VS_ShowMassToMemo('', MassB); //Выводим матрицу Б
VS_MultiplicMass(MassA, MassB, MassC); //Умножаем матрицы
VS_ShowMassToMemo('получаем матрицу ', MassC); //Выводим матрицу С
Det:= VS_Det(MassC);
ResultMemo.Lines.Add('Итого: Det C = ' + FloatToStr(Det));
ResultMemo.Lines.Add('2)');
//Решаем по Бине-Коши
If (MassA.M > MassA.N) Then
Begin //попали под условие, когда М>n, значит определитель равен 0
ResultMemo.Lines.Add('m > n массива А, исходя из т. Бине - Коши, DetC = 0');
Exit //Завершаем процедуру
end;
//If (MassB.M > MassB.N) Then
// Begin //попали под условие, когда М>n, значит определитель равен 0
// ResultMemo.Lines.Add('m > n массива B, исходя из т. Бине - Коши, DetC = 0');
// Exit//Завершаем процедуру
// end;
If (MassA.M = MassA.N) And (MassA.M = MassA.N)
Then //попали под условие, когда обе матрицы кувадратные
Begin
ResultMemo.Lines.Add('m = n массивов B и А, исходя из т. Бине - Коши, ');
DetA:= VS_Det(MassA);
DetB:= VS_Det(MassB);
Det:= DetA * DetB;
ResultMemo.Lines.Add('DetC = detA * Det B = ' + FloatToStr(DetA) + ' * ' + FloatToStr(DetB) + ' = ' + FloatToStr(Det));
end;
If (MassA.M < MassA.N) And (MassB.M > MassB.N) Then
Begin
IF VS_IfMassEq(MAssA, MAssB)
Then
BEgin
VS_VerMass(MAssA, MAssB);
VS_InitMassPErebor;
VS_Init2xMassPerebot;
VS_SortMassPerebor;
VS_GetMAssForDet;
ResultMemo.Lines.Add('Итого по формуле Коши - Бине: ' + FloattoStr(VS_GetKoshi_Bine))
end{IF VS_IfMassEq(MAssA, MAssB)}
Else ResultMemo.Lines.Add('Матрицы не равны')
end;{If (MassA.M < MassA.N) And (MassB.M > MassB.N) Then}
end;
procedure TMainForm.DetCClick(Sender: TObject);
Var Det: Real;
begin
Det:= VS_Det(MassC); //ВЫчисляем определитель
ResultMemo.Lines.Add('Определитель матрицы C равен ' + FloattoStr(Det)); //Выводим результат в Мемо
ShowMessage(FloatToStr(Det)); //Выводим результат в диалоговое окно
end;
function TMainForm.VS_Minor(II, Jj: Integer; InMass: TVS_MassData): REal;
//Вычислаем минор
Var
Col, //Текущий столбец новой матрицы
Row, //Текущая строка новой матрицы
I, J: Integer;
TempMass: TVS_MassData;
begin
If InMass.M <> InMass.N Then Exit; // Матрица не квадратная - убегаем
SetLength(TempMass.Mass, InMass.M -1, InMass.N -1);//Установили размер матрицы
Row:= 0;
For I:= 0 To InMass.M -1 Do
begin
Col:= 0; //Начали новый массив с первого элемента
If I <> II -1 Then
Begin //Отбрасываем I строку
For J:= 0 To InMass.N -1 do
If J <> JJ -1 Then
Begin //Перебираем все столюцы, кроме J
TempMass.Mass[Row,Col]:= InMass.Mass[I,J];
Inc(Col);
end;{If J <> JJ Then}
Inc(Row); //Перешли на сл. строку для нового массива
end;{If I <> II Then}
end; {For I:= 0 To InMass.M Do}
TempMass.M:= InMass.M - 1;
TempMass.N:= InMass.N - 1;
Result:= VS_Det(TempMass);
end;
procedure TMainForm.AssignMass(InMAss: TVS_MassData;
var OutMass: TVS_MassData);
//Передаем данные из InMass в OutMass;
Var
I,
J: Integer;
begin
for i:= 0 to InMAss.M - 1 do //Пробегаемся по строкам
for j:= 0 to InMAss.N - 1 do //Пробегаемся по столбцам
OutMass.Mass[i, j]:= InMass.Mass[i, j]; //Переносим значения из InMAss в OutMas
OutMass.M:= InMAss.M; //Переносим число, определяющее количество строк
OutMass.N:= InMAss.N; //Переносим число, определяющее количество столбцов
OutMass.Name:= InMAss.Name; //Переносим название массива
end;
procedure TMainForm.VS_MinorMass(InMass: TVS_MassData; var OutMass: TVS_MassData);
//Находим все миноры входящей матрицы
//InMass - массив, в котором будем искать миноры
//OutMass - массив минор
Var
i,
j: Integer;
begin
If InMass.M <> InMass.N Then Exit; //Вышли, так как мартица не квадратная
For I:= 0 to InMass.M - 1 Do //пробегаемся по строкам
For J:= 0 To InMass.N - 1 do //Пробегаемся по столбцам
OutMass.Mass[I,J]:= VS_Minor(I +1, J +1, InMass); //Получили I, J минор и занесли в массив OutMass
OutMass.M:= InMass.M;
OutMass.N:= InMass.N;
end;
procedure TMainForm.N6Click(Sender: TObject);
begin
VS_MinorMass(MassA, MassC);
VS_ShowMass('Минор', MassC);
VS_ShowMassToMemo('Минор', MassC);
end;
procedure TMainForm.N7Click(Sender: TObject);
begin
VS_MinorMass(MassB, MassC);
VS_ShowMass('Минор', MassC);
VS_ShowMassToMemo('Минор', MassC);
end;
procedure TMainForm.N8Click(Sender: TObject);
begin
VS_MinorMass(MassC, MassC);
VS_ShowMass('Минор', MassC);
VS_ShowMassToMemo('Минор', MassC);
end;
procedure TMainForm.lll1Click(Sender: TObject);
begin
IF VS_IfMassEq(MAssA, MAssB)
Then
BEgin
VS_VerMass(MAssA, MAssB);
VS_InitMassPErebor;
VS_Init2xMassPerebot;
VS_SortMassPerebor;
VS_GetMAssForDet;
ResultMemo.Lines.Add('Итого по форуме Коши - Бине: ' + FloattoStr(VS_GetKoshi_Bine))
end
Else ResultMemo.Lines.Add('Матрицы не равны')
end;
procedure TMainForm.VS_InitMassPErebor;
//Создаем массив переборов для вычесления Детерминант формулы Коши-Бине
// Все действия делаются над массивом MAssP
Var
I, J, Curr: Integer;
begin
Curr:= 0; //Текущий элемент массива
SetLength(MassP, MassA.N * MassA.M); //Установили размерность
For I:= 0 to MassA.M -1 do //Пробегаемся по строкам
For J:= 0 to MassA.N -1 do //Пробегаемся по столбцам
Begin
MassP[Curr]:= J +1; //Заполняем массив строками-перестановками/столбцами-перестановками
Inc(Curr); //Перешли к след. элеенту массива
end;
//VS_SortMassPerebor
end;
procedure TMainForm.VS_GetMAssForDet;
//Формуриуем массив для вычисления Дет.
//Данные перестановки уже должны хранится в массиве MassP
//т. е уже нужно иметь Массив А и уже должна быть выполнена VS_InitMassPErebor;
Var I, J: Integer;
Det: Real;
SA, SB: String;
TempB,
TempA: TVS_MassData; //Н*М мерный массив миноров
begin
ResultMemo.Lines.Add('Переборы: ');
SetLength(TempA.Mass, MAssA.M, MAssA.M);
SetLength(TempB.Mass, MAssB.N, MAssB.N);
SetLength(DetA, MassA.N);
SetLength(DetB, MassB.M);
TEmpA.M:= MAssA.M;
TEmpA.N:= MAssA.M;
TEmpB.M:= MAssB.N;
TEmpB.N:= MAssB.N;
For I:= 0 to MassPer.M - 1 do //пробегаемся по строкам
Begin
SA:= IntToStr(I +1) + 'A) ';
SB:= IntToStr(I +1) + 'B) ';
For J:= 0 to MassPer.N - 1 do //Пробегаемся по всем столбцам -1
begin
SA:= SA + FloatToStr(MassPer.Mass[I, J]) + ' ';
SB:= SB + FloatToStr(MassPer.Mass[I, J]) + ' ';
VS_GenerateColMinorData(J, Trunc(MassPer.Mass[I, J]), TempA);
VS_GenerateRowMinorData(J, Trunc(MassPer.Mass[I, J]), TempB);
end;{For J:= 0 to MassPer.N - 1 do //Пробегаемся по всем столбцам -1}
ResultMemo.Lines.Add('');
ResultMemo.Lines.Add(SA);
VS_ShowMassToMemo('', TempA, False);
DetA[I]:= VS_Det(TempA);
ResultMemo.Lines.Add('DetA = ' + FloatToStr(Deta[I]));
ResultMemo.Lines.Add('');
ResultMemo.Lines.Add(SB);
VS_ShowMassToMemo('', TempB, False);
DetB[I]:= VS_Det(TempB);
ResultMemo.Lines.Add('DetB = ' + FloatToStr(DetB[I]));
end;{For I:= 0 to MassPer.M - 1 do //пробегаемся по строкам}
end;
procedure TMainForm.VS_GenerateColMinorData(CurCol, Col: Integer;
var inMass: TVS_MassData);
//Формируем массив минор для КоШИ_БИНЕ
//На входе
//CurCol - номер столбюца в новом массиве
//COl - номер столбца для массива, с которого будем брать значения
//InMass - массив, в который будем заносить значения
Var I: Integer;
begin
For I:= 0 To MassA.M -1 do
inMass.Mass[I, CurCol]:= MassA.Mass[I, Col -1];
end;
procedure TMainForm.VS_SortMassPerebor;
//Сортируем элементы массива переборов для правильного вычисления миноров
Var
K, I, J, Curr: Integer;
Rez: Real;
begin
For I:= 0 to MassPer.M - 1 do //пробегаемся по строкам
For J:= 0 to MassPer.N - 2 do //Пробегаемся по всем столбцам -1
For K:= J + 1 to MassPer.N - 1 do
If MassPer.Mass[I, j] > MassPer.Mass[I, K] Then //Текущий элемент больше следующего - меняем местами
Begin
REz:= MassPer.Mass[I, j];
MassPer.Mass[I, j]:= MassPer.Mass[I, K];
MassPer.Mass[I, K]:= Rez;
end;
end;
procedure TMainForm.VS_Init2xMassPerebot;
//Формируем 2хмерный массив переборов
//На выходе будет M*N мерный массив переборов (не сортированый)
Var I, J, Curr, CurCol, CurRow: Integer;
Det: Real;
S: String;
begin
Curr:= 0; //Текущий элемент в массиве MassP
SetLEngth(MassPer.Mass, MassA.N, MassA.M); //Установвили размерность массива перестановок
MassPer.M:= MassA.N; //Задали размерность
MassPer.N:= MassA.M; //Задали размерность
CurRow:= 0; //Текущая строка нового массива
For I:= 0 to MassA.N -1 Do //Запускаем по строкам
begin
CurCol:= 0; // Текущий столбец/строка нового массива
For J:= 0 to MassA.M - 1 do
Begin
MassPer.Mass[CurRow, CurCol]:= MassP[Curr];
Inc(Curr); //Перешли к новому элементу массива MassP
Inc(CurCol); //Перешли к нововму столбцу нового массива
end; {For J:= 0 to MassA.M - 1 do}
Inc(CurRow); //Перешли к новой строке нового массива
end;{For I:= 0 to MassA.N -1 Do //Запускаем}
end;
procedure TMainForm.VS_GenerateRowMinorData(CurCol, Col: Integer;
var InMass: TVS_MassData);
//Формируем массив минор для КоШИ_БИНЕ
//На входе
//CurCol - номер столбюца в новом массиве
//COl - номер столбца для массива, с которого будем брать значения
//InMass - массив, в который будем заносить значения
Var I: Integer;
begin
For I:= 0 To MassB.N -1 do
inMass.Mass[CurCol, I ]:= MassB.Mass[Col -1,I];
end;
Function TMainForm.VS_GetKoshi_Bine: Real;
//Вычисляем формулу Коши-Бине
// ьПеред вызовом должны быть выполнены след. условия:
//1 - введен масив а и б
//выполнены след. процедуры
//VS_InitMassPErebor;
//VS_Init2xMassPerebot;
//VS_SortMassPerebor;
//VS_GetMAssForDet
//
Var I: Integer;
S: String;
begin
Result:= 0;
S:= '';
For I:= 0 to MassA.N - 1 do
Begin
REsult:= REsult + DetA[I] * Detb[I];
S:= S + ' (' + FloattoStr(DetA[I])+ ')*(' + FloattoStr(DetB[I]) + ') + ';
end;
ResultMemo.Lines.Add('C = ' + (Copy(S, 1, Length(s) -2)));
end;
function TMainForm.VS_IfMassEq(Massin1, MAssIn2: TVS_MassData): Boolean;
//Сравниваем 2 мартицы
//Получаем True, если
//1. число строк матрицы 1 - числу столбцов матрицы 2
//2. число стоблцов матрицы 1 = числу строк матрицы 2
begin
Result:= (Massin1.M = MAssIn2.N) And (Massin1.N = MAssIn2.M)
end;
procedure TMainForm.VS_VerMass(var Massin1, MAssIn2: TVS_MassData);
//Проверяем матрицы
//Если Столбцв матрицы А меньше, чем в Б, меняем матрицы местами
Var TempMass: TVS_MassData;
begin
If Massin1.N < MAssIn2.N Then
Begin
SetLength(TempMass.Mass, MassIn1.M, MassIn1.N);
TempMass:= Massin1;
SetLength(Massin1.Mass, MassIn2.M, MassIn2.N);
Massin1:= MAssIn2;
SetLength(Massin2.Mass, TempMass.M, TempMass.N);
MAssIn2:= TempMass;
end;
end;
procedure TMainForm.VS_LoadData(var InMAss: TVS_MassData);
//Загружаем данные из файла в Массив InMAss
Var F: TextFile; //Описали переменную работы с текстовым файлом
RezStr: String;
CurRow,
MaxCol,
MaxRow,
CorCol: Integer;
begin
OpenDialog.DefaultExt:= '*.txt'; //Расширение файлов по умочлчанию
OpenDialog.InitialDir:= ExtractFilePath(Application.ExeName); //Открываем каталог, в котором запущена наша программа
MaXcol:= 0;
;
If OpenDialog.Execute Then
Begin //Если пользователь нажал на ОК и выбрал файл - начинаем загрузку
AssignFile(F, OpenDialog.FileName);
If FileExists(OpenDialog.FileName) Then
Reset(f) //Файл есть, открываем
Else Exit; //Файла нету, выходим
CurRow:= 0;
VS_GetRazmOnFile(OpenDialog.FileName, MaxCol, MaxRow);
SetLEngth(InMAss.Mass, MaxRow, MaxCol);
While Not Eof(F) Do
Begin
REadLn(F, RezStr);
VS_InitMassInStr(RezStr, CurRow, InMAss);
// ResultMemo.Lines.Add(RezStr);
Inc(CurRow);
end;{While Not Eof(F) Do}
InMass.M:= MaxRow;
InMAss.N:= MaxCol;
VS_ShowMassToMemo('Успешно загружен', InMAss);
end;{If OpenDialog.Execute Then}
end;
procedure TMainForm.N9Click(Sender: TObject);
begin
VS_LoadData(MassA);
end;
procedure TMainForm.VS_InitMassInStr(InStr: String; CurRow: Integer;
var InMass: TVS_MassData);
//Формируем строку элементов массива.
Var
N: Integer;
RezStr: String;
CurCol: Integer;
begin
inStr:= Trim(InStr); //Удалили пробелы с обоих концов строки
CurCol:= 0;
While Length(InStr) > 0 Do
Begin //Запускаем цикл до тех пор, пока строка имеет значения
N:= Pos(#32, InStr); //Нашли ближайший пробел
If N <> 0 Then
Begin // Действительно у нас нашелся прьблел
RezStr:= Copy(inStr, 1, N);
Delete (inStr,1, N);
RezStr:= Trim(RezStr); //Удалили лишние пробелы
Try //Включаем обработку ошибок
InMass.Mass[CurRow, CurCol]:= StrtoFloat(RezStr); //Присваиваем элемент массива из строк
except //Если авария
InMass.Mass[CurRow, CurCol]:= 0; //Присваиваем элемнту 0
end;
Inc(CurCol);//Перешли к след. стобцу массива
end {If N <> 0 Then}
Else
//Пробела нету, возможно, это последний символ
If Length(InStr)> 0 Then
Begin //Есть значение
Try //Включаем обработку ошибок
InMass.Mass[CurRow, CurCol]:= StrtoFloat(InStr); //Присваиваем элемент массива из строк
except //Если авария
InMass.Mass[CurRow, CurCol]:= 0; //Присваиваем элемнту 0
end;
Inc(CurCol);//Перешли к след. стобцу массива
InStr:= '';
end; {If Length(InStr)> 0 Then}
end;
end;
procedure TMainForm.VS_GetRazmOnFile(FileName: String; var Col,
Row: Integer);
Var F: TextFile; //Описали переменную работы с текстовым файлом
RezStr: String;
begin
Col:= 0;
Row:= 0;
AssignFile(F, FileName);
Reset(F);
While Not Eof(F) Do
Begin
ReadLn(F, RezStr);
If (Row = 0) And (Length(RezStr)<> 0) Then Col:= VS_GetColOnFile(RezStr);
Inc(Row);
end;{While Not Eof(F) Do}
CloseFile(f);
end;
function TMainForm.VS_GetColOnFile(InStr: String): Integer;
Var
N: Integer;
RezStr: String;
begin
inStr:= Trim(InStr); //Удалили пробелы с обоих концов строки
Result:= 0;
While Length(InStr) > 0 Do
Begin //Запускаем цикл до тех пор, пока строка имеет значения
N:= Pos(#32, InStr); //Нашли ближайший пробел
If N <> 0 Then
Begin // Действительно у нас нашелся прьблел
RezStr:= Copy(inStr, 1, N);
Delete (inStr,1, N);
RezStr:= Trim(RezStr); //Удалили лишние пробелы
Inc(Result);//Перешли к след. стобцу массива
end {If N <> 0 Then}
Else
//Пробела нету, возможно, это последний символ
If Length(InStr)> 0 Then
Begin //Есть значение
Inc(Result);//Перешли к след. стобцу массива
InStr:= '';
end; {If Length(InStr)> 0 Then}
end;
end;
procedure TMainForm.N10Click(Sender: TObject);
begin
VS_LoadData(MassB);
end;
end.