Смекни!
smekni.com

Определитель произведения прямоугольных матриц. Теорема Коши-Бине (стр. 11 из 11)

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.