Показать сообщение отдельно
  #7  
Старый 01.09.2012, 01:02
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Примерно так:

Код:
{*** Решение уравнений методом Гаусса - Жордана ***}
unit GausJordan;

interface

type
  TInMatr		= array[0..19] of array[0..19] of Double;
  TOutMatr		= array[0..19] of Double;

const
  GAUSS_ACCURACY	= 0.0000001;
  GAUSS_OK		= 0;
  GAUSS_NOSOL		= 1;
  GAUSS_MANYSOL		= 2;

function gauss(a : TInMatr; n, u : Integer; var x : TOutMatr) : Integer;

implementation

{********************************************* 
 * Функция решения систем линейных уравнений * 
 * методом Гаусса - Жордана                  * 
 * (C) 2002 Восков Алексей                   * 
 * версия 2.1                                * 
 *********************************************}
// ВХОДНЫЕ ДАННЫЕ
{  a[20][20] - Матрица для хранения системы a[y][x] 
           последний столбец - для хранения св. члена 
           св. член - в правой части 
   n - число неизвестных    
   u - число уравнений    
   ВЫХОДНЫЕ ДАННЫЕ    
   x[20] - массив для хранения корней системы      
   в случае нормального выполнения задачи функция возвращает 0, 
   в случае неразрешимости 1   в случае бесконечного числа решений 2 }

function gauss(a : TInMatr; n, u : Integer; var x : TOutMatr) : Integer;
var 
  i, j, k : Integer;		// Счетчики циклов
  sn      : Integer;		// Номер строки
  d       : Double;		// Коэффициент домножения или модуль наиб. эл.
begin  
  Result := GAUSS_OK;		// Нормальное завершение работы
  
  //*** Проверка u и n ***
  if n > u then
  begin
    Result := GAUSS_MANYSOL;
    Exit;
  end;
  
  //*** Приведение к диагональному виду ***
  for j := 0 to n - 1 do
  begin         
    // а) поиск строки с наибольшим по модулю элементом
    d  := Abs(a[j][j]);
    sn := j;

    for i := j to u - 1 do
      if Abs(a[i][j]) > d then
      begin
        d  := Abs(a[i][j]);
        sn := i;
      end;
       
    // б) перенос строки на надлежащее место
    for k := 0 to n do
    begin
      d := a[sn][k];
      a[sn][k] := a[j][k];
      a[j][k]  := d;
    end;
     
    // в) деление ведущего ур-я на главный элемент
    d := a[j][j];
     
    if d > 0 then
      for k := 0 to n do
        a[j][k] := a[j][k] / d
    else
      for k := 0 to n do
        a[j][k] := 0;
       
    // г) вычитание данной строки из всех остальных
    //    с домножением на коэффициент
    for i := 0 to u - 1 do
    begin
      if i = j then
        Continue;			// Не трогаем вычит. строку
      d := -a[i][j];

      for k := 0 to n do		// Вычитание
        a[i][k] := a[i][k] + a[j][k] * d;
    end;
  end;

  //*** Вычисление корней ***
  // а) проверка системы на разрешимость
  if u > n then
  begin
    for i := n to u - 1 do
    begin
      k := 0;
      for j := 0 to n - 1 do
        if Abs(a[i][j]) > GAUSS_ACCURACY then
          k := 1;
 
      if (k = 0) and (Abs(a[i][n]) > GAUSS_ACCURACY) then
      begin
        Result := GAUSS_NOSOL;
        Exit;
      end;
    end;
  end;
   
  // б) поиск корней
  for i := 0 to n - 1 do
  begin
    x[i] := -a[i][n];

    if a[i][i] <> 1 then		// Обработка ошибок
    begin
      if x[i] > 0 then
      begin
        Result := GAUSS_NOSOL;		// Решений нет
        Exit;
      end
      else
      begin
        Result := GAUSS_MANYSOL;	// Бесконечно много решений
        Exit;
      end;
    end;

    if Abs(x[i]) < GAUSS_ACCURACY then
      x[i] := 0;			// Обнуление слишком малых знач.
  end;
end;

end.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием