Помощь - Поиск - Пользователи - Календарь
Полная версия: Обратная матрица
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Pasha
Собственно требуется найти матрицу обратную данной! (способ нахождения не принципиален)
Нужно ввести размерность квадратной матрицы (мах 10*10), затем ручками ввести её, и вывести на экран результат..


Думал по зубам прога, а оказалось что зубов вовсе нету sad.gif Подскажите пожалуйста .. в понедельник сдавать уже.
volvo
Ну, раз способ не принципиален, то попробуй скачать модуль, который я выкладывал здесь: FAQ: Матрицы, там обрати внимание на функции matrixInvert (для инвертирования) и mxInput (для ввода матрицы)
Guest
Под словами "(способ нахождения не принципиален)" я имелл ввиду алгебраический способ.
А вот на паскале мне нужно что бы всё было без модулей! ! ! там всякие процедуры и функции можно...

честно говоря я что то не разобрался как воспользоватся твоим модулем...
Altair
{
       НАХОЖДЕНИЕ ОБРАТНОЙ МАТРИЦЫ

     Используется псевдо-метод Гаусса.
Если к матрице приписать справа единичную матрицу, а затем с
помощью линейных  преобразований привести левую матрицу к единичной,
 проводя те же  преобразования над правой (изначально единичной)
 матрицей, то на ее месте образуется матрица, обратная к исходной.
  К линейным преобразованиям относятся прибавление одной строки,
  умноженной на произвольный  коэффициент, к другой. Решение можно
  разбить на два этапа: "прямой" и  "обратный" ход.
      Есть исходная матрица, приписываем к ней единичную:
      а[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;
      Во время "прямого" хода необходимо добиться нулей под главной
      диаганалью левой матрицы. Берем первую строку и делим ее на а[1,1].
      Теперь на месте  а[1,1] стоит 1. Вычитаем из второй строки первую
      умноженную на а[2,1] - на месте этого элемента появляется ноль.
      Аналогично для всех строк до n-ой.
      Теперь в первом столбце матрицы ниже единицы стоят нули.
      Переходим ко второй строке и для всех строк ниже второй повторям
      описанную процедуру. Теперь ниже диагонали и во второй строке нули.
      Так продолжаем до (n-1)-ой строки. Для n-ной строки достаточно
      разделить ее на а[n,n].
      Матрица а приведена к верхней треугольной. На месте единичной обр
      азовалась некая матрица.
!! Если на месте диагонального элемента левой матрицы образуется число
близкое к нулю, то деление на малое число приведет к   значительной
погрешности вычисления. Поэтому необходимо, чтобы это число было "далеко"
от нуля. С этой целью предпринимается следующий шаг: перед тем, как
 разделить строку на этот элемент, прибавим к строке все нижележащие
 строки (умноженные на -1 если в этом столбце стоит отрицательный элемент).
      Обратный ход. Здесь сначала добвиваемся нулей в последнем столбце
      матрицы а. Для этого из каждой строки (i) выше n-ной вычитаем n-ную
      умноженную на а[i,n]. Затем добиваемся нулей в (n-1)-ом столбце и так
       далее до второго  столбца.
      Теперь слева имеем единичную матрицу, а справа, на месте единичной -
       искомая обратная матрица. Для проверки перемножим ее на начальную -
       олжна  получиться единичная.
}
const
 n=3;
 eps=0.000000001; { all numbers less than eps are equal 0 }
type matr=array[1..n,1..n] of real;
var
 a,b,a0:matr;
 i,j,imx,np:integer;
 s0,s1:real;
procedure PrintMatr(m,m1:matr;n,nz,nd:integer);
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]:nz:nd);
  for j:=1 to n do write(m1[i,j]:nz:nd);
  writeln;
 end;
 inc(np);
end;

procedure MultString(var a,b:matr;i1:integer;r:real);
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:real);
{ Процедура прибавляет к i1 строке матрицы a i2-ю умноженную на 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:real;
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:real):shortint;
begin
 if (r>=0) then sign:=1 else sign:=-1;
end;


{MAIN}
begin
 randomize;
 for i:=1 to n do
 begin
  for j:=1 to n do
  begin
   b[i,j]:=0;
   a[i,j]:=1.0*random(8)-4;
  end;
  b[i,i]:=1;
 end;
      { отладочные присвоения}
      a[1,1]:= 1; a[1,2]:=-1; a[1,3]:= 2; {a[1,4]:= 0;}
      a[2,1]:= 0; a[2,2]:=-2; a[2,3]:= 3; {a[2,4]:= 5;}
      a[3,1]:= 0; a[3,2]:=-1; a[3,3]:= 1; {a[3,4]:= 2;
      a[4,1]:= 0; a[4,2]:=-2; a[4,3]:= 3; a[4,4]:=-4;

      a[1,1]:= 5; a[1,2]:= 7; a[1,3]:= 7; a[1,4]:= 1;
      a[2,1]:= 6; a[2,2]:= 6; a[2,3]:= 3; a[2,4]:= 4;
      a[3,1]:= 5; a[3,2]:= 1; a[3,3]:= 1; a[3,4]:= 1;
      a[4,1]:= 3; a[4,2]:= 3; a[4,3]:= 3; a[4,4]:= 3;
      }
 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,n,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]));
  {  PrintMatr(a,b,n,6,1);}
  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]);
   {    PrintMatr(a,b,n,6,1);}
  end else
  begin
   writeln('Обратной матрицы не существует.');
   halt;
  end
 end;
 {writeln('Обратный ход:');}
 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,n,7,3);
 writeln('Проверка: должна быть единичная матрица.');
 PrintMatr(a,a,n,7,3);
end.

Guest
www.pscal.al.ru ;)
Это конечно круто НО! этим я уже пользовался smile.gif
Да и потом тут используется автозаполнение случайными числами а мне нужно что бы я сам вводил матрицу ...
volvo
Цитата(Guest @ 3.06.05 22:02)
Это конечно круто НО! этим я уже пользовался smile.gif

А что, у нас тут есть телепаты, чтобы знать, кто чем пользовался, а кто-нет?
Вот я немного изменил свою программу из FAQ-а (только учти, обработки ошибок нет, чуть что - программа вылетит):
Altair
Цитата
Да и потом тут используется автозаполнение случайными числами а мне нужно что бы я сам вводил матрицу ...

А переписать пару строчек для ручного ввода слабо?

Цитата
www.pscal.al.ru
Это конечно круто НО! этим я уже пользовался

Дело бы пошло гораздо быстрее, если бы ты сразу сказал что пользовался этим и что тебе не подошло здесь, проще что-то дописать или изменить ...
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.