cms.integration.integ_order のソースコード

import csv
import numpy as np
from math import exp


"""
様々な近似法による数値積分の比較を行うスクリプト。

概要:
    指数関数 `exp(x)` の定積分をリーマン和、台形公式、シンプソン公式、シンプソン3/8公式、ブール(Bode)公式といった
    異なる数値積分法を用いて計算し、解析解と比較する。結果はCSVファイルに書き出される。

詳細説明:
    このスクリプトは、与えられた関数 `func(x)` (ここでは `exp(x)`) の区間 `[x, x+h]` における定積分を、
    複数の数値積分手法で近似計算する。
    各 `x` の値について、数値積分結果と解析解(`integ(x+h) - integ(x)`)を比較し、
    その結果を標準出力とCSVファイル `integ_order.csv` に出力する。
    計算範囲とステップサイズは `x0`, `nx`, `h` パラメータで設定される。

関連リンク:
    :doc:`integ_order_usage`
"""


[ドキュメント] def func(x): """被積分関数 f(x) を定義する。 概要: 被積分関数 `f(x)` を定義する。 詳細説明: この例では `exp(x)` を返す。 :param x: float 入力値。 :returns: float `exp(x)` の値。 """ return exp(x)
[ドキュメント] def integ(x): """解析的な原始関数 F(x) を定義する。 概要: 解析的な原始関数 `F(x)` を定義する。 詳細説明: この例では `exp(x)` を返す。これは `exp(x)` の原始関数である。 :param x: float 入力値。 :returns: float `exp(x)` の値。 """ return exp(x)
[ドキュメント] def integ_rieman(func, x, h): """リーマン和を用いて数値積分を行う。 概要: リーマン和を用いて関数 `func` の区間 `[x, x+h]` における数値積分を近似する。 詳細説明: 区間 `[x, x+h]` における左端の点 `x` での関数値 `func(x)` を用いて、 長方形の面積として積分を近似する(左リーマン和)。 :param func: callable 積分対象の関数。 :param x: float 積分区間の開始点。 :param h: float 積分区間の幅。 :returns: float リーマン和による積分の近似値。 """ return func(x) * h
[ドキュメント] def integ_trapezoid(func, x, h): """台形公式を用いて数値積分を行う。 概要: 台形公式を用いて関数 `func` の区間 `[x, x+h]` における数値積分を近似する。 詳細説明: 区間 `[x, x+h]` の両端 `x` と `x+h` での関数値を用いて、 台形の面積として積分を近似する。 :param func: callable 積分対象の関数。 :param x: float 積分区間の開始点。 :param h: float 積分区間の幅。 :returns: float 台形公式による積分の近似値。 """ return (func(x) + func(x + h)) * 0.5 * h
[ドキュメント] def integ_simpson(func, x, h): """シンプソン1/3公式を用いて数値積分を行う。 概要: シンプソン1/3公式を用いて関数 `func` の区間 `[x, x+h]` における数値積分を近似する。 詳細説明: 区間 `[x, x+h]` を2つの部分区間に分け、3つの点(`x`, `x+0.5*h`, `x+h`)での関数値を用いて 二次多項式で近似し、積分を計算する。 :param func: callable 積分対象の関数。 :param x: float 積分区間の開始点。 :param h: float 積分区間の幅。 :returns: float シンプソン1/3公式による積分の近似値。 """ return (func(x) + 4.0 * func(x + 0.5 * h) + func(x + h)) / 6.0 * h
[ドキュメント] def integ_simpson38(func, x, h): """シンプソン3/8公式を用いて数値積分を行う。 概要: シンプソン3/8公式を用いて関数 `func` の区間 `[x, x+h]` における数値積分を近似する。 詳細説明: 区間 `[x, x+h]` を3つの部分区間に分け、4つの点(`x`, `x+h/3.0`, `x+2.0*h/3.0`, `x+h`)での関数値を用いて 三次多項式で近似し、積分を計算する。 :param func: callable 積分対象の関数。 :param x: float 積分区間の開始点。 :param h: float 積分区間の幅。 :returns: float シンプソン3/8公式による積分の近似値。 """ return ( 3.0 * func(x) + 9.0 * func(x + h / 3.0) + 9.0 * func(x + 2.0 * h / 3.0) + 3.0 * func(x + h) ) / 24.0 * h
[ドキュメント] def integ_bode(func, x, h): """ブール(Bode)公式を用いて数値積分を行う。 概要: ブール(Bode)公式を用いて関数 `func` の区間 `[x, x+h]` における数値積分を近似する。 詳細説明: 区間 `[x, x+h]` を4つの部分区間に分け、5つの点(`x`, `x+h/4.0`, `x+h/2.0`, `x+3.0*h/4.0`, `x+h`)での関数値を用いて 四次多項式で近似し、積分を計算する。この公式はシンプソン公式よりも高精度な近似を提供する。 :param func: callable 積分対象の関数。 :param x: float 積分区間の開始点。 :param h: float 積分区間の幅。 :returns: float ブール公式による積分の近似値。 """ return ( 14.0 * func(x) + 64.0 * func(x + h / 4.0) + 24.0 * func(x + h / 2.0) + 64.0 * func(x + 3.0 * h / 4.0) + 14.0 * func(x + h) ) / 180.0 * h
# =================== # parameters # =================== outfile = 'integ_order.csv' x0 = 0.0 nx = 10 h = 0.5
[ドキュメント] def main(): """数値積分の比較を実行し、結果を標準出力とCSVファイルに出力する。""" print("Numerical integration using different approximations") print("Write to [{}]".format(outfile)) with open(outfile, 'w', newline='') as f: fout = csv.writer(f, lineterminator='\n') fout.writerow([ 'x', 'f', 'integ(f)[x,x+h]', 'Riemtan', 'Trapezoid', 'Simpson', 'Simpson 3/8', 'Bode' ]) print("") print("{:^3}:\t{:^10}\t{:^10}\t" "{:^12}\t{:^12}\t{:^12}\t{:^12}\t{:^12}" .format( 'x', 'f', 'integ(f)[x,x+h]', 'Riemtan', 'Trapezoid', 'Simpson', 'Simpson 3/8', 'Bode' )) for ix in range(nx): x = x0 + ix * h fx = func(x) Fx = integ(x + h) - integ(x) print("{:^3}:\t{:^10.4f}\t{:^10.4f}\t".format(x, fx, Fx), end='') res = [ integ_rieman(func, x, h), integ_trapezoid(func, x, h), integ_simpson(func, x, h), integ_simpson38(func, x, h), integ_bode(func, x, h), ] print("{:^12.6f}\t{:^12.6f}\t{:^12.6f}\t{:^12.6f}\t{:^12.6f}\t".format( res[0], res[1], res[2], res[3], res[4] ), end='') fout.writerow([x, fx, Fx] + res) print("")
if __name__ == "__main__": main()