C++ での逆行列

Adnan Ashraf 2023年10月12日
  1. 逆行列
  2. 3x3 行列の逆行列の C++ 実装
C++ での逆行列

この記事では、逆行列とその C++ を使用した実装について説明します。 C++ の実装を簡単に理解するには、まず逆行列の概念を理解する必要があります。

逆行列

逆行列を見つけるには 3つの手順があります。 手順の説明を以下に示します。

  • 最初のステップでは、与えられた行列の行列式を計算します。
  • 2 番目のステップでは、行列式がゼロに等しくない場合、指定された行列の随伴を計算します。
  • 最後に、ステップ 2 で得られた行列に 1/determinant を掛けます。

逆行列の数式

S を 3 x 3 行列とします。 次に、その逆を求める式を以下に示します。

$$ Inverse\; of\; Matrix\; S\;= S^{-1}=\frac{1}{\operatorname{determinant}(S)} \operatorname{adjoint}(S) $$

注: 与えられた行列の行列式がゼロ (0) の場合、つまり行列が特異な場合、逆行列を見つけることはできません。

以下は、C++ で次数 3x3 の行列の逆行列を見つけるプログラムです。 簡単にするために、行列を格納するために配列を使用しました。

プログラムは、行列が特異でない場合にのみ逆行列を見つけます。 次のプロパティで答えを確認できます。

$$ S.S^{-1}=I $$

ここで、I は対角要素 1 を持つ恒等行列です。 上記のプロパティが成り立つ場合、私たちの答えは真になります。 それ以外の場合は false。

提案されたプログラムはモジュールに分割されます。

3x3 行列の逆行列の C++ 実装

逆行列は、ベクトル、テンプレート、およびクラスを使用して実装できます。 ただし、簡単にするために、3x3 行列の逆数を決定するために 2D 配列を使用します。

次に、解を一般化して、NxN 行列の逆行列を見つけることができます。

プログラムの構成要素を一つ一つ説明していきましょう。

メイン関数

int main()  // main function
{
  float matrix3X3[3][3];
  int r, c;
  float determinant = 0;
  for (r = 0; r < 3; r++) {
    for (c = 0; c < 3; c++) {
      cout << "Enter the value at index [" << r << "][" << c << "] : ";
      cin >> matrix3X3[r][c];
    }
  }
  display(matrix3X3);
  determinant = findDeterminant(matrix3X3);
  cout << "\n\nDeteterminant of the given matrix is : " << determinant;
  if (determinant != 0) {
    adjoint(matrix3X3);
    inverse(matrix3X3, determinant);
  } else {
    cout << " As the determinant of the given matrix is 0, so we cannot take "
            "find it's Inverse :";
  }
}

メイン関数では、逆行列を求める行列を作成しました。 次に、条件付きチェックを適用して、行列が特異かどうかを判断しました。

特異でない場合、逆行列は関数によって計算されます。 作成した各関数の説明です。

表示機能

void display(float matrix3X3[][3]) {
  printf("\nThe Elements of the matrix are :");
  for (int r = 0; r < 3; r++) {
    cout << "\n";
    for (int c = 0; c < 3; c++) {
      cout << matrix3X3[r][c] << "\t";
    }
  }
}

display 関数は、マトリックスを表示するために使用されます。 ここで matrix3X3 は値が表示される行列です。

行列式計算関数

float findDeterminant(float matrix3X3[][3]) {
  float det = 0;  // here det is the determinant of the matrix.
  for (int r = 0; r < 3; r++) {
    det = det + (matrix3X3[0][r] *
                 (matrix3X3[1][(r + 1) % 3] * matrix3X3[2][(r + 2) % 3] -
                  matrix3X3[1][(r + 2) % 3] * matrix3X3[2][(r + 1) % 3]));
  }
  return det;
}

findDeterminant 関数は、マトリックスの行列式を見つけるために使用されます。 ここで、det は行列式 matrix3X3 です。

行列式を見た後、逆行列が可能かどうかを判断できます。

随伴関数

void adjoint(float matrix3X3[][3]) {
  cout << "\n\nAdjoint of matrix is: \n";
  for (int r = 0; r < 3; r++) {
    for (int c = 0; c < 3; c++) {
      cout << ((matrix3X3[(c + 1) % 3][(r + 1) % 3] *
                matrix3X3[(c + 2) % 3][(r + 2) % 3]) -
               (matrix3X3[(c + 1) % 3][(r + 2) % 3] *
                matrix3X3[(c + 2) % 3][(r + 1) % 3]))
           << "\t";
    }
    cout << endl;
  }
}

