C 言語による有限差分近似の評価

C 言語Beginner
オンラインで実践に進む

はじめに

この実験では、C 言語で有限差分近似による導関数の評価方法を学びます。この実験では以下の手順を踏みます。

  1. 数学関数 f(x) を定義し、有限差分近似のステップサイズ h を設定します。
  2. 与えられた評価点 x における f(x) の導関数の前進差分近似と後退差分近似を計算します。
  3. 計算された近似値を出力し、真の導関数と比較します。

この実験の終わりまでに、C 言語で有限差分法を実装し、近似の精度を評価する方法をしっかりと理解しているはずです。

f(x) の定義とステップサイズ h

このステップでは、C 言語で数学関数と有限差分近似のステップサイズを定義する方法を学びます。

まず、有限差分近似プログラム用の新しい C ファイルを作成します。

cd ~/project
nano finite_difference.c

次に、関数とステップサイズを定義する以下のコードを追加します。

#include <stdio.h>
#include <math.h>

// 関数 f(x) を定義
double f(double x) {
    return x * x;  // 例:f(x) = x^2
}

int main() {
    // ステップサイズ h を定義
    double h = 0.0001;  // 精度を高めるために小さなステップサイズ

    // 導関数を評価する点 x
    double x = 2.0;

    printf("関数:f(x) = x^2\n");
    printf("ステップサイズ h: %f\n", h);
    printf("評価点 x: %f\n", x);

    return 0;
}

出力例:

関数: f(x) = x^2
ステップサイズ h: 0.000100
評価点 x: 2.000000

主な構成要素を説明します。

  1. f(x) 関数:簡単な 2 次関数 f(x) = x^2 を定義しました。近似したい任意の数学関数をこの関数に変更できます。

  2. ステップサイズ h: 有限差分近似で使用する小さな値です。小さな h の方が一般的により正確な結果になりますが、非常に小さな値は数値的な精度問題を引き起こす可能性があります。

  3. 評価点 x: 導関数の近似値を計算する点です。

プログラムをコンパイルして動作を確認します。

gcc -o finite_difference finite_difference.c -lm
./finite_difference

出力例:

関数:f(x) = x^2
ステップサイズ h: 0.000100
評価点 x: 2.000000

前進/後退差分計算

このステップでは、前進差分と後退差分による導関数の近似計算方法を学びます。

前のファイルを開き、コードに導関数近似方法を含めるように修正します。

cd ~/project
nano finite_difference.c

前進差分と後退差分の計算を含めたコードを更新します。

#include <stdio.h>
#include <math.h>

// 関数 f(x) を定義
double f(double x) {
    return x * x;  // 例:f(x) = x^2
}

int main() {
    // ステップサイズ h を定義
    double h = 0.0001;  // 精度を高めるために小さなステップサイズ

    // 導関数を評価する点 x
    double x = 2.0;

    // 前進差分近似
    double forward_diff = (f(x + h) - f(x)) / h;

    // 後退差分近似
    double backward_diff = (f(x) - f(x - h)) / h;

    printf("前進差分近似:%f\n", forward_diff);
    printf("後退差分近似:%f\n", backward_diff);

    return 0;
}

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

gcc -o finite_difference finite_difference.c -lm
./finite_difference

出力例:

前進差分近似: 4.000100
後退差分近似: 3.999900

有限差分近似を詳しく見てみましょう。

  1. 前進差分:x の次の点を使用して導関数を計算します。

    • 式:(f(x + h) - f(x)) / h
    • 前方への変化率を近似します。
  2. 後退差分:x の前の点を使用して導関数を計算します。

    • 式:(f(x) - f(x - h)) / h
    • 後方への変化率を近似します。

関数 f(x) = x^2 の真の導関数は 2x (x = 2 のとき 4) です。 近似値は実際の導関数値に非常に近い値です。

近似値の出力

このステップでは、プログラムを拡張して詳細な近似結果を出力し、実際の導関数と比較します。

前のファイルを開き、包括的な出力を含めるようにコードを修正します。

cd ~/project
nano finite_difference.c

詳細な近似出力を含めたコードを更新します。

#include <stdio.h>
#include <math.h>

// 関数 f(x) を定義
double f(double x) {
    return x * x;  // 例:f(x) = x^2
}

// 実際の導関数
double actual_derivative(double x) {
    return 2 * x;  // x^2 の導関数は 2x
}

int main() {
    // 比較のために複数のステップサイズを定義
    double step_sizes[] = {0.1, 0.01, 0.001, 0.0001};
    int num_steps = sizeof(step_sizes) / sizeof(step_sizes[0]);

    // 導関数を評価する点 x
    double x = 2.0;

    // 実際の導関数値
    double true_derivative = actual_derivative(x);

    printf("導関数近似分析\n");
    printf("-----------------\n");
    printf("関数:f(x) = x^2\n");
    printf("評価点:x = %f\n", x);
    printf("真の導関数:%f\n\n", true_derivative);

    printf("ステップサイズ | 前進差分 | 後退差分 | 前進誤差 | 後退誤差\n");
    printf("-------------------------------------------------------\n");

    // 異なるステップサイズに対する近似値を計算して出力
    for (int i = 0; i < num_steps; i++) {
        double h = step_sizes[i];

        // 前進差分近似
        double forward_diff = (f(x + h) - f(x)) / h;

        // 後退差分近似
        double backward_diff = (f(x) - f(x - h)) / h;

        // 絶対誤差を計算
        double forward_error = fabs(forward_diff - true_derivative);
        double backward_error = fabs(backward_diff - true_derivative);

        printf("%9f | %11f | %12f | %11f | %12f\n",
               h, forward_diff, backward_diff, forward_error, backward_error);
    }

    return 0;
}

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

gcc -o finite_difference finite_difference.c -lm
./finite_difference

出力例:

導関数近似分析
-----------------
関数: f(x) = x^2
評価点: x = 2.000000
真の導関数: 4.000000

ステップサイズ | 前進差分 | 後退差分 | 前進誤差 | 後退誤差
-------------------------------------------------------
    0.100000 |     4.100000 |      3.900000 |      0.100000 |       0.100000
    0.010000 |     4.010000 |      3.990000 |      0.010000 |       0.010000
    0.001000 |     4.001000 |      3.999000 |      0.001000 |       0.001000
    0.000100 |     4.000100 |      3.999900 |      0.000100 |       0.000100

主な観察事項:

  1. ステップサイズ h が小さくなるにつれて、近似値はより正確になります。
  2. 前進差分と後退差分は真の導関数に収束します。
  3. ステップサイズが小さくなるにつれて、誤差は減少します。

まとめ

この実験では、数学関数と有限差分近似のステップサイズを C で定義する方法を学びました。また、前進差分と後退差分による導関数の近似計算方法も学びました。主な手順としては、関数 f(x) とステップサイズ h を定義し、与えられた評価点 x での導関数を近似するために前進差分法と後退差分法を実装することです。これにより、数値解析や科学計算における有限差分法の理解と実装のための基礎が築かれました。