Показать сообщение отдельно
Старый 14.06.2018, 14:28   #8 (permalink)
Vladimir_S
Специалист
 
Регистрация: 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.
Изображения
   
Vladimir_S вне форума   Ответить с цитированием
Ads

Яндекс

Member
 
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070