adjoint 関数は、行列の随伴を見つけるために使用されます。 随伴行列を見つけたら、行列式の逆数を掛けて逆行列を見つけます。

逆関数

void inverse(float matrix3X3[][3], float d) {
  cout << "\n\nInverse of matrix is: \n";
  for (int r = 0; r < 3; r++) {
    for (int c = 0; c < 3; c++) {
      cout << ((matrix3X3[(c + 1) % 3][(r + 1) % 3] *
                matrix3X3[(c + 2) % 3][(r + 2) % 3]) -
               (matrix3X3[(c + 1) % 3][(r + 2) % 3] *
                matrix3X3[(c + 2) % 3][(r + 1) % 3])) /
                  d
           << "\t";
    }
    cout << endl;
  }
}

最後に、inverse 関数を使用して逆行列を計算します。 この関数では、随伴行列の各エントリが行列式で除算され、逆行列が求められます。

では、3x3 行列の逆行列の完全なコードを見てみましょう。

完全な C++ プログラム

#include <iostream>
using namespace std;
void display(float matrix3X3[][3]) {
  printf("\nThe Elements of the matrix are :");
  for (int r = 0; r < 3; r++) {
    cout << "\n";
    for (int c = 0; c < 3; c++) {
      cout << matrix3X3[r][c] << "\t";
    }
  }
}
// This function will calculate the determinant of the given matrix
float findDeterminant(float matrix3X3[][3]) {
  float det = 0;  // here det is the determinant of the matrix.
  for (int r = 0; r < 3; r++) {
    det = det + (matrix3X3[0][r] *
                 (matrix3X3[1][(r + 1) % 3] * matrix3X3[2][(r + 2) % 3] -
                  matrix3X3[1][(r + 2) % 3] * matrix3X3[2][(r + 1) % 3]));
  }
  return det;
}
// This function will calculate the adjoint of the given matrix
void adjoint(float matrix3X3[][3]) {
  cout << "\n\nAdjoint of matrix is: \n";
  for (int r = 0; r < 3; r++) {
    for (int c = 0; c < 3; c++) {
      cout << ((matrix3X3[(c + 1) % 3][(r + 1) % 3] *
                matrix3X3[(c + 2) % 3][(r + 2) % 3]) -
               (matrix3X3[(c + 1) % 3][(r + 2) % 3] *
                matrix3X3[(c + 2) % 3][(r + 1) % 3]))
           << "\t";
    }
    cout << endl;
  }
}
// This function will find the Inverse of the given matrix
void inverse(float matrix3X3[][3], float d) {
  cout << "\n\nInverse of matrix is: \n";
  for (int r = 0; r < 3; r++) {
    for (int c = 0; c < 3; c++) {
      cout << ((matrix3X3[(c + 1) % 3][(r + 1) % 3] *
                matrix3X3[(c + 2) % 3][(r + 2) % 3]) -
               (matrix3X3[(c + 1) % 3][(r + 2) % 3] *
                matrix3X3[(c + 2) % 3][(r + 1) % 3])) /
                  d
           << "\t";
    }
    cout << endl;
  }
}
int main()  // main function
{
  float matrix3X3[3][3];
  int r, c;
  float determinant = 0;
  for (r = 0; r < 3; r++) {
    for (c = 0; c < 3; c++) {
      cout << "Enter the value at index [" << r << "][" << c << "] : ";
      cin >> matrix3X3[r][c];
    }
  }
  display(matrix3X3);
  determinant = findDeterminant(matrix3X3);
  cout << "\n\nDeteterminant of the given matrix is : " << determinant;
  if (determinant != 0) {
    adjoint(matrix3X3);
    inverse(matrix3X3, determinant);
  } else {
    cout << " As determinant of the given matrix is 0, so we cannot take find "
            "it's Inverse :";
  }
}

入力行列が特異な場合の出力:

特異行列の出力

出力は、行列が特異な場合、アルゴリズムが逆行列を計算しないことを示しています。

入力行列が特異でない場合の出力:

非特異行列の出力

出力は、行列が特異でない場合にのみアルゴリズムが逆行列を計算することを示しています。