收敛到错误值的 Tanh-sinh 正交数值积分方法

计算科学 Python 正交
2021-12-06 12:50:23

我正在尝试编写一个 Python 程序来使用 Tanh-sinh 求积来计算 但尽管程序在每种情况下都收敛到一个没有错误的合理值,但它并没有收敛到正确的值(对于这个特定的积分是),我找不到问题所在。

11dx1x2
π

该程序不是要求所需的准确度,而是要求所需的函数评估次数,以便更容易地比较收敛与更简单的集成方法。评估的数量需要是奇数,因为使用的近似值是 谁能建议我可能做错了什么?

11f(x)dx=k=nnwkf(xk)

import math

def func(x):
    # Function to be integrated, with singular points set = 0
    if x == 1 or x == -1 :
        return 0
    else:
        return 1 / math.sqrt(1 - x ** 2)

# Input number of evaluations
N = input("Please enter number of evaluations \n")
if N % 2 == 0:
    print "The number of evaluations must be odd"
else:
    print "N =", N  

# Set step size
h = 2.0 / (N - 1)
print "h =", h

# k ranges from -(N-1)/2 to +(N-1)/2
k = -1 * ((N - 1) / 2.0)
k_max  = ((N - 1) / 2.0)
sum = 0

# Loop across integration interval
while k < k_max + 1:

    # Compute abscissa
    x_k = math.tanh(math.pi * 0.5 * math.sinh(k * h))

    # Compute weight
    numerator = 0.5 * h * math.pi * math.cosh(k * h)
    denominator = math.pow(math.cosh(0.5 * math.pi * math.sinh(k * h)),2)
    w_k =  numerator / denominator

    sum += w_k * func(x_k)

    k += 1

print "Integral =", sum
3个回答

tanh-sinh 求积有很多陷阱,其中一个是被积函数需要非常接近区间边界进行评估,距离小于机器精度,例如1.0 - 1.0e-20在原始示例中。当评估这一点时,它会四舍五入到1.0具有f奇点的位置,并且任何事情都可能发生。您得到了错误的结果,因为您将该值设置为 0。

您首先必须转换函数,使奇点位于 0 以避免四舍五入。在 的情况下1 / sqrt(1 - x**2),这1 / numpy.sqrt(2*x - x**2)适用于左奇点和右奇点。使用tanh_sinh(我的一个项目),然后得到

import numpy as np
import tanh_sinh

# def f(x):
#    return 1 / np.sqrt(1 - x ** 2)

val, error_estimate = tanh_sinh.integrate_lr(
    lambda x: 1 / np.sqrt(2 * x - x ** 2),  # = 1 / sqrt(1 - (x-1)**2)
    lambda x: 1 / np.sqrt(2 * x - x ** 2),  # = 1 / sqrt(1 - (-(x-1))**2)
    2.0,  # length of the interval
    1.0e-10,
)
print(val, val - np.pi)
3.1415926533203944 -2.693987255497632e-10

您根据选择的方法不是一种非常复杂的方法,并且可能没有使足够小。和估计积分评估中的误差的更合理方法,请参阅这些注释:hNhh

http://www.davidhbailey.com/dhbpapers/dhb-tanh-sinh.pdf

再说一句:

我建议您阅读有关 DE 正交的开发和实现的原始论文(有关一些论文,请参见此处)并尝试理解 Ooura 教授的实现,您可以在此处下载(确保下载他所谓的“the简单的版本”,因为那个版本或多或少是可读的)。像您一样直接计算权重也会导致舍入误差。wk