Міністерство освіти і науки України
Національний університет «Львівська Політехніка»
Звіт
Про виконання розрахункової роботи
з курсу «алгоритмізація та програмування»
на тему:
«Побудова оберненої матриці
методом Гауса»
Обернена матриця
Як відомо, для кожного числа а≠0 існує обернене число, тобто таке число а-1, що а∙а-1 = а-1∙а = 1.
Оскільки в множині квадратних матриць n-го порядку роль одиниці відіграє одинична матриця Е, то природно, за аналогією, прийняти таке означення: матриця А називається оберненою для квадратної матриці А, якщо А?=А?=Е. Легко зрозуміти, що не для кожної квадратної матриці існує обернена матриця. Питання про існування для даної матриці А оберненої матриці виявляється складним. Зважаючи на некомутативність множення матриць ми говоритимемо зараз про праву обернену матрицю, тобто про таку матрицю А-1, що добуток матриці А справа на цю матрицю дає одиничну матрицю
AA-1 = E (1)
Якщо матриця А вироджена, то, якби матриця А-1 існувала, то добуток, що стоїть в лівій частині рівності (1), був би виродженою матрицею, тоді як насправді матриця E , яка стоїть в правій частині цієї рівності, є невиродженою, оскільки її визначник рівний одиниці. Таким чином, вироджена матриця не може мати правої оберненої матриці. Такі ж міркування показують, що вона не має і ліву обернену матрицю і тому для виродженої матриці обернена матриця взагалі не існує.
В даній програмі використовуємо метод Гауса. Відомо, що якщо, до матриці дописати справа одиничну матрицю, а потім з допомогою лінійних перетворень звести ліву матрицю до одиничної, проводячи ті ж перетворення над правою (одиничною) матрицею, то на її місці утвориться матриця, обернена до початкової. До лінійних перетворень належить додавання одного рядка, помноженного на довільний коефіцієнт, до другого. Розв'язок можна розбити на два етапи: «прямий» та «зворотний» хід.
Є початкова матриця, приписуємо до неї одиничну:
а[1,1], а[1,2], ..., а[1,n]; 1, 0, ..., 0;а[2,1], а[2,2], ..., а[2,n]; 0, 1, ..., 0;...а[n,1], а[n,2], ..., а[n,n]; 0, 0, ..., 1;Під час «прямого» ходу необхідно добитися нулів під головною діагоналлю лівої матриці. Беремо перший рядок і ділимо його на a[1,1]. Тепер на місці a[1,1] стоїть 1. Віднімаємо від першого рядка перший, помножений на a[2,1] – на місці цього елемента утворюється нуль. Аналогічно для всіх рядків до n-го. Тепер в першому стовпчику матриці нижче одиниці, стоять нулі.
Переходимо до другого рядка і для всіх рядків нижче другого повторюємо описану процедуру. Тепер нижче діагоналі і в другому рядку – нулі. Так продовжуємо до (n-1)-го рядка. Для n-го рядка достатньо поділити його на a[n,n]. Матриця А приведена до верхньої трикутної. На місці одиничної утворилася деяка матриця.
Зауваження 1. Якщо на місці діагонального елемента лівої матриці утвориться число близьке до нуля, то ділення на маленьке число призведе до значної похибки в обрахунках. Тому, необхідно, щоб це число було «далеким» від нуля. З цією метою робиться наступний крок: перед тим, як поділити рядок на цей елемент, добавимо до рядка всі нижче лежачі рядки (помножені на -1, якщо в цьому рядку стоїть негативний елемент).
Зворотний хід. Тут спочатку добиваємося нулів в останньому в стовпці матриці А. Для цього з кожного рядка (і) вище n-го віднімаємо n-ний рядок помножену на a[i,n]. Після цього добиваємося нулів в (n-1)-му стовпці і так далі до другого стовпця.
Тепер зліва маємо одиничну матрицю, а справа, на місці одиничної – шукана обернена матриця. Для перевірки перемножуємо її на початкову – повинна вийти обернена матриця.
program pz;
uses crt;
const
eps=0.00001; { Всі номери менші eps еквівалентні 0 }
type matr=array[1..10,1..10] of double;
var a,b,a0:matr;
i,j, np,n:integer;
procedure PrintMatr(m,m1:matr;);
var i,j:integer;
begin
for i:=1 to n do
begin
if (i=1) then write(np:2,':')
else write(' ');
for j:=1 to n do
write(m[i,j]:6:1);
for j:=1 to n do
write(m1[i,j]:6:1);
writeln;
end;
inc(np);
end;
procedure MultString(var a,b:matr;i1:integer;r:double);
var j:integer;
begin
for j:=1 to n do
begin
a[i1,j]:=a[i1,j]*r;
b[i1,j]:=b[i1,j]*r;
end;
end;
procedure AddStrings(var a,b:matr;i1,i2:integer;r:double);
{ Процедура додає до і1-го рядка матриці А і-ий помножений на r}
var j:integer;
begin
for j:=1 to n do
begin
a[i1,j]:=a[i1,j]+r*a[i2,j];
b[i1,j]:=b[i1,j]+r*b[i2,j];
end;
end;
procedure MultMatr(a,b:matr;var c:matr);
var i,j,k:byte;
s:double;
begin
for i:=1 to n do
for j:=1 to n do
begin
s:=0;
for k:=1 to n do
s:=s+a[i,k]*b[k,j];
c[i,j]:=s;
end;
end;
function sign(r:double):shortint;
begin
if (r>=0) then sign:=1 else sign:=-1;
end;
begin { початок основної програми }
write('Розмір матриці:');
read(n);
for i:=1 to n do
begin
for j:=1 to n do
begin
b[i,j]:=0;
write('a[',i,',',j,']='); {введення елементів матриці}
readln(a[i,j]);
end;
b[i,i]:=1; {відбувається присвоєння елементам головної діагоналі нульової матриці значення 1 (утворюємо одиничну матрицю)}
end;
for i:=1 to n do
for j:=1 to n do
a0[i,j]:=a[i,j];
writeln('Starting matrix:'); np:=0;
PrintMatr(a,b,6,1);
for i:=1 to n do
begin
for j:=i+1 to n do
AddStrings(a,b,i,j,sign(a[i,i])*sign(a[j,i]));
{ Прямий хід }
if (abs(a[i,i])>eps) then
begin
MultString(a,b,i,1/a[i,i]);
for j:=i+1 to n do
AddStrings(a,b,j,i,-a[j,i]);
end
else
begin
writeln('Оберненої матриці не існує');
readln;
exit;
end
end;
{Зворотній хід:}
if (a[n,n]>eps) then
begin
for i:=n downto 1 do
for j:=1 to i-1 do
begin
AddStrings(a,b,j,i,-a[j,i]);
end;
{ PrintMatr(a,b,n,8,4);}
end
else writeln('Оберненої матриці не існує');
MultMatr(a0,b,a);
writeln('Початкова матриця, Обернена до неї');
PrintMatr(a0,b,7,3);
writeln('Перевірка: повинна бути одинична матриця');
PrintMatr(a,a,7,3);
readln;
end.
Результати виконання:
1. Для матриці A знайти обернену матрицю.
/
Знайдемо обернену матрицю за формулою:
Рішення. Знаходимо спочатку детермінант матриці А:
/
Це означає, що обернена матриця існує і ми її можемо знайти по формулі /, де Аi j (i,j=1,2,3) - алгебраїчні доповнення до елементів аi j початкової матриці.
/ /
/ /
/ /
/ /
/
звідки /.
Результат на Turbo Pascal:
/
2. Знайти матрицю, обернену до матриці.
Знаходимо обернену матрицю за формулою:
A =
Знаходимо спочатку визначник матриці A:
Знаходимо обернену матрицю за формулою:
= = 1/(-1)4+1 = (-1) =
= (-1)1(-1)3+1= -1 0. Отже обернена матриця існує.
Знаходимо алгебраїчні доповнення:
A11=(-1)1+1= 2 A21=(-1)2+1= -1
A31=(-1)3+1= -1 A41=(-1)4+1= -1
A12=(-1)1+2= -1 A22=(-1)2+2= 1
A32=(-1)3+2= 0 A42=(-1)4+2= 0
A13=(-1)1+3= -1 A23=(-1)2+3= 0
A33=(-1)3+3= 1 A43=(-1)4+3= 0
A14=(-1)1+4= -1 A24=(-1)2+4= 0
A34=(-1)3+4= 0 A44=(-1)4+4= 1
Підставляючи у формулу (3) знайдені значення, одержуємо:
A-1 =
Перевірка. Одержаний результат можна легко перевірити.
Оскільки, AA-1 = E, де E –це одинична матриця, то:
AA-1 = =
=
=
Результат на Turbo Pascal:
/
Результати збігаються.
Висновок: в даній роботі я визначав обернену матрицю методом Гауса. Для реалізації цього завдання було створено користувацький тип та задіяно три матриці. Використав в даній роботі 4 поцедури (PrintMatr, MultMatr, AddString, MultString) та 1-ну функцію (sign). Обчистив обернену матрицю за формулою та з допомогою програми – результати збігаються.