【发布时间】:2015-10-06 03:49:08
【问题描述】:
在搜索一些 numpy 的东西时,我遇到了一个讨论 numpy.dot() 的舍入精度的问题:
Numpy: Difference between dot(a,b) and (a*b).sum()
由于我的桌子上碰巧有两台(不同的)带有 Haswell-CPU 的计算机,它们应该提供 FMA 和一切,我想我会测试 Ophion 在第一个答案中给出的示例,我得到的结果是有点让我吃惊:
在更新/安装/修复 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 的结果相同。
【问题讨论】:
-
有趣的是,我只在 NumPy 1.9.2 上得到这种差异,而不是在 NumPy 1.8.2 上。两者都使用 blas + lapack(不是 atlas)。在 NumPy 1.8.2 中,结果与 dot 和 sum 相同,表明舍入事件相同,在 NumPy 1.9.2 上,乘法 + sum() 更精确。
-
还有github.com/numpy/numpy/pull/3685,这是对
sum进行更改的地方。 -
谁能确认 ATLAS 使用 FMA?我知道最新的 MKL 确实如此,应该是一个有趣的比较。