0

私は学部生として物理学の研究に取り組んでおり、そのためには c++ を使用して 348x348 のオーダーで大きな行列を乗算する必要があります。先生は、6x6 や 12x12 などの小さな行列を使用してコードをテストするように指示し、それらの行列を使用して、探していたものを正確に取得しました。しかし、348x348 の場合とまったく同じコードを使用しようとすると、行列の乗算に対して正しい出力が得られません。プログラムにいくつかのデータを読み取らせ、データを行列として配置し、すべてのデータが正しく読み取られたことを確認しました。しかし、私はまだ行列の正しい積を得ていません。私は C++ ライブラリ Eigen を使用しており、行列の要素の数値を double として読み込んでいます。私の先生は自分のプログラムで計算を行い、正しい結果を得ています。そう、

myOutfile << NormCoord.transpose() * SqrtMass * NormCoord << endl;

これが実際の乗算です。単位行列を取得する必要がありますが、大きな行列では、対角要素が 2 倍ずれており、少なくともオンにしたい場合、一部の非対角要素が 0.0001 のオーダーで少し大きすぎます。 10^(-6)のオーダー

4

1 に答える 1

0

私の推測: 問題は、行列データをファイルに保存する場所です。

double次のようなファイルに保存する場合を参照してください。

double d=...;
out_file<<d;

その後、次のようにファイルから読み取ります。

in_file>>d;

同じ番号は得られません。double は書き込み時に切り捨てられ、おおよその数しか得られません (重大なエラーが追加される可能性があります)。

数値は印刷しない場所で正確に切り捨てられるため、マトリックスを印刷するときにエラーを確認することはできません。しかし、データを 348x348 の行列として乗算すると、誤差は 348*2=696 倍になり、表示するのに十分な大きさになります。

と同じことprintf/scanf

ソリューション?データを書き込むときに精度を追加します。

out_file<<std::setprecision(20)<<d; // need to #include<iomanip>

(「たくさんある」以外の正当な理由で 20 を入れました。多かれ少なかれ必要な場合があります - double の精度が実際に何であるかはわかりません)

またはさらに良いことに、可能であれば保存はバイナリデータです。

編集printfあなたはこれを行います:

printf("%.20lf",d);
于 2013-10-28T06:10:09.883 に答える