// ================================= ПИ МГОУ =============================== //
//                 ПРОГРАММА РАСЧЕТА РАНГА КВАДРАТНОЙ МАТРИЦЫ                //
//                             ЧЕТВЕРТОГО ПОРЯДКА                            //
// ------------------------- Консольное приложение ------------------------- //
//   Среда проектирования: C++Builder 5, автор: Костенко А.Г., группа: 6-33  //
//            Проект: ex2с.bpr, модуль: ex2с.cpp, дата: 16.11.2001           //
// =============================== Примечание ============================== //
//    Так как приложение консольное, для удобства его применения в программу //
// добавлена  операция  ожидания  нажатия  любой  клавиши  с помощью функции //
// getch(), что дает возможность запускать приложение  из любого окна опера- //
// ционной системы Windows.  Функция getch() останавливает завершение работы //
// программы до нажатия клавиши и окно режима MS-DOS, в котором функциониру- //
// ет настоящая консоль останется открытым до активизации клавиатуры.        //
// ========================================================================= //
#include <conio.h> // getch()
#include <stdio.h> // printf(), scanf()

// ***************************************************************************
// ** Функция расчета определителя матрицы 3-го порядка
float det3( float A[ 3 ][ 3 ] )
{
  return( A[ 0 ][ 0 ] * A[ 1 ][ 1 ] * A[ 2 ][ 2 ]
        + A[ 0 ][ 1 ] * A[ 1 ][ 2 ] * A[ 2 ][ 0 ]
        + A[ 0 ][ 2 ] * A[ 1 ][ 0 ] * A[ 2 ][ 1 ]
        - A[ 0 ][ 2 ] * A[ 1 ][ 1 ] * A[ 2 ][ 0 ]
        - A[ 0 ][ 1 ] * A[ 1 ][ 0 ] * A[ 2 ][ 2 ]
        - A[ 0 ][ 0 ] * A[ 1 ][ 2 ] * A[ 2 ][ 1 ] );
}

