我正在尝试使用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(使用笔和纸计算)。
答案 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
是函数句柄,a
和b
是极限,poles
是极点列表,eps
是您想要的距离接近两极。您可以使eps越来越小以获得更好的结果,但是也许sympy对于这样的问题会更好。
使用此功能和标准的eps
,我得到1.0986112886023367
的结果,这与wolframalpha给出的结果几乎相同。