scipy integration.quad返回不正确的值

时间:2018-06-26 13:35:49

标签: scipy integrate quad

我使用scipy integration.quad计算正态分布的cdf:

def nor(delta, mu, x):
    return 1 / (math.sqrt(2 * math.pi) * delta) * np.exp(-np.square(x - mu) / (2 * np.square(delta)))


delta = 0.1
mu = 0
t = np.arange(4.0, 10.0, 1)
nor_int = lambda t: integrate.quad(lambda x: nor(delta, mu, x), -np.inf, t)
nor_int_vec = np.vectorize(nor_int)

s = nor_int_vec(t)
for i in zip(s[0],s[1]): 
    print i

其打印如下:

(1.0000000000000002, 1.2506543424265854e-08)
(1.9563704110140217e-11, 3.5403445591955275e-11)
(1.0000000000001916, 1.2616577562700088e-08)
(1.0842532749783998e-34, 1.9621183122960244e-34)
(4.234531567162006e-09, 7.753407284370446e-09)
(1.0000000000001334, 1.757986959115912e-10)

对于某些x,它返回的值近似为零,应该返回1。 有人可以告诉我怎么了吗?

1 个答案:

答案 0 :(得分:0)

why does quad return both zeros when integrating a simple Gaussian pdf at a very small variance?中的原因相同,但是看到我无法将其标记为重复,所以去了:

您正在集成一个很大的(实际上是无限的)时间间隔内具有紧密定位(按比例增量)的函数。积分例程可以简单地忽略该函数实质上不同于0的区间部分,而是将其判断为0。需要一些指导。可以使用参数points来达到此目的(请参阅链接的问题),但是由于quad在无限间隔内不支持此参数,因此必须手动分割间隔,如下所示:

for t in range(4, 10):
    int1 = integrate.quad(lambda x: nor(delta, mu, x), -np.inf, mu - 10*delta)[0] 
    int2 = integrate.quad(lambda x: nor(delta, mu, x), mu - 10*delta, t)[0] 
    print(int1 + int2)

每次打印1或将近1。我选择mu-10*delta作为切入点,认为无论mu和delta为何,大多数功能都位于其右侧。

注意:

  1. 使用np.sqrt等;通常不需要在NumPy代码中放置math函数。 NumPy版本可用并且已矢量化。
  2. np.vectorize应用于quad并没有做任何事情,除了使代码更长且更难阅读。使用普通的Python循环或列表理解。参见NumPy vectorization with integration