реклама на сайте
подробности

 
 
> Расчет обратной матрицы, Программа на Delphi
Andbiz
сообщение Oct 2 2011, 19:25
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 447
Регистрация: 16-11-08
Из: Украина, Донецк
Пользователь №: 41 684



Здравствуйте! Столкнулся по учебе с написанием программы, которая делает различные операции с матрицами (умножение, деление, вычитание, транспонирование и т.д.). Все операции сделал, кроме одной - обратная матрица.

В качестве метода расчета выбрал метод расчета с помощью матрицы алгебраических дополнений.

Принцип расчета - находится определитель матрицы. Затем создается транспонированная матрица алгебраических дополнений, каждый элемент которой делится на определитель матрицы.
Расчет определителя - получился и работает. А вот с алгебраическими дополнения возникли трудности

det:=1.0;
// начинаю прямой ход Гаусса
for k:=1 to n do
begin
det:=det*A[k,k]; //вычисление определителя
for j:=k+1 to n do
begin
A[k,j]:=A[k,j]/A[k,k];
end;
for i:=k+1 to n do //начало вложенного цикла
for j:=k+1 to m do
begin
r:=A[k,j]*A[i,k];
A[i,j]:=A[i,j]-r;
end;
end;
// Делаю транспонирование матрицы
begin
for i:=1 to n do
for j:=1 to m do
D[i,j]:=A[j,i];
for i:=1 to n do
for j:=1 to m do
C[i,j]:=(1/det)*D[i,j];
begin
for i:=1 to n do
for j:=1 to m do
StringGrid_C.Cells[j-1,i-1]:=FloatToStr(C[i,j]) // вношу полученное значение в матрицу С
end;
end;


Красным отмечен участок, который я неправильно написал. Я просто транспонировал матрицу (заменил строки столбцами) и разделил каждый элемент на определитель, но это оказалось неправильным расчетом.

Вот пример расчета обратной матрицы.
Прикрепленное изображение


Здесь находят так называемые миноры, которые и образуют обратную матрицу.
В интернете много примеров расчета обратных матриц на паскале, но я не могу их понять и поэтому решил писать свою программу. Определитель посчитан, нужно разобраться как находить миноры, а потом их уже домножать как в примере на -1 в степени суммы индексов и делить на определитель, расположив в новой матрице.
В интернете это описывают так:
Цитата
"Создадим массив для хранения союзной матрицы. Думаю нужно создать цикл в цикле (перебор всех членов матрицы). можно создать еще один, временный массив в котором будем хранить минор. ну и все опять же вызываем функцию по нахождению определителя и вписываем результат в союзную матрицу."

Как написать код, чтобы найти эти миноры?

P.S.
Я знаю, что в Delphi есть функции, которые позволяют рассчитывать матрицы более проще, но мне хочется разобраться с минорами.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Andbiz
сообщение Oct 4 2011, 04:57
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 447
Регистрация: 16-11-08
Из: Украина, Донецк
Пользователь №: 41 684



Ниже есть другие "end" - я их не скопировал, т.к. полностью вся программа больше и это участок этой программы. При копировании побоялся скоприовать лишние "end"ы (этот участок в самом конце) Примерно расставил соответстствие между begin и end цифрами. По поводу цикла по i и j, к которому относится C[i,j]:=((i+j)*ln(-1)*det_1)/det; - , то это

Код
for i:=1 to n do  // начинаю цикл обхода всех строк и столбиков матрицы А
                              for j:=1 to m do


Вот программа с "end" в конце программы

