有时,当我在Python中集成无限边界时,我得到了错误的解决方案。这是一个简单的例子来说明我的困惑:
from scipy import *
import numpy as np
from scipy.integrate import quad
def integrand1(x):
output = exp(-(x-1.0)**2.0)
return output
def integrand2(x):
output = exp(-(x-100.0)**2.0)
return output
solution1 = quad(integrand1,-np.inf,np.inf)
print solution1
solution1 = quad(integrand2,-np.inf,np.inf)
print solution2
输出为:
(1.7724538509055159, 3.668332157626072e-11)
(0.0, 0.0)
我不明白为什么第二个积分是错误的,而第一个积分是错误的。告诉我在Python中处理无限的一些技巧会很棒。
答案 0 :(得分:0)
您的代码没有任何内在错误。你得到的结果是由于quad
算法是一种近似方法,其准确性,从我收集到的一些测试,很大程度上取决于积分区间的中点位于x轴间隔的位置被积函数与0显着不同。
在(-inf,+inf)
间隔的情况下,积分间隔的中点始终为0(请参阅相关Fortran代码here的注释,从第238行开始),并且(遗憾地)无法配置。您的integrand2
函数以x = 100为中心,距离quad
算法的中点太远,因为它不够准确。
能够在-inf
和+inf
之间进行集成时指定中点会很好,但好消息是您可以使用函数装饰器自己实现它。首先,你需要一个包含你的被积函数的包装器,以便在x轴上任意移动它:
def shift_integrand(integrand, offset):
def dec(x):
return integrand(x - offset)
return dec
这将根据您喜欢的任何被积函数生成一个新函数,只需根据offset
参数沿x轴移动它。因此,如果您执行此类操作(使用integrand1
和integrand2
函数):
new_integrand1 = shift_integrand(integrand1, -1.0)
print new_integrand1(0.0)
new_integrand2 = shift_integrand(integrand2, -100.0)
print new_integrand2(0.0)
你得到:
1.0
1.0
现在你需要quad
函数的另一个包装器,以便能够传递一个新的中点:
def my_quad(func, a, b, midpoint=0.0, **kwargs):
if midpoint != 0.0:
func = shift_integrand(func, -midpoint)
return quad(func, a, b, **kwargs)
最后,知道你的积分集中在哪里,你可以这样称呼它:
solution2 = my_quad(integrand2, -np.inf, np.inf, midpoint=100.0)
print solution2
哪个收益率:
(1.772453850905516, 1.4202639944499085e-08)