【C言語】4×4の逆行列を作成する

この記事では、C言語を使用して4×4行列の逆行列を求める方法を解説します。

掃き出し法と行列式を用いた方法の2つの手法を紹介し、サンプルコードを通じて具体的な手順を示します。

初心者の方でもわかりやすく、実際のプログラムの実行結果も紹介します。

目次から探す

4×4行列の逆行列の求め方

4×4行列の定義

4×4行列は、4行4列の要素を持つ行列です。

C言語では、2次元配列を使用して4×4行列を表現します。

以下のように定義されます。

float matrix[4][4];

4×4行列の要素

4×4行列は、16個の要素を持ちます。

要素は行と列のインデックスを指定してアクセスすることができます。

例えば、行列の2行3列目の要素にアクセスするには、以下のようにします。

float element = matrix[1][2];

4×4行列の逆行列の求め方

4×4行列の逆行列を求める方法には、主に2つの方法があります。

掃き出し法と行列式を用いた方法です。

掃き出し法による4×4行列の逆行列の求め方

掃き出し法は、行列を上三角行列に変換する手法です。

以下の手順で逆行列を求めることができます。

  1. 単位行列を作成します。

単位行列は、対角線上の要素が1で、それ以外の要素が0の行列です。

  1. 元の行列と単位行列を結合します。
  2. 掃き出し法を用いて、元の行列を上三角行列に変換します。
  3. 上三角行列になった行列を逆行列とします。

以下に、掃き出し法を用いた4×4行列の逆行列の求め方のサンプルコードを示します。

#include <stdio.h>
void inverseMatrix(float matrix[4][4], float inverse[4][4]) {
    // 単位行列を作成
    float identity[4][4] = {
        {1, 0, 0, 0},
        {0, 1, 0, 0},
        {0, 0, 1, 0},
        {0, 0, 0, 1}
    };
    // 元の行列と単位行列を結合
    float augmented[4][8];
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            augmented[i][j] = matrix[i][j];
            augmented[i][j + 4] = identity[i][j];
        }
    }
    // 掃き出し法による上三角行列への変換
    for (int i = 0; i < 4; i++) {
        for (int j = i + 1; j < 4; j++) {
            float ratio = augmented[j][i] / augmented[i][i];
            for (int k = 0; k < 8; k++) {
                augmented[j][k] -= ratio * augmented[i][k];
            }
        }
    }
    // 上三角行列を逆行列とする
    for (int i = 3; i >= 0; i--) {
        float diagonal = augmented[i][i];
        for (int j = 0; j < 8; j++) {
            augmented[i][j] /= diagonal;
        }
        for (int j = i - 1; j >= 0; j--) {
            float ratio = augmented[j][i];
            for (int k = 0; k < 8; k++) {
                augmented[j][k] -= ratio * augmented[i][k];
            }
        }
    }
    // 逆行列を取り出す
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            inverse[i][j] = augmented[i][j + 4];
        }
    }
}
int main() {
    float matrix[4][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12},
        {13, 14, 15, 16}
    };
    float inverse[4][4];
    inverseMatrix(matrix, inverse);
    printf("Inverse Matrix:\n");
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            printf("%f ", inverse[i][j]);
        }
        printf("\n");
    }
    return 0;
}

上記のサンプルコードでは、与えられた4×4行列の逆行列を求めています。

掃き出し法を用いて、元の行列を上三角行列に変換し、その後逆行列を取り出しています。

行列式を用いた4×4行列の逆行列の求め方

行列式を用いた方法では、行列式の値を計算し、その逆数をかけることで逆行列を求めます。

以下の手順で逆行列を求めることができます。

  1. 元の行列の行列式を計算します。
  2. 元の行列の余因子行列を作成します。

余因子行列は、元の行列の各要素に対して、その余因子を計算して並べた行列です。

  1. 余因子行列を転置します。
  2. 行列式の逆数をかけて、逆行列を求めます。

以下に、行列式を用いた4×4行列の逆行列の求め方のサンプルコードを示します。

#include <stdio.h>
float determinant(float matrix[4][4]) {
    float det = 0;
    det += matrix[0][0] * (matrix[1][1] * (matrix[2][2] * matrix[3][3] - matrix[2][3] * matrix[3][2]) - matrix[1][2] * (matrix[2][1] * matrix[3][3] - matrix[2][3] * matrix[3][1]) + matrix[1][3] * (matrix[2][1] * matrix[3][2] - matrix[2][2] * matrix[3][1]));
    det -= matrix[0][1] * (matrix[1][0] * (matrix[2][2] * matrix[3][3] - matrix[2][3] * matrix[3][2]) - matrix[1][2] * (matrix[2][0] * matrix[3][3] - matrix[2][3] * matrix[3][0]) + matrix[1][3] * (matrix[2][0] * matrix[3][2] - matrix[2][2] * matrix[3][0]));
    det += matrix[0][2] * (matrix[1][0] * (matrix[2][1] * matrix[3][3] - matrix[2][3] * matrix[3][1]) - matrix[1][1] * (matrix[2][0] * matrix[3][3] - matrix[2][3] * matrix[3][0]) + matrix[1][3] * (matrix[2][0] * matrix[3][1] - matrix[2][1] * matrix[3][0]));
    det -= matrix[0][3] * (matrix[1][0] * (matrix[2][1] * matrix[3][2] - matrix[2][2] * matrix[3][1]) - matrix[1][1] * (matrix[2][0] * matrix[3][2] - matrix[2][2] * matrix[3][0]) + matrix[1][2] * (matrix[2][0] * matrix[3][1] - matrix[2][1] * matrix[3][0]));
    return det;
}
void cofactorMatrix(float matrix[4][4], float cofactor[4][4]) {
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            float minor[3][3];
            int minorRow = 0;
            int minorCol = 0;
            for (int k = 0; k < 4; k++) {
                for (int l = 0; l < 4; l++) {
                    if (k != i && l != j) {
                        minor[minorRow][minorCol] = matrix[k][l];
                        minorCol++;
                        if (minorCol == 3) {
                            minorCol = 0;
                            minorRow++;
                        }
                    }
                }
            }
            float minorDet = determinant(minor);
            cofactor[i][j] = (i + j) % 2 == 0 ? minorDet : -minorDet;
        }
    }
}
void transposeMatrix(float matrix[4][4], float transpose[4][4]) {
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            transpose[i][j] = matrix[j][i];
        }
    }
}
void inverseMatrix(float matrix[4][4], float inverse[4][4]) {
    float det = determinant(matrix);
    if (det == 0) {
        printf("The matrix is not invertible.\n");
        return;
    }
    float cofactor[4][4];
    cofactorMatrix(matrix, cofactor);
    float adjugate[4][4];
    transposeMatrix(cofactor, adjugate);
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            inverse[i][j] = adjugate[i][j] / det;
        }
    }
}
int main() {
    float matrix[4][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12},
        {13, 14, 15, 16}
    };
    float inverse[4][4];
    inverseMatrix(matrix, inverse);
    printf("Inverse Matrix:\n");
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            printf("%f ", inverse[i][j]);
        }
        printf("\n");
    }
    return 0;
}

上記のサンプルコードでは、与えられた4×4行列の逆行列を求めています。

行列式を用いて、行列の余因子行列を作成し、転置して逆行列を求めています。

以上が、4×4行列の逆行列の求め方についての解説です。

掃き出し法と行列式を用いた方法の2つの手法を紹介しました。

これらの手法を使えば、与えられた4×4行列の逆行列を求めることができます。

目次から探す