如何在 Python 中处理非常小的数字 (<1e-15),传递给 Scipy/Numpy 函数?

How to handle very small numbers (<1e-15) in Python, passed to Scipy/Numpy functions?

提问人:Geoff2009max 提问时间:2/21/2023 最后编辑:Geoff2009max 更新时间:2/23/2023 访问量:232

问:

我想计算一些 scipy 函数,例如:(https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.gammaincinv.html#scipy.special.gammaincinv)。scipy.special.gammaincinv

然而,挑战在于,我需要使用的一个参数是,在这种情况下,where 是一个非常小的数字。1 - aaa=1e-18

因此,由于 Python 的小数精度限制在大约 1e-15,因此 Python 计算 = = 1.0,即它不准确。1 - a1 - 1e-18

我可以使用库 like 来获得准确的计算,但返回的对象不是正常数字,因此无法传递给 numpy / scipy 函数。mpmath1 - a

因此,我的问题是:当输入数字包含超出标准浮点数的精度时,如何最好地使用 scipy 和 numpy 函数(理想情况下,不是简单地使用 mpmath 类型结构重写函数本身?

编辑: 我要计算的确切表达式是:其中是一个非常小的数字()。由于精度有限,计算为 1.0,这给出了错误的值。gammaincinv(10, 1-a)aa=1e-181-a

numpy scipy 浮动精度 mpmath

评论

0赞 Reinderien 2/21/2023
如果可行,最好的方法是分解表达式,以便将 1 和 分开处理。因此,您的问题需要准确地显示您希望计算的表达式,而不仅仅是“例如”a
0赞 Geoff2009max 2/22/2023
谢谢。这是一个很好的观点。我试图编辑 Q,但 SO 有太多待处理的编辑。我要计算的确切表达式是:其中 a 是一个非常小的数字 ()。由于精度有限,计算为 1.0,这给出了错误的值。我想知道我如何实施您单独处理这些的建议?gammaincinv(10, 1-a)a=1e-181-a
0赞 hpaulj 2/22/2023
ufunc像这样使用编译的代码,所以输入仅限于编译中使用的 C 类型(通常是 float 和 double)。
0赞 Geoff2009max 2/22/2023
谢谢。所以这听起来好像做不到?我敢肯定其他人在想要使用 numpy/scipy 函数时也遇到过类似的问题,所以我想知道是否有任何技巧或解决方法?
2赞 hpaulj 2/22/2023
对于我测试的值,与sc.gammainccinv(10, x)sc.gammaincinv(10,1-x)

答:

0赞 Warren Weckesser 2/23/2023 #1

使用代替 .这正是 gammainccinv 的用途。gammainccinv(10, a)gammaincinv(10, 1 - a)

对于 的中等值,您可以看到它们给出了相同的值:a

In [14]: from scipy.special import gammaincinv, gammainccinv

In [15]: a = 0.125

In [16]: gammaincinv(10, 1 - a)
Out[16]: 13.688247592108494

In [17]: gammainccinv(10, a)
Out[17]: 13.688247592108494


对于小,所有精度都在减法中丢失a1 - a

In [18]: a = 1e-18

In [19]: gammaincinv(10, 1 - a)
Out[19]: inf

使用避免了这种减法并给出了正确的答案:gammainccinv

In [20]: gammainccinv(10, a)
Out[20]: 66.57188367091577