"""
倍精度指数関数型数値積分モジュール。
二重指数関数型変換 (Double Exponential Transformation, DE変換) を用いて、
特定区間の定積分を数値的に評価します。
本モジュールは、特に被積分関数 `sqrt(1 - x^2)` の `[-1, 1]` 区間における
数値積分を実行し、解析解と比較します。
:doc:`integ_doubleexp_usage`
"""
import numpy as np
from math import exp, sqrt, pi, tanh, sinh, cosh
# 既存の自作モジュール(必要に応じてパスを通してください)
# from integ_gauss_legendre import integ_GL
# define function to be integrated
[ドキュメント]
def func(x):
"""
積分対象の関数 f(x) = sqrt(1 - x^2) を定義します。
:param x: float型の独立変数。
:returns: float型の `sqrt(1 - x^2)` の計算結果。
"""
return sqrt(1.0 - x*x)
#===================
# parameters (Default values)
#===================
# Integration parameters
xmin_def, xmax_def = -1.0, 1.0
umin_def, umax_def = -2.0, 2.0
nblock_max_def = 32
[ドキュメント]
def main():
"""
倍精度指数関数型数値積分を実行し、結果を出力するメイン関数です。
`[-1, 1]` の区間で `sqrt(1 - x^2)` を積分します。
各ブロック数 (nblock) における数値積分結果と解析解との誤差を表示します。
"""
# パラメータのローカル変数化
xmin, xmax = xmin_def, xmax_def
umin, umax = umin_def, umax_def
nblock_max = nblock_max_def
print("Numerical integration using by double exponential integra for [-1, 1]")
fx = func(xmin)
# Analytical integration of sqrt(1-x^2) from -1 to 1 is pi/2
Fx = pi / 2.0
print("")
print("Analytical values:")
print(" f({})={}".format(xmin, fx))
print(" integ(f)[{}, {}]={}".format(xmin, xmax, Fx))
print("")
print("nBlock\tS\tError")
for nblock in range(2, nblock_max + 1):
h = (umax - umin) / nblock
S = 0.0
for i in range(0, nblock + 1):
# ui is in the converted range [-u, u]
ui = umin + i * h
# x' = phi(ui) is in [-1, 1]
phiui = tanh(pi / 2.0 * sinh(ui))
# obtain the original x from x' = phi(ui)
xi = xmin + (phiui + 1.0) / 2.0 * (xmax - xmin)
yi = func(xi)
# Derivative of phi(ui) for the weight
coshsinh = cosh(pi / 2.0 * sinh(ui))
coshnh = cosh(ui)
phi1 = coshnh / (coshsinh * coshsinh)
S += yi * phi1
# Final scaling
S *= pi / 2.0 * h * (xmax - xmin) / 2.0
print("{}\t{}\t{}".format(nblock, S, S - Fx))
if __name__ == "__main__":
main()