python中具有奇点的数值积分(主值)

时间:2018-10-07 23:56:28

标签: python scipy

我正在尝试使用scipy.integrate中的quad函数将具有奇点的函数集成在一起,但是我没有得到想要的答案。这是代码:

from scipy.integrate import quad
import numpy as np
def fun(x):
    return 1./(1-x**2)
quad(fun, -2, 2, points=[-1, 1])

这将导致IntegrationWarning,并返回有关0.4的值。

该功能的极点为[-1,1]。答案应约为1.09(使用笔和纸计算)。

2 个答案:

答案 0 :(得分:4)

选项weight='cauchy'可用于高效地计算像这样的发散积分的主值。这意味着提供给quad的函数将隐式乘以1/(x-wvar),因此请相应地调整该函数(乘以x-wvar,其中wvar是奇点)。

i1 = quad(lambda x: -1./(x+1), 0, 2, weight='cauchy', wvar=1)[0]
i2 = quad(lambda x: -1./(x-1), -2, 0, weight='cauchy', wvar=-1)[0]
result = i1 + i2

结果为1.0986122886681091

使用这样的简单功能,您还可以与SymPy进行符号集成:

from sympy import symbols, integrate
x = symbols('x')
f = integrate(1/(1-x**2), x)
result = (f.subs(x, 2) - f.subs(x, -2)).evalf()

结果:1.09861228866811。如果没有evalf(),它将是log(3)

答案 1 :(得分:1)

我也无法使其与原始功能一起使用。我想出了这个来评估scipy的主要价值:

def principal_value(func, a, b, poles, eps=10**(-6)):
    #edges
    res = quad(func,a,poles[0]-eps)[0]+quad(func,poles[-1]+eps,b)[0]
    #inner part
    for i in range(len(poles)-1):
        res += quad(func, poles[i]+eps, poles[i+1]-eps)[0]
    return res

其中func是函数句柄,ab是极限,poles是极点列表,eps是您想要的距离接近两极。您可以使eps越来越小以获得更好的结果,但是也许sympy对于这样的问题会更好。

使用此功能和标准的eps,我得到1.0986112886023367的结果,这与wolframalpha给出的结果几乎相同。