// ***************************************************************************
// ** Функция расчета определителя матрицы 4-го порядка
// ** методом применения разложения определителя по строке
float det4( float A[ 4 ][ 4 ] )
{
  float B[ 3 ][ 3 ];  // Вспомогательный массив для постоения матрицы 3-го
                        // для вычисления определителя матрицы 4-го порядка

  // Умножение минора 1-го слагаемого и вложение его во вспомогательную матрицу
  B[ 0 ][ 0 ] = A[ 0 ][ 0 ] * A[ 1 ][ 1 ];
  B[ 0 ][ 1 ] = A[ 0 ][ 0 ] * A[ 1 ][ 2 ];
  B[ 0 ][ 2 ] = A[ 0 ][ 0 ] * A[ 1 ][ 3 ];

  B[ 1 ][ 0 ] = A[ 0 ][ 0 ] * A[ 2 ][ 1 ];
  B[ 1 ][ 1 ] = A[ 0 ][ 0 ] * A[ 2 ][ 2 ];
  B[ 1 ][ 2 ] = A[ 0 ][ 0 ] * A[ 2 ][ 3 ];

  B[ 2 ][ 0 ] = A[ 0 ][ 0 ] * A[ 3 ][ 1 ];
  B[ 2 ][ 1 ] = A[ 0 ][ 0 ] * A[ 3 ][ 2 ];
  B[ 2 ][ 2 ] = A[ 0 ][ 0 ] * A[ 3 ][ 3 ];


  // Умножение минора 2-го слагаемого и вычитание его из вспомогательной матрицы
  B[ 0 ][ 0 ] -= A[ 0 ][ 1 ] * A[ 1 ][ 0 ];
  B[ 0 ][ 1 ] -= A[ 0 ][ 1 ] * A[ 1 ][ 2 ];
  B[ 0 ][ 2 ] -= A[ 0 ][ 1 ] * A[ 1 ][ 3 ];

  B[ 1 ][ 0 ] -= A[ 0 ][ 1 ] * A[ 2 ][ 0 ];
  B[ 1 ][ 1 ] -= A[ 0 ][ 1 ] * A[ 2 ][ 2 ];
  B[ 1 ][ 2 ] -= A[ 0 ][ 1 ] * A[ 2 ][ 3 ];

  B[ 2 ][ 0 ] -= A[ 0 ][ 1 ] * A[ 3 ][ 0 ];
  B[ 2 ][ 1 ] -= A[ 0 ][ 1 ] * A[ 3 ][ 2 ];
  B[ 2 ][ 2 ] -= A[ 0 ][ 1 ] * A[ 3 ][ 3 ];


  // Умножение минора 3-го слагаемого и сложение его со вспомогательной матрицей
  B[ 0 ][ 0 ] += A[ 0 ][ 1 ] * A[ 1 ][ 0 ];
  B[ 0 ][ 1 ] += A[ 0 ][ 1 ] * A[ 1 ][ 1 ];
  B[ 0 ][ 2 ] += A[ 0 ][ 1 ] * A[ 1 ][ 3 ];

  B[ 1 ][ 0 ] += A[ 0 ][ 1 ] * A[ 2 ][ 0 ];
  B[ 1 ][ 1 ] += A[ 0 ][ 1 ] * A[ 2 ][ 1 ];
  B[ 1 ][ 2 ] += A[ 0 ][ 1 ] * A[ 2 ][ 3 ];

  B[ 2 ][ 0 ] += A[ 0 ][ 1 ] * A[ 3 ][ 0 ];
  B[ 2 ][ 1 ] += A[ 0 ][ 1 ] * A[ 3 ][ 1 ];
  B[ 2 ][ 2 ] += A[ 0 ][ 1 ] * A[ 3 ][ 3 ];


  // Умножение минора 4-го слагаемого и вычитание его из вспомогательной матрицы
  B[ 0 ][ 0 ] -= A[ 0 ][ 1 ] * A[ 1 ][ 0 ];
  B[ 0 ][ 1 ] -= A[ 0 ][ 1 ] * A[ 1 ][ 1 ];
  B[ 0 ][ 2 ] -= A[ 0 ][ 1 ] * A[ 1 ][ 2 ];

  B[ 1 ][ 0 ] -= A[ 0 ][ 1 ] * A[ 2 ][ 0 ];
  B[ 1 ][ 1 ] -= A[ 0 ][ 1 ] * A[ 2 ][ 1 ];
  B[ 1 ][ 2 ] -= A[ 0 ][ 1 ] * A[ 2 ][ 2 ];

  B[ 2 ][ 0 ] -= A[ 0 ][ 1 ] * A[ 3 ][ 0 ];
  B[ 2 ][ 1 ] -= A[ 0 ][ 1 ] * A[ 3 ][ 1 ];
  B[ 2 ][ 2 ] -= A[ 0 ][ 1 ] * A[ 3 ][ 2 ];

  // Вычисление и возврат детерминанта
  return( det3( B ) );
}

