如何在 Python 中使用 scipy.integrate.quad 中的参数 epsabs?

zyy*_*zyy 3 python precision integrate scipy quad

我试图通过指定 的参数来更精确地计算积分epsabsscipy.integrate.quad假设我们正在将函数sin(x) / x^2从 1e-16 积分到 1.0

from scipy.integrate import quad
import numpy

integrand = lambda x: numpy.sin(x) / x ** 2
integral = quad(integrand, 1e-16, 1.0)
Run Code Online (Sandbox Code Playgroud)

这给了我们

(36.760078801255595, 0.01091187908038005)
Run Code Online (Sandbox Code Playgroud)

为了使结果更加精确,我们通过以下方式指定绝对误差容限epsabs

from scipy.integrate import quad
import numpy

integrand = lambda x: numpy.sin(x) / x ** 2
integral = quad(integrand, 1e-16, 1.0, epsabs = 1e-4)
Run Code Online (Sandbox Code Playgroud)

结果一模一样,误差还大到0.0109!我对参数的理解epsabs有误吗?我应该采取什么不同的措施来提高积分的精度?

Ser*_*ity 5

根据 scipy 手册,quad 函数limit参数指定

自适应算法中使用的子区间数量的上限。

默认情况下 的值为limit50。您的代码返回警告消息

quadpack.py:364: IntegrationWarning: 已达到最大细分数 (50)。如果增加限制没有改善,建议分析被积函数以确定困难。如果可以确定局部困难的位置(奇异性、不连续性),那么人们可能会通过分割区间并在子范围上调用积分器而获益。也许应该使用专用积分器。
warnings.warn(msg, IntegrationWarning)

你必须改变limit论点,即:

from scipy.integrate import quad
import numpy

integrand = lambda x: numpy.sin(x) / x ** 2
print(quad(integrand, 1e-16, 1.0, epsabs = 1e-4, limit=100))
Run Code Online (Sandbox Code Playgroud)

输出:

(36.7600787611414、3.635057215414274e-05)

输出中没有警告消息。细分数在100以下,quad达到了要求的精度。