Python与无限集成

时间:2017-05-03 10:05:39

标签: python

有时,当我在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中处理无限的一些技巧会很棒。

1 个答案:

答案 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轴移动它。因此,如果您执行此类操作(使用integrand1integrand2函数):

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)