numpy 点积的机器精度是多少?

1 投票
2 回答
1721 浏览
提问于 2025-04-18 06:29

我该如何处理numpy中的浮点数精度问题?比如在下面的例子中,a==0 返回的是 False,尽管在计算机的精度范围内它应该是0:

a = -2.22044605e-16

这个问题特别棘手,因为我在计算向量的点积时,结果似乎受到了影响,也就是说,a被当作一个“负数”来处理。

np.finfo(float).eps 

返回的结果是 -2.22044605e-16

这里有一个例子:

a = np.array([[-2.22044605e-16,-2.22044605e-16]])

b = np.array([[5,5]])

np.dot(a,b)
array([[ -2.22044605e-15]])

a = np.array([[-2.22044605e-16,2.22044605e-16]])
np.dot(a,b.T)
array([[ 0.]])

2 个回答

2

可以试试 numpy.allclose

从这个链接可以了解到:

numpy.allclose(a, b, rtol=1e-05, atol=1e-08)

如果两个数组在一定的容差范围内逐个元素相等,就会返回 True。

这个容差值是正数,通常是非常小的数字。相对差值(rtol * abs(b))和绝对差值 atol 会加在一起,用来和 a 和 b 之间的绝对差值进行比较。

如果任意一个数组里有一个或多个 NaN(不是一个数字),就会返回 False。如果两个数组中相同位置的元素都是无穷大,并且符号相同,那么它们会被认为是相等的。


如果下面的等式在逐个元素上都为 True,那么 allclose 会返回 True

    absolute(a - b) <= (atol + rtol * absolute(b))

举个例子

>>> np.allclose([1e10,1e-7], [1.00001e10,1e-8])
False
>>> np.allclose([1e10,1e-8], [1.00001e10,1e-9])
True
>>> np.allclose([1e10,1e-8], [1.0001e10,1e-9])
False
>>> np.allclose([1.0, np.nan], [1.0, np.nan])
False

所以:

与其这样做:

>>> 0 == -2.22044605e-16
False

不如这样做:

>>> import numpy as np
>>> np.allclose([0], [-2.22044605e-16])
True
2

虽然 a 可能等于机器精度,但这并不意味着它就是零!实际上,2.22044605e-16 这个数比 float64 能表示的最小值要大得多,那个最小值是:

np.finfo(float).tiny  # = 2.2250738585072014e-308

我想你在这里看到的是误差传播舍入误差。在你的第二个例子中,你只是碰巧让舍入误差相互抵消了。

撰写回答