Python Numpy:如何避免舍入错误

Python Numpy:如何避免舍入错误,python,numpy,floating-point,precision,Python,Numpy,Floating Point,Precision,我想我对Numpy和小数字有问题 您能帮我找到以下问题的解决方案吗: import numpy as np def gaussian(xx, mu=0, sigma=1): return 1./(np.sqrt(2*np.pi)*sigma)*np.exp(-(mu-xx)**2/(2*sigma**2)) factors = (1., 0.1, 0.01, 0.001, 0.0001) for factor in factors: xx = np.linspace(5000

我想我对Numpy和小数字有问题

您能帮我找到以下问题的解决方案吗:

import numpy as np

def gaussian(xx, mu=0, sigma=1):
    return 1./(np.sqrt(2*np.pi)*sigma)*np.exp(-(mu-xx)**2/(2*sigma**2))

factors = (1., 0.1, 0.01, 0.001, 0.0001)
for factor in factors:
    xx = np.linspace(5000, 5200, 1000)
    yy = 1.-(factor*xx*(1.+gaussian(xx, 5100)))
    step = xx[1] - xx[0]

    print np.sum((1.-yy/(1.-factor*xx))*step)
对于所有不同的
因素
,此代码的计算结果应为
-1
。 但结果是:

1.0 -1.00019611689
0.1 -1.00196463662
0.01 -1.0200000008
0.001 -1.24390245353
0.0001 1.04081641153
所以问题是,因子越小,我就越容易陷入麻烦,因为我认为这与Numpy/Python的精度有关

即使是很小的因素,如何评估方程式


非常感谢您的帮助。

这不是一个棘手的问题。您对结果应为
-1
的期望是不正确的

5100
附近的一个大区间上,有效地计算函数的定积分
f(x)
。您正在积分的函数简化为
因子*x*高斯(x)/(1-因子*x)
。我们可以很容易地给出所用因子的积分值的包络估计:数量
因子*x/(1-因子*x)
在感兴趣的范围内变化相当缓慢,约为
5095
5105
;对于超出此范围的任何对象,高斯函数将使贡献可以忽略不计。所以对于一级近似,我们可以把这个量当作常数。然后我们剩下的常数乘以高斯(x),这将足够接近
1
。因此,预期输出应该在
因子*5100/(1-因子*5100)
的某个区域内。(尽管当
系数
接近
1/5100
时,这将不太有效)


因此,例如在
因子
0.0001
的情况下,
因子*5100/(1-因子*5100)
的值约为
1.0408163265306123
。这与您所看到的答案非常接近,可以让人相信NumPy做的或多或少是正确的。

我怀疑至少部分问题在于数学(或者更可能的是,在数学到Python+NumPy代码的翻译中)。为什么你认为这应该评估为-1?这是基于什么?将
yy
-部分重写为
1-ax(1+g(x))
,然后将总和内的部分重写为
1-yy/(1-ax)=1-((1-ax(1+g(x))/(1-ax))=1-(1+g(x))=-g(x)
。因为
g(x)
是一种高斯分布,其峰值位于
5100
和stddev
1
,我们在
200
范围内(从
5000
5200
)积分
g(x)
将是1,因此结果将是
-1
。我认为数学不是问题,而是Numpy/Python处理小数字的方式。不,你的代数中有一个错误。你的表达式简化为
axg(x)/(1-ax)
,而不是
-g(x)
。也许你的意思是将
yy
定义为
(1-因子*xx)*(1+高斯(xx,5100))
取而代之?谢谢你的提示。这样做的时候,问题就解决了,一切都很好。我试图简化我在获取上述代码时遇到的一个问题。显然出了问题。我需要检查我在哪里犯了错误……是的,你完全正确。我想简化我遇到的一个问题,犯了你上面描述的错误。对此我真的很抱歉,虽然我已经检查了我的简化,但我把它搞砸了。谢谢你的努力。为我感到羞耻,为你的更正投票。