2017-07-03 19 views
-1

私は32ビットの浮動小数点数の大きいNを含むファイルを持っています。次のようにこのファイルはnumpys memmap機能を使用して作成されます。C mmapとnumpy memmapの相違

mmoutput = np.memmap("filename", dtype='f4', mode='w+', offset=0, shape=N) 
mmoutput[:] = my_floats 
mmoutput.flush() 

私は戻ってnumpyのを使用してこれらの係数をロードして使用してそれらを合計すると:

mminput = np.memmap("filename", dtype="f4", mode='c', offset=0, shape=N) 
mminput.sum() 

を私は(正しい)値82435.047を取得します。しかし

、私は次のようにCさんのmmapを使用して浮動小数点数に読ま:

int fd = open("filename", O_RDONLY, 0); 
float * coefs = (float*) mmap(NULL, sizeof(float) * N, PROT_READ, MAP_SHARED, fd, 0); 
double sum = 0.0; 
for (int i = 0; i < N; i++) sum += coefs[i]; 

数字の合計を別の値に:82435.100。

誰かが私のエラーを見つけるのを助けることができますか?おそらく、numpyがその浮動小数点数を書き、Cがそれらを読み取る方法に違いがありますか?

全開示

は、私は実際にちょうどそれらが同じであるチェックとしてこれらの数字の合計を計算しました。それらの実際の使用はbsplineの係数として(例えば、ここではhttps://github.com/ahay/src/blob/master/user/cram/esc_slow2.cのようにeinsplineライブラリを使用して実装されています)。私がPythonとCのスプラインを評価するとき、私は異なる値を取得します。

+0

例に集計コードはありません。 –

+0

フェアポイント - 今すぐ追加 – JMzance

+0

@JMzance開始する前に 'sum'を0に設定する方法を示してください。 – unwind

答えて

0

私は値が82435.047(これは正しい)です。

いいえそうではありません。 「多数の」単精度浮動小数点値が合計されているため、4桁または5桁以上の有効桁数は正確ではありません。特に値に大きなダイナミックレンジがある場合は特にそうです。

numpyは、倍精度に変換するなど、精度を向上させる合計を実行していると考えられます。 sourceはumath.add.reduceをいくつか呼び出すと痕跡が残るので、倍精度で加算される可能性があります。倍精度に変換するか、Kahan summationを使用して精度を失わない結果を得る - Kahanはダイナミックレンジエフェクトの補正を行っているので、加算の減少よりも正確な結果を得ます。

+0

float sumではなくdouble sum = 0.0を使用すると、合計が改善されます。しかし、価値はそれほどではありませんが、依然として異なります。そして値をbsplineに代入して評価すると、結果は異なる – JMzance

+0

@JMzance正確に同じ結果が必要な場合は、numpyと同じ実装方法と最適化を使用します。しかし、アプリケーションで合計の有効数字が6つ必要な場合は、各操作で精度が失われるため、データを浮動小数点にしてはいけません。あなたの目標はnumpyで、あなたのシンプルなCコードはまったく同じように動作しているか、あるいは「これらの値の合計は何ですか?」という答えを得ようとしていますか? –

+0

前者 - 係数として使うために同じ単精度浮動小数点数をeinsplineに渡す必要があります。ファイルからまったく同じものが読み込まれていれば、別のものに集約されても構いません – JMzance

関連する問題