#include <math.h>
// =======================================================================
// Решение системы линейных уравнений модифицированным методом
// Жордана-Гаусса с частичным выбором разрешающего элемента
// #define ABS(x) (((x)<0) ? -(x) : (x) )
#define ABS(x) (fabs(x))
/* =======================================================================
  Входные данные:
    - Rows - матрица систмы линейных уравнений;
    - B - вектор - столбец свободных членов;
    - N - порядок системы.
  Выход:
    0 если система не имеет единственного решения;
    1 если решение найдено;
    Матрица B содержит решение, матрица A неопределенна.
======================================================================= */
extern int __pascal mp_mtMatSolve(double **Rows, double *B, int N)
{
  int i,j,k,ind;
  double elem,max,b,*row;
  // Цикл по столбцам матрицы системы
  for(k=0;k<N;k++)
  {
    // За разрешающий элемент берем наибольший по модулю из непреобра-
    // зованной части текущего столбца, затем переставляем k-ю строку
    // со строкой, в которой находится разрешающий элемент.
    ind=k;
    max=ABS(Rows[ind][k]);
    for(i=ind+1;i<N;i++)
    {
      elem=ABS(Rows[i][k]);
      if(elem>max)
      {
        ind=i;
        max=elem;
      }
    }
//    if(max=0.0) return 0;
    // Перестановка строк матрицы A и элементов столбца B
    if(ind!=k)
    {
      row=Rows[ind];
      Rows[ind]=Rows[k];
      Rows[k]=row;
      b=B[ind];
      B[ind]=B[k];
      B[k]=b;
    }
    // Собственно решение.
    elem = Rows[k][k];
    for(j=k+1;j<N;j++)
      Rows[k][j]/=elem;
    B[k]/=elem;
    // Непреобразованная часть матрицы состоит из двух подматриц:
    // - верхней: (0,k+1) - (k-1,N-1)
    // - нижней:  (k+1,k+1) - (N-1,N-1)
    // Элементы подматриц пересчитываются по правилу прямоугольника.
    for(i=0;i<k;i++)
    {
      for(j=k+1;j<N;j++)
        Rows[i][j]-=Rows[i][k]*Rows[k][j];
      B[i]-=Rows[i][k]*B[k];
    }
    for(i=k+1;i<N;i++)
    {
      for(j=k+1;j<N;j++)
        Rows[i][j]-=Rows[i][k]*Rows[k][j];
      B[i]-=Rows[i][k]*B[k];
    }
  }
  return 1;
}
