Numpy 浮点舍入错误

Numpy floating point rounding errors

在搜索一些 numpy 的东西时,我遇到了一个讨论 numpy.dot() 舍入精度的问题:

Numpy: Difference between dot(a,b) and (a*b).sum()

因为我桌上正好有两台(不同的)带有 Haswell-CPU 的计算机,它们应该提供 FMA 和一切,我想我会测试 Ophion 在第一个答案中给出的例子,我得到了结果让我有些吃惊:

在 updating/installing/fixing lapack/blas/atlas/numpy 之后,我在两台机器上都得到了以下信息:

>>> a = np.ones(1000, dtype=np.float128)+1e-14
>>> (a*a).sum()
1000.0000000000199999
>>> np.dot(a,a)
1000.0000000000199948

>>> a = np.ones(1000, dtype=np.float64)+1e-14
>>> (a*a).sum()
1000.0000000000198
>>> np.dot(a,a)
1000.0000000000176

所以标准乘法+sum()比np.dot()更精确。然而,timeit 确认 .dot() 版本对于 float64 和 float128 都更快(但不多)。

谁能解释一下?

编辑:我不小心删除了有关 numpy 版本的信息:1.9.0 和 1.9.3 与 python 3.4.0 和 3.4.1 的结果相同。

他们最近似乎在 ndarray.sum 中添加了一个特殊的 Pairwise Summation 以提高数值稳定性。

PR 3685 开始,这会影响:

all add.reduce calls that go over float_add with IS_BINARY_REDUCE true
so this also improves mean/std/var and anything else that uses sum.

有关代码更改,请参阅 here