Код
    
                         begin
                         det:=1;
                         // начинаю прямой ход Гаусса
                         for k:=1 to n do
                         begin
                              det:=det*A[k,k]; //вычисление определителя
                              for j:=k+1 to n do
                              begin
                                   A[k,j]:=A[k,j]/A[k,k];
                              end;
                              for i:=k+1 to n do //начало вложенного цикла
                              for j:=k+1 to m do
                              begin
                              r:=A[k,j]*A[i,k];
                              A[i,j]:=A[i,j]-r;
                              end;
                         end;
                         Edit1.Text:=FloatToStr(det);
                         // Создаю союзную матрицу D
             (9)            begin
                              for i:=1 to n do  // начинаю цикл обхода всех строк и столбиков матрицы А
                              for j:=1 to m do
                 (8)             begin
                                   l:=1;
                                   p:=1;
                                   for i_1:=1 to n do // начинаю второй цикл обхода матрицы А, в котором будут отсеиваться одна строчка и один столбик
                                   for j_1:=1 to m do
                                       if (i_1<>i) and (j_1<>j)  // отсеиваю элементы, которые находятся в столбике или строчке рассматриваемого элемента матрицы
                                       then
                              (6)             begin
                                           D[l,p]:=A[i_1,j_1]; // вношу соответствующий элемент в временную матрицу D
                                           p:=p+1;  // прибавляю 1 к индексу столбика матрицы D
                                           if(p>(m-1)) // проверяю индекс столбика на крайнее значение, если оно больше (n-1) исходной таблицы, то перехожу на новую строку
                                           then
                             (7)              begin
                                           p:=1;  // при начале новой строки столбик приравниваю единице
                                           l:=l+1;  // и на одну строчку опускаюсь вниз, прибавив к l единицу
                           (7)                end;
                         (6)                  end;
                                (5)               begin
                                               if (n-1)=1 then det_1:=D[1,1]  // если матрица еденичная, то определитель определить легком
                                               else
                                               if (n-1)=2 then det_1:=(D[1,1]*D[2,2]-D[1,2]*D[2,1])  // если матрица имеет размерность 2*2, то определитель можно найти по следующей формуле
                                               else
                                           (4)         begin
                                                    det_1:=1;
                                                    // начинаю прямой ход Гаусса
                                                    for k:=1 to n-1 do
                                        (3)                begin
                                                        det_1:=det_1*D[k,k];  //вычисление определителя
                                                        for p:=k+1 to n-1 do
                                        (2)                    begin
                                                                 D[k,p]:=D[k,p]/D[k,k];
                                      (2)                      end;
                                                            for l:=k+1 to n-1 do  //начало вложенного цикла
                                                            for p:=k+1 to m-1 do
                                      (1)                    begin
                                                                 r:=D[k,p]*D[l,k];
                                                                 D[l,p]:=D[l,p]-r;
                                     (1)                       end;
                                         (3)               end;
                                       (4)             end;
                                                        C[i,j]:=(power((-1),(i+j))*det_1)/det; // рассчитываю соответствующий элемент матрицы С
                                                        StringGrid_C.Cells[i-1,j-1]:=FloatToStr(C[i,j])  // вношу рассчитанный элемент в матрицу
                              (5)                 end;
                                   (8)   end;

                     (9)     end;
                          end;


А куда по Вашему мнению нужно скопировать C[i,j]:=((i+j)*ln(-1)*det_1)/det;, что он был в цикле?
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 4 2011, 15:07
Сообщение #3


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



1) Всё уже сделано до нас. Найдите книгу Дж.Форсайт, М.Малькольм, К.Моулер "Машинные методы математических вычислений", Мир, 1980. В параграфе 3.3 приведено описание и текст программ DECOMP и SOLVE. Вам нужна первая. Вся программа занимает 3 листа, из них половина - комментарии.

2) Определитель считать не кошерно, более показательным параметром является число обусловленности матрицы cond(A). В книге оно тоже описывается (п.3.2). Если интересуетесь, то в конце книги есть обсуждение и программа сингулярного разложения матриц, весьма мощное вычислительное средство для анализа матричных задач (п.9.2).


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd August 2025 - 13:12
Рейтинг@Mail.ru


Страница сгенерированна за 0.02456 секунд с 7
ELECTRONIX ©2004-2016