C 言語でクラメルの公式を使用して線形方程式を解く

CBeginner
オンラインで実践に進む

はじめに

この実験では、C 言語でクラメルの公式(Cramer's Rule)を使用して線形方程式を解く方法を学びます。この実験では、線形方程式系の係数と定数を読み取り、行列式を計算し、最後に変数の解を出力するプロセスを案内します。ユーザーが係数と定数を入力できる C プログラムを作成し、そのプログラムがクラメルの公式を使用して解を提供します。この実験では、重要な行列と線形代数の概念がカバーされており、学んだスキルはさまざまな現実世界の問題に適用できます。

係数と定数の読み取り

このステップでは、C 言語でクラメルの公式(Cramer's Rule)を使用して線形方程式を解くために、係数と定数を読み取る方法を学びます。線形方程式系の係数をユーザーが入力できるプログラムを作成します。

まず、線形方程式ソルバーの C ソースファイルを作成しましょう。

cd ~/project
nano cramer_solver.c

次に、以下のコードをファイルに追加します。

#include <stdio.h>

#define MAX_SIZE 3

int main() {
    float matrix[MAX_SIZE][MAX_SIZE];
    float constants[MAX_SIZE];
    int n;

    // 方程式系のサイズを入力
    printf("Enter the number of equations (max 3): ");
    scanf("%d", &n);

    // 係数を入力
    printf("Enter the coefficients of the matrix:\n");
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf("Enter coefficient a[%d][%d]: ", i+1, j+1);
            scanf("%f", &matrix[i][j]);
        }
    }

    // 定数を入力
    printf("Enter the constants:\n");
    for (int i = 0; i < n; i++) {
        printf("Enter constant b[%d]: ", i+1);
        scanf("%f", &constants[i]);
    }

    // 入力された行列と定数を表示
    printf("\nInput Matrix:\n");
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf("%.2f ", matrix[i][j]);
        }
        printf("| %.2f\n", constants[i]);
    }

    return 0;
}

プログラムをコンパイルします。

gcc -o cramer_solver cramer_solver.c

プログラムを実行します。

./cramer_solver

出力例:

Enter the number of equations (max 3): 2
Enter the coefficients of the matrix:
Enter coefficient a[1][1]: 2
Enter coefficient a[1][2]: 1
Enter coefficient a[2][1]: -3
Enter coefficient a[2][2]: 4
Enter the constants:
Enter constant b[1]: 4
Enter constant b[2]: 5

Input Matrix:
2.00 1.00 | 4.00
-3.00 4.00 | 5.00

コードを分解してみましょう。

  1. 線形方程式系の最大サイズを 3x3 と定義します。
  2. プログラムはまず、ユーザーに方程式の数を入力するように求めます。
  3. 次に、ユーザーに行列の係数を入力するように促します。
  4. その後、線形方程式の定数を入力するように求めます。
  5. 最後に、入力された行列と定数を検証のために表示します。

このステップでは、ユーザーが線形方程式系の係数と定数を入力できるようにすることで、クラメルの公式の実装の基礎を築きます。

行列式の計算

このステップでは、C 言語でクラメルの公式(Cramer's Rule)を使用して線形方程式を解くために、行列式を計算する方法を学びます。前のプログラムを拡張して、行列式の計算関数を追加します。

既存のソースファイルを開きます。

cd ~/project
nano cramer_solver.c

行列式の計算関数を含むようにコードを更新します。

#include <stdio.h>

#define MAX_SIZE 3

// 行列の行列式を計算する関数
float computeDeterminant(float matrix[MAX_SIZE][MAX_SIZE], int n) {
    if (n == 1) {
        return matrix[0][0];
    }

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

    float det = 0;
    float submatrix[MAX_SIZE][MAX_SIZE];
    int sign = 1;

    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 += sign * matrix[0][x] * computeDeterminant(submatrix, n - 1);
        sign = -sign;
    }

    return det;
}

int main() {
    float matrix[MAX_SIZE][MAX_SIZE];
    float constants[MAX_SIZE];
    int n;

    // 前の入力コードは同じまま
    printf("Enter the number of equations (max 3): ");
    scanf("%d", &n);

    // 係数を入力
    printf("Enter the coefficients of the matrix:\n");
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf("Enter coefficient a[%d][%d]: ", i+1, j+1);
            scanf("%f", &matrix[i][j]);
        }
    }

    // 定数を入力
    printf("Enter the constants:\n");
    for (int i = 0; i < n; i++) {
        printf("Enter constant b[%d]: ", i+1);
        scanf("%f", &constants[i]);
    }

    // 行列式を計算して表示
    float mainDeterminant = computeDeterminant(matrix, n);
    printf("\nMain Determinant: %.2f\n", mainDeterminant);

    return 0;
}

更新したプログラムをコンパイルします。

gcc -o cramer_solver cramer_solver.c

プログラムを実行します。

./cramer_solver

出力例:

Enter the number of equations (max 3): 2
Enter the coefficients of the matrix:
Enter coefficient a[1][1]: 2
Enter coefficient a[1][2]: 1
Enter coefficient a[2][1]: -3
Enter coefficient a[2][2]: 4
Enter the constants:
Enter constant b[1]: 4
Enter constant b[2]: 5