// ****************************************************************************
// ** Гололовная программа
void main( void )
{
  float a[ 4 ][ 4 ], b[ 3 ][ 3 ], c[ 2 ][ 2 ]; // массивы
  int Rank,                 // ранг матрицы
      i, j, k, r, q, l, m, // индексы циклов и матриц
      di, dj, dr, dq;       // смещения индексов матриц для определения миноров
  float d;                  // детерминант матрицы

  // Предложить ввод данных
  printf( "\nEnter, please, array elements:\n" );

  // Заполнить массив значениями элементов
  for( i = 0; i < 4; i++ )
    for( j = 0; j < 4; j++ )
    {
      printf( "A[ %i ][ %i ] = ", i + 1, j + 1 );
      scanf( "%f", &a[ i ][ j ] );
    }

  // Вывести на экран матрицу
  for( i = 0; i < 4; i++ )
    printf( "\n %f %f %f %f ", a[ i ][ 0 ], a[ i ][ 1 ], a[ i ][ 2 ],  a[ i ][ 3 ] );

  // Проверить определитель на неравенство нулю
  if( ( d = det4( a ) ) != 0 ) // при положительном результате - ранг матрицы равен 4
    // Вывести значение детерминанта на экран
    printf( "determinant = %lf\n Rang = 4\n", d );
  else // иначе - проверить миноры 3-го порядка
  {
    i = 0; // индекс строки матрицы
    d = 0.0; // значение детерминанта минора
    // Условный цикл последовательного "вычеркивания" строк
    // из матрицы для получения минора,
    // ( при превышении индекса строки максимального значения
    // или при детерминанте текущего минора не равном нулю - цикл закончить )
    while( i < 4 && d == 0.0 )
    {
      di = 0; // смещение строкового индекса матрицы
      j = 0; // столбцовый индекс матрицы
      // Условный цикл последовательного "вычеркивания" столбцов
      // из матрицы для получения минора,
      // ( при превышении индекса строки максимального значения
      // или при детерминанте текущего минора не равном нулю - цикл закончить )
      while( j < 4 && d == 0.0 )
      {
        dj = 0; // смещение столбцового индекса матрицы
        // Вложенный цикл для взятия элементов матрицы в минор
        for( r = 0; r < 3; r++ )
        {
          // Если индекс строки минора совпадает с индексом строки матрицы
          // сделать смещение равным 1 для пропуска строки матрицы
          if( r == i ) di = 1;
          for( q = 0; q < 3; q++ )
          {
             // Если индекс столбца минора совпадает с индексом столбца матрицы
             // сделать смещение равным 1 для пропуска столбца матрицы
            if( q == j ) dj = 1;

             // Взять значение соответствующего элемента матрицы в ячейку минора
             b[ r ][ q ] = a[ r + di ][ q + dj ];
          }
        }
        // Определить детерминант минора
        d = det3( b );

        // Вывести на экран матрицу
        printf( "\n" );
        for( k = 0; k < 3; k++ )
           printf( "\n %f %f %f ", b[ k ][ 0 ], b[ k ][ 1 ], b[ k ][ 2 ] );

        // Вывести значение детерминанта на экран
        printf( " determinant = %lf", d );
        j++;
      }
      i++;
    }

    // После завершения циклов проверить определитель на неравенство 0
    if( d != 0.0 ) // при положительном результате - ранг матрицы равен 3
      printf( "\n Rang = 3\n" );
    else // иначе - проверить миноры 2-го порядка матрицы аналогичным
    { // алгоритмом, получая их из миноров 3-го порядка
      i = 0;
      d = 0.0;
      while( i < 4 && d == 0.0 )
      {
        di = 0;
        j = 0;
        while( j < 4 && d == 0.0 )
        {
          dj = 0;
          // Собрать минор 3-го порядка
          for( r = 0; r < 3; r++ )
          {
            if( r == i ) di = 1;
            for( q = 0; q < 3; q++ )
            {
               if( q == j ) dj = 1;
               b[ r ][ q ] = a[ r + di ][ q + dj ];
            }
          }
          r = 0;
          while( r < 3 && d == 0.0 )
          {
            q = 0;
            while( q < 3 && d == 0.0 )
            {
              dr = 0;
              // Вложенные циклы для формирования миноров 2-го порядка
              // из текущего минора 3-го порядка
              for( l = 0; l < 2; l++ )
              {
                if( l == r ) dr = 1;
                dq = 0;
                for( m = 0; m < 2; m++ )
                {
                  if( m == q ) dq = 1;
                  c[ l ][ m ] = b[ l + dr ][ m + dq ];
                }
                printf( "\n %f %f ", c[ l ][ 0 ], c[ l ][ 1 ] );
              }
              d = c[ 0 ][ 0 ] * c[ 1 ][ 1 ] - c[ 0 ][ 1 ] * c[ 1 ][ 0 ];
              printf( " determinant = %lf", d );
              q++;
            }
            r++;
          }
          j++;
        }
        i++;
      }
       // После завершения циклов проверить определитель на неравенство 0
      if( d != 0.0 ) // при положительном результате - ранг матрицы равен 2
        printf( "\n Rang = 2 \n" );
      else // иначе - проверить 1 элемент матрицы на неравенство 0
        if( a[ 0 ][ 0 ] != 0 ) // при положительном результате - ранг матрицы равен 1
          printf( "\n Rang = 1 \n" );
        else // иначе - ранг матрицы равен 0
          printf( "\n Rang = 0 \n" );
    }
  }

  printf( "\n Press any key..." );

  // Ждать нажатия клавиши
  getch();
}
// ================================ The end ==================================


Основная часть МГОУ.1007.601981.КР