ナンシードットは、コンパイル時にリンクするBLASライブラリを呼び出すルーチンの1つです(または独自にビルドします)。 BLASライブラリでは、計算が実行する丸めの回数を制限する乗算累積演算(通常はFused-Multiply Add)を使用できます。
は以下ください:
>>> a=np.ones(1000,dtype=np.float128)+1E-14
>>> (a*a).sum()
1000.0000000000199948
>>> np.dot(a,a)
1000.0000000000199948
ない正確な、しかし十分に近いです。それはナイーブ(a*a).sum()
がないこと約浮動小数点丸め数の半分を使用するように
>>> a=np.ones(1000,dtype=np.float64)+1E-14
>>> np.dot(a,a)
1000.0000000000176 #off by 2.3948e-12
>>> (a*a).sum()
1000.0000000000059 #off by 1.40948e-11
np.dot(a, a)
は、二つの、より正確であろう。
Nvidiaの書籍には、4桁の精度の例があります。最寄りの4桁の数字に4ラウンドのrn
スタンド:もちろん浮動小数点数の
x = 1.0008
x2 = 1.00160064 # true value
rn(x2 − 1) = 1.6006 × 10−4 # fused multiply-add
rn(rn(x2) − 1) = 1.6000 × 10−4 # multiply, then add
は、ベース10に16小数点第2位を四捨五入していますが、アイデアを得るされていません。
out=0
for x in a:
out=rn(x*x+out) #Fused multiply add
(a*a).sum()
であるが:このから
arr=np.zeros(a.shape[0])
for x in range(len(arr)):
arr[x]=rn(a[x]*a[x])
out=0
for x in arr:
out=rn(x+out)
数を使用して2倍の数倍に丸められていることを確認するために、その簡単にいくつかの追加の擬似コードで上記表記でnp.dot(a,a)
を配置
(a*a).sum()
と比較してnp.dot(a,a)
となります。これらの小さな差は、答えを微妙に変えることができます。追加のexmaplesはhereを見つけることができます。
これは加重平均です。 ['np.average'](http://docs.scipy.org/doc/numpy/reference/generated/numpy.average.html)を使うだけでいいかもしれません。 – user2357112
"数値的に正確な"部分は、ドットを使用するのではなく、値から平均を差し引くことを指していたと思います。 – user2357112