Main Determinant: 11.00

行列式の計算に関する要点:

  1. computeDeterminant() 関数は、再帰を使用して行列の行列式を計算します。
  2. 1x1 と 2x2 の行列を基本ケースとして扱います。
  3. より大きな行列については、余因子展開法(cofactor expansion method)を使用します。
  4. この関数は最大 3x3 の正方行列に対して機能します。

このコードは、係数行列の主行列式を計算する方法を示しており、これはクラメルの公式による線形方程式の解法における重要なステップです。

変数の解を出力する

このステップでは、線形方程式系の変数の解を計算して出力することで、クラメルの公式(Cramer's Rule)の実装を完成させます。

既存のソースファイルを開きます。

cd ~/project
nano cramer_solver.c

クラメルの公式による解の計算を含むようにコードを更新します。

#include <stdio.h>

#define MAX_SIZE 3

// 前の computeDeterminant 関数は同じまま
float computeDeterminant(float matrix[MAX_SIZE][MAX_SIZE], int n) {
    if (n == 1) {
        return matrix[0][0];
    }

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

    float det = 0;
    float submatrix[MAX_SIZE][MAX_SIZE];
    int sign = 1;

    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 += sign * matrix[0][x] * computeDeterminant(submatrix, n - 1);
        sign = -sign;
    }

    return det;
}

// クラメルの公式を使用して線形方程式を解く関数
void solveUsingCramersRule(float matrix[MAX_SIZE][MAX_SIZE], float constants[MAX_SIZE], int n) {
    float mainDeterminant = computeDeterminant(matrix, n);

    // システムが一意の解を持つかチェック
    if (mainDeterminant == 0) {
        printf("The system has no unique solution (determinant is zero).\n");
        return;
    }

    // 各変数のための一時行列を作成
    float tempMatrix[MAX_SIZE][MAX_SIZE];
    float solutions[MAX_SIZE];

    // 各変数の解を計算
    for (int i = 0; i < n; i++) {
        // 元の行列をコピー
        for (int j = 0; j < n; j++) {
            for (int k = 0; k < n; k++) {
                tempMatrix[j][k] = matrix[j][k];
            }
        }

        // i 番目の列を定数で置き換え
        for (int j = 0; j < n; j++) {
            tempMatrix[j][i] = constants[j];
        }

        // この変数の行列式を計算
        solutions[i] = computeDeterminant(tempMatrix, n) / mainDeterminant;
    }

    // 解を出力
    printf("\nSolutions:\n");
    for (int i = 0; i < n; i++) {
        printf("x%d = %.2f\n", i+1, solutions[i]);
    }
}

int main() {
    float matrix[MAX_SIZE][MAX_SIZE];
    float constants[MAX_SIZE];
    int n;

    // 入力コードは同じまま
    printf("Enter the number of equations (max 3): ");
    scanf("%d", &n);

    // 係数を入力
    printf("Enter the coefficients of the matrix:\n");
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf("Enter coefficient a[%d][%d]: ", i+1, j+1);
            scanf("%f", &matrix[i][j]);
        }
    }

    // 定数を入力
    printf("Enter the constants:\n");
    for (int i = 0; i < n; i++) {
        printf("Enter constant b[%d]: ", i+1);
        scanf("%f", &constants[i]);
    }

    // クラメルの公式を使用して解く
    solveUsingCramersRule(matrix, constants, n);

    return 0;
}

更新したプログラムをコンパイルします。

gcc -o cramer_solver cramer_solver.c

プログラムを実行します。

./cramer_solver

出力例:

Enter the number of equations (max 3): 2
Enter the coefficients of the matrix:
Enter coefficient a[1][1]: 2
Enter coefficient a[1][2]: 1
Enter coefficient a[2][1]: -3
Enter coefficient a[2][2]: 4
Enter the constants:
Enter constant b[1]: 4
Enter constant b[2]: 5

Solutions:
x1 = 2.00
x2 = 1.00

解の計算に関する要点:

  1. solveUsingCramersRule() 関数はクラメルの公式を実装しています。
  2. 主行列式を確認することで、システムが一意の解を持つかどうかをチェックします。
  3. 各変数について、一時行列を作成してその行列式を計算します。
  4. 各変数の行列式を主行列式で割ることで解を計算します。

このプログラムは、クラメルの公式を使用して線形方程式系を完全に解くことができます。

まとめ

この実験では、線形方程式系の係数と定数を読み取る方法を学びます。これは、C 言語でクラメルの公式(Cramer's Rule)を使用して線形方程式を解く最初のステップです。このプログラムでは、ユーザーが行列の係数と定数を入力でき、入力された行列を検証のために出力します。このステップは、その後の行列式の計算や変数の解の出力といったステップの基礎を築きます。

次のステップでは、係数行列と修正行列の行列式を計算します。これはクラメルの公式の重要な部分です。最後のステップでは、修正行列の行列式を係数行列の行列式で割ることにより、変数の解を出力します。