2015-10-05 38 views
11

いくつかのnumpyのものを探している間、私はnumpy.dotの丸め精度()議論質問に出くわした:私は2つの(異なる)コンピュータを持って起こるのでnumpyの浮動小数点丸め誤差

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

をハーフウェルCPUが私の机の上に座ってFMAとすべてを提供すべきだと私は最初の答えでオフィオンによって与えられた例をテストすると思っていたが、私は幾分驚いた結果を得た:

更新/ 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()よりも正確です。しかし、.dot()の方がfloat64とfloat128の方が速い(ただしそれほど多くない)ことが確認されています。

誰でも説明ができますか?

編集:誤ってnumpyバージョンの情報を削除しました:python 3.4.0と3.4.1で1.9.0と1.9.3と同じ結果が出ました。

+1

興味深いことに、この不一致は、NumPy 1.8.2ではなく、NumPy 1.9.2でのみ発生します。 両方ともblas + lapack(アトラスではない)を使用します。 NumPy 1.8.2では、結果はNumPy 1.9.2で同じ丸めイベントを示唆するドットとサムと同じですが、乗算+サム()はより正確です。 –

+0

http://docs.scipy.org/doc/numpy/release.html#better-numerical-stability-for-sum-in-some-cases –

+1

も参照してください。https://github.com/numpy/numpy/pull/3685、これは 'sum'の変更が実装された場所です。 –

答えて

2

数値安定性を向上させるために、最近彼らがPairwise Summationndarray.sumに特殊文字を追加したようです。 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を参照してください。

+0

"分割と征服"アルゴリズム。はい、それは感謝します、ありがとう。 –

+0

これは、実際には、統合された関数よりも行列を計算するために代替戦略を使用する方が良いということですか?これは、皮肉なことに、科学的な仕事を簡単にすることが目的だからです。 –

関連する問題