Специалист
Регистрация: 27.08.2008
Адрес: Санкт-Петербург
Сообщений: 27,807
Сказал(а) спасибо: 340
Поблагодарили 583 раз(а) в 208 сообщениях
Репутация: 113184
|
Уф, ну, не знаю, актуально ещё или нет, но, признаться, самого "заело". Вроде "добил".
Несколько замечаний.
1. Программа зациклена с возможностью выхода.
2. Транспонирование матрицы сделано "по рабоче-крестьянски", т.е. с генерацией другой матрицы, а не с преобразованием исходной. Это нужно затем, чтобы сохранить исходную матрицу для последующих действий, не куроча её.
3. Поиск обратной матрицы сделан "из первых принципов", т.е. процедура написана "с нуля". В принципе, ошибка может возникнуть, если диагональный элемент обнулился, а на него надо делить. Для такого случая предусмотрено завершение программы с выводом сообщения о невозможности решения. Впрочем, сколько ни гонял, на такое не напоролся ни разу. Вероятно, это может возникнуть, если матрица вырождена, но вырожденную матрицу нужно специально строить, случайное же её появление очень маловероятно.
Код:
program lr;
type
mtr = array[0..9, 0..9] of real;
const
eps = 0.00001;{ all numbers less than eps are equal to zero }
var
a,b,d:mtr;
w,i,j,s1,s2,n:byte;
procedure Trans(m1:mtr;var m2:mtr);
var
i,j:byte;
begin
for i:=0 to n-1 do
for j:=0 to n-1 do
m2[i,j]:=m1[j,i];
end;
function Scal(a:mtr; st,sb:byte):real;
var
i:byte;
s:real;
begin
s:=0;
for i:=0 to n-1 do
s:=s+a[st-1,i]*a[i,sb-1];
scal:=s;
end;
procedure PrintMatr(m:mtr);
var
i,j:integer;
begin
for i:=0 to n-1 do
begin
for j:=0 to n-1 do
write(m[i,j]:8:3);
writeln;
end;
end;
procedure Inversion(m:mtr; var c:mtr);
var
m1,e:mtr;
i,j,k,p,r:byte;
Q,Dummy:real;
begin
for i:=0 to n-1 do
for j:=0 to n-1 do
begin
m1[i,j]:=m[i,j];
e[i,j]:=0;
end;
for i:=0 to n-1 do e[i,i]:=1;
{Avers}
for k:=0 to n-1 do
begin
Q:=m1[k,k];
if Abs(Q)<eps then
begin
Writeln('No solution!');
Readln;
Halt;
end
else
begin
for j:=0 to n-1 do
begin
m1[k,j]:=m1[k,j]/Q;
e[k,j]:=e[k,j]/Q;
end;
for i:=k+1 to n-1 do
begin
Q:=m1[i,k];
if Abs(Q)<eps then
m1[i,k]:=0
else
for j:=0 to n-1 do
begin
m1[i,j]:=m1[i,j]/Q;
e[i,j]:=e[i,j]/Q;
m1[i,j]:=m1[k,j]-m1[i,j];
e[i,j]:=e[k,j]-e[i,j];
end;
end;
end;
end;
{Revers}
for k:=n-1 downto 0 do
begin
Q:=m1[k,k];
if Abs(Q)<eps then
begin
Writeln('No solution!');
Readln;
Halt;
end
else
begin
for j:=n-1 downto 0 do
begin
m1[k,j]:=m1[k,j]/Q;
e[k,j]:=e[k,j]/Q;
end;
if k>0 then
begin
for i:=k-1 downto 0 do
begin
Q:=m1[i,k];
if Abs(Q)<eps then
m1[i,k]:=0
else
for j:=n-1 downto 0 do
begin
m1[i,j]:=m1[i,j]/Q;
e[i,j]:=e[i,j]/Q;
m1[i,j]:=m1[i,j]-m1[k,j];
e[i,j]:=e[i,j]-e[k,j];
end;
end;
end;
end;
end;
for i:=0 to n-1 do
for j:=0 to n-1 do
c[i,j]:=e[i,j];
end;
procedure MultMatr(a,b:mtr; var c:mtr);
var
i,j,k:byte;
s:real;
begin
for i:=0 to n-1 do
for j:=0 to n-1 do
begin
s:=0;
for k:=0 to n-1 do
s:=s+a[i,k]*b[k,j];
c[i,j]:=s;
end;
end;
Begin
repeat
write('Enter the matrix size from 2 to 10, n = ');
readln(n);
until n in [2..10];
randomize;
for i:=0 to n-1 do
for j:=0 to n-1 do a[i,j]:=1+random(10);
Repeat
writeln;
writeln('Choose the action:');
writeln('1 - Matrix transposition');
writeln('2 - Scalar product of string and column');
writeln('3 - Inverse matrix');
writeln('4 - Quit');
repeat
readln(w);
until w in [1..4];
case w of
1:
begin
Trans(a,b);
Writeln('Initial matrix:');
PrintMatr(a);
Writeln;
Writeln('Transposed matrix:');
PrintMatr(b);
end;
2:
begin
repeat
Writeln('Initial matrix:');
PrintMatr(a);
Writeln;
write('Enter the string number from 1 to ', n, ' s1 = ');
readln(s1);
if (s1>n) then
writeln('String with this number does not exist');
until s1 in [1..n];
repeat
write('Enter the column number from 1 to ', n, ' s2 = ');
readln(s2);
if (s2>n) then
writeln('Column with this number does not exist');
until s2 in [1..n];
writeln('Scalar product of string ',s1,' and column ', s2, ' = ', Scal(a,s1,s2):0:3);
end;
3:
begin
Inversion(a,b);
Writeln('Initial matrix:');
PrintMatr(a);
Writeln;
Writeln('Inverse matrix:');
PrintMatr(b);
Writeln;
Writeln('Test. Product of initial and inverse matrix:');
MultMatr(a,b,d);
PrintMatr(d);
end;
end;
Until w=4;
End.
|