【C++】n次行列式の計算

4328 ワード

基本思想.
まず、対角線要素mat[i][i]の絶対値が以下の要素の絶対値より大きいことを保証するために、n次行列式を行交換操作する.次に行列式を簡略化し、上三角形行列にし、最後に対角線要素の積だけを必要とします.
コード#コード#
#include <cmath>
#include <iomanip>
#include <iostream>
using namespace std;

int main() {
  double mat[10][10] = {0};
  double n; // The size of a matrix
  cin >> n;
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < n; ++j)
      cin >> mat[i][j];
  int sign = 0; // Record the sign of the result
  for (int i = 0; i < n - 1; ++i) {
    int t = i; // Record the row having the diagonal element with the biggest
               // absolute value
    double max =
        mat[i]
           [i]; // Record the diagonal element with the biggest absolute value
    for (int j = i + 1; j < n; ++j) { // Scan from the i + 1 row
      if (fabs(max) < fabs(mat[j][i])) {
        max = mat[j][i];
        t = j;
      }
    }
    if (t != i) { // If we find a row having the diagonal element with the
                  // biggest absolute value,
                  // then exchange t row and i row
      ++sign;
      for (int j = i; j < n; ++j) {
        double tmp = mat[i][j];
        mat[i][j] = mat[t][j];
        mat[t][j] = tmp;
      }
    }
    // Simiplify the matrix to echelon
    for (int j = i + 1; j < n; ++j) {
      double factor =
          mat[j][i] /
          mat[i][i]; // Record the factor which is used to construct echelon
      for (int k = i; k < n; ++k)
        mat[j][k] -= mat[i][k] * factor;
    }
  }
  double res = 1.0;
  for (int i = 0; i < n; ++i)
    res *= mat[i][i];
  if (sign % 2) // If the sign is odd, we get a negative number
                // If the sign is even, we get a positive number
    cout << fixed << setprecision(0) << -res << endl;
  else
    cout << fixed << setprecision(0) << res << endl;
  return 0;
}