C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++で正方行列の行列式を計算する方法|再帰呼び出しによる実装例

行列式とは?

正方行列の行列式(determinant)は、行列の要素の値から求められるスカラー値です。行列Aの行列式は「det(A)」と表記され、幾何学においては、その行列が表す線形変換のスケーリング係数(面積・体積の拡大率)と考えることができます。

2次の正方行列の場合は、「ad − bc」という公式で簡単に計算できます。以下に具体例を示します。

行列:
3 1
2 7

行列式 = 3 × 7 − 1 × 2
      = 21 − 2
      = 19
よって、この行列の行列式は 19 です。

行列式を計算するC++プログラム

以下は、キーボードから入力した任意のサイズの正方行列に対して、余因子展開(cofactor expansion)を用いて行列式を再帰的に計算するC++プログラムです。

サンプルコード

#include<iostream>
#include<math.h>
using namespace std;
int determinant( int matrix[10][10], int n) {
    int det = 0;
    int submatrix[10][10];
    if (n == 2)
    return ((matrix[0][0] * matrix[1][1]) - (matrix[1][0] * matrix[0][1]));
    else {
        for (int x = 0; x < n; x++) {
            int subi = 0;
            for (int i = 1; i < n; i++) {
                int subj = 0;
                for (int j = 0; j < n; j++) {
                    if (j == x)
                    continue;
                    submatrix[subi][subj] = matrix[i][j];
                    subj++;
                }
                subi++;
            }
            det = det + (pow(-1, x) * matrix[0][x] * determinant( submatrix, n - 1 ));
        }
    }
    return det;
}
int main() {
    int n, i, j;
    int matrix[10][10];
    cout << "Enter the size of the matrix:\n";
    cin >> n;
    cout << "Enter the elements of the matrix:\n";
    for (i = 0; i < n; i++)
    for (j = 0; j < n; j++)
    cin >> matrix[i][j];
    cout<<"The entered matrix is:"<<endl;
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++)
        cout << matrix[i][j] <<" ";
        cout<<endl;
    }
    cout<<"Determinant of the matrix is "<< determinant(matrix, n);
    return 0;
}

実行結果

Enter the size of the matrix: 3
Enter the elements of the matrix:
7 1 3
2 4 1
1 5 1
The entered matrix is:
7 1 3
2 4 1
1 5 1
Determinant of the matrix is 10

このように、3×3の行列に対して行列式「10」が正しく求められています。

プログラムの解説

① 入力と結果表示(main関数)

main()関数では、まず行列のサイズnを読み込み、続けてn×n個の要素を標準入力から受け取ります。入力された行列を画面に表示した後、determinant()関数を呼び出し、その戻り値である行列式を出力します。該当するコード部分は以下の通りです。

cout << "Enter the size of the matrix:\n";
cin >> n;
cout << "Enter the elements of the matrix:\n";
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
cin >> matrix[i][j];
cout<<"The entered matrix is:"<<endl;
for (i = 0; i < n; i++) {
    for (j = 0; j < n; j++)
    cout << matrix[i][j] <<" ";
    cout<<endl;
}
cout<<"Determinant of the matrix is "<< determinant(matrix, n);

② 基本ケース:サイズが2の場合

determinant()関数の中では、行列のサイズが2のときに限り、公式に従って行列式を直接計算し、その値を即座に返します。これが再帰処理の終了条件(基本ケース)となります。

if (n == 2)
return ((matrix[0][0] * matrix[1][1]) - (matrix[1][0] * matrix[0][1]));

③ 再帰ケース:サイズが3以上の場合

サイズが2以外の場合は、第1行に沿った余因子展開によって再帰的に行列式を計算します。ループ変数x、i、jを用いた3重のforループで、注目している要素(0行x列)を取り除いた(n−1)次の小行列submatrixを作成します。その後、determinant()関数を再帰的に呼び出して小行列の行列式を求め、符号項(−1)^xと第1行の要素matrix[0][x]を掛け合わせた値を累積変数detに加算していきます。

for (int x = 0; x < n; x++) {
    int subi = 0;
    for (int i = 1; i < n; i++) {
        int subj = 0;
        for (int j = 0; j < n; j++) {
            if (j == x)
            continue;
            submatrix[subi][subj] = matrix[i][j];
            subj++;
        }
        subi++;
    }
    det = det + (pow(-1, x) * matrix[0][x] * determinant( submatrix, n - 1 ));
}

なお、pow()関数の戻り値はdouble型ですが、ここでは±1の符号生成のみに使われるため、実用上問題ありません。このような再帰構造を利用することで、任意の次数の正方行列の行列式を段階的に求めることができます。

  1. C++でべき等行列を判定するプログラムの作成方法

    行数を r、列数を c とする行列 M[r][c] が与えられ、r = c となる正方行列を考えます。この記事では、与えられた正方行列がべき等行列(アイデンポテント行列)であるかどうかを判定するC++プログラムを解説します。 べき等行列とは 行列 M がべき等行列であるとは、行列 M と自分自身の積が元の行列 M と等しくなること、すなわち M × M = M が成り立つことを指します。 例えば、次の行列を見てください。 この行列を自分自身で掛け合わせても、結果は元の行列とまったく同じになります。したがって、この行列はべき等行列であると言えます。 べき等行列の代表的な例としては、ベクトルを

  2. C++でグラフの隣接行列を実装する方法【サンプルコード付き解説】

    隣接行列とは グラフの隣接行列(Adjacency Matrix)とは、V×Vのサイズを持つ正方行列のことです。ここでVはグラフGの頂点数を表します。行列の行と列にはそれぞれ頂点が対応付けられ、頂点iから頂点jへの辺が存在する場合は、i行目・j列目の要素に1が格納されます(重み付きグラフの場合は、辺の重みなどの非ゼロの値が入ります)。辺が存在しない場合は0が格納されます。 なお、無向グラフの場合、辺は双方向につながりを持つため、隣接行列は必ず対称行列になります。つまり、adj[i][j]とadj[j][i]は常に同じ値となります。 隣接行列表現の計算量 空間計算量: 隣接行列にはO(V²)