C 言語でシンプソン則を用いた積分の近似計算

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

はじめに

この実験では、C 言語を用いてシンプソン則を用いて積分を近似する方法を学びます。この実験では、積分対象の関数、積分範囲を定義し、シンプソン則アルゴリズムを実装して近似積分値を計算する手順を段階的に解説します。この実験の終わりまでに、指定された区間で与えられた関数をシンプソン則を用いて数値積分できる C プログラムを作成できるようになります。

この実験は主に 2 つのステップから構成されます。まず、関数を定義し、積分範囲を定義します。次に、偶数の小区間を用いてシンプソン則を用いて近似積分を行います。この実践的な演習を通して、C プログラミングにおける数値積分手法の適用に関する実践的な経験を積むことができます。

関数 f(x) と区間 [a, b] の定義

このステップでは、C 言語で数値積分を行うためのシンプソン則を実装するための基礎となる部分を設定します。積分対象の関数と積分区間を定義します。

まず、~/project ディレクトリに新しい C ファイルを作成します。

cd ~/project
nano simpson_integration.c

次に、関数と区間を定義するための初期コードを記述します。

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

// 関数 (積分対象): f(x) = x^2
double f(double x) {
    return x * x;
}

int main() {
    // 積分区間 [a, b] を定義
    double a = 0.0;  // 下限
    double b = 1.0;  // 上限

    printf("f(x) = x^2 を %f から %f まで積分します\n", a, b);

    return 0;
}

コードを詳しく見てみましょう。

  1. 入出力のための stdio.h と数学関数のための math.h をインクルードしています。
  2. f(x) は、積分する単純な 2 次関数 x^2 として定義されています。
  3. main() 内で、積分区間を 0 から 1 に設定しています。
  4. 明確にするために、積分区間を出力しています。

コンパイルして実行し、確認します。

gcc simpson_integration.c -o simpson_integration -lm
./simpson_integration

実行結果の例:

f(x) = x^2 を 0.000000 から 1.000000 まで積分します

偶数小区間を用いたシンプソン則の実装

このステップでは、関数の定積分を近似するためにシンプソン則アルゴリズムを実装します。既存の C プログラムに積分関数を追加します。

以前のファイルを開きます。

cd ~/project
nano simpson_integration.c

シンプソン則の実装を含めるようにコードを更新します。

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

// 関数 (積分対象): f(x) = x^2
double f(double x) {
    return x * x;
}

// シンプソン則の実装
double simpsons_rule(double a, double b, int n) {
    double h = (b - a) / n;  // 各小区間の幅
    double sum = f(a) + f(b);  // 最初の点と最後の点

    // 偶数点と奇数点の和を計算
    for (int i = 1; i < n; i++) {
        double x = a + i * h;
        sum += (i % 2 == 0 ? 2 : 4) * f(x);
    }

    return (h / 3) * sum;
}

int main() {
    // 積分区間 [a, b] を定義
    double a = 0.0;  // 下限
    double b = 1.0;  // 上限
    int n = 100;     // 小区間の数 (偶数でなければなりません)

    double integral = simpsons_rule(a, b, n);

    printf("f(x) = x^2 の %f から %f までの定積分\n", a, b);
    printf("%d 個小区間を用いたシンプソン則による近似値:%f\n", n, integral);

    return 0;
}

コンパイルして実行します。

gcc simpson_integration.c -o simpson_integration -lm
./simpson_integration

実行結果の例:

f(x) = x^2 の 0.000000 から 1.000000 までの定積分
100 個小区間を用いたシンプソン則による近似値: 0.333333

シンプソン則の実装を詳しく見てみましょう。

  1. simpsons_rule() は積分区間と小区間の数を引数にとります。
  2. h は各小区間の幅を計算します。
  3. 積分区間の最初の点と最後の点を初期値として加算します。
  4. ループは中間点からの加重された寄与を合計します。
  5. 偶数点には 2 が、奇数点には 4 が乗算されます。
  6. 最終結果は h/3 でスケーリングされます。

近似積分値の出力

この最終ステップでは、シンプソン則の実装をさらに強化し、より詳細な出力を追加して、数値近似値と正確な積分値を比較します。

以前のファイルを開きます。

cd ~/project
nano simpson_integration.c

より包括的な出力を含めるようにコードを更新します。

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

// 関数 (積分対象): f(x) = x^2
double f(double x) {
    return x * x;
}

// f(x) = x^2 の a から b までの正確な積分値を計算する関数
double exact_integral(double a, double b) {
    return (pow(b, 3) - pow(a, 3)) / 3.0;
}

// シンプソン則の実装
double simpsons_rule(double a, double b, int n) {
    double h = (b - a) / n;  // 各小区間の幅
    double sum = f(a) + f(b);  // 最初の点と最後の点

    // 偶数点と奇数点の和を計算
    for (int i = 1; i < n; i++) {
        double x = a + i * h;
        sum += (i % 2 == 0 ? 2 : 4) * f(x);
    }

    return (h / 3) * sum;
}

int main() {
    // 積分区間 [a, b] を定義
    double a = 0.0;  // 下限
    double b = 1.0;  // 上限
    int n = 100;     // 小区間の数 (偶数でなければなりません)

    // 近似値と正確な積分値を計算
    double approx_integral = simpsons_rule(a, b, n);
    double exact_value = exact_integral(a, b);
    double error = fabs(exact_value - approx_integral);

    // 詳細な結果を出力
    printf("積分近似結果:\n");
    printf("------------------------------\n");
    printf("関数:f(x) = x^2\n");
    printf("区間:[%.2f, %.2f]\n", a, b);
    printf("小区間数:%d\n\n", n);

    printf("近似値 (シンプソン則): %.6f\n", approx_integral);
    printf("正確な値:%.6f\n", exact_value);
    printf("絶対誤差:%.6f\n", error);
    printf("相対誤差:%.4f%%\n", (error / exact_value) * 100);

    return 0;
}

コンパイルして実行します。

gcc simpson_integration.c -o simpson_integration -lm
./simpson_integration

実行結果の例:

積分近似結果:
------------------------------
関数: f(x) = x^2
区間: [0.00, 1.00]
小区間数: 100

近似値 (シンプソン則): 0.333333
正確な値: 0.333333
絶対誤差: 0.000000
相対誤差: 0.0000%

このステップで追加された主な点は以下のとおりです。

  1. 真の積分値を計算するための exact_integral() 関数を追加しました。
  2. 絶対誤差と相対誤差を計算しました。
  3. 詳細な積分結果を示すフォーマットされた出力を作成しました。

まとめ

この実験では、まず積分対象の関数 f(x) = x^2 と積分区間 [a, b] = [0, 1] を定義しました。次に、シンプソン則アルゴリズムを実装して、関数の定積分を近似しました。シンプソン則では、区間を偶数個の小区間に分割し、これらの小区間の端点および中点における関数の値の加重和を計算します。最後に、シンプソン則を用いて得られた近似積分値を出力します。