2017-03-20 2 views
0

私はGauss EliminatorをCで作成しようとしています。これは時々、行列が数値的に特異であるかどうかをチェックする必要があります。ある数(double)が非常に非常に小さい場合です。ダブルに推奨される最小イプシロンは何ですか?

if(0 == matrix->items[from]){ 
     fprintf(stderr,"Matrix is still singular after attempting pivot. Exitig.\n"); 
} 

これは真になることはありません:

私の問題は、私はこれを行うにしようということ、です。しかし、プログラムを実行しようとすると、このような場合は、それを乗算するかどうか、またはその組み合わせに応じて、infまたはNaNで数値が埋められます。

これらをフィルタリングするために、私はこのような何か必要があります:

#define EPSILON very_small 
// rest of the code 
if(matrix->items[from] < EPSILON){ 
    ...singular 
} 

をこのEPSILONの推奨値とは何ですか?それは倍精度の絶対精度か、多少大きな値ですか?良いだろうところで、

、上記のようにマクロとしてそれを定義するか、それが好きで使用して:

const double EPSILON = ...; 

申し訳ありませんが、私は十分に明確されていないよ場合は、英語が母国語ではありません。

返信いただきありがとうございます。

+3

'if(0 == matrix-> items [from]')と書いてはいけません。本当に醜いです。そして、現代のコンパイラは、あなたが誤って代わりに代入を使用すると文句を言うので、これはもはや「*良い*」の習慣ではありません。 –

+0

正しい値は1つだけです: 'DBL_EPSILON'です。 – Olaf

+2

@Olafなぜそれが唯一の正しい値ですか? – immibis

答えて

2

私は行列が数値的に

通常、これはdoubleオーバーフローを防止することにより、検出された特異であるかどうかを確認する必要があります。 DBL_EPSILON(例:2E-16)を使用して

// Check if 1.0/determinant will overflow. 
if (fabs(determinant) <= 1.0/(0.99*DBL_MAX)) { 
    Handle_Singular_Case() 
} else { 
    one_over_det = 1.0/determinant; 
} 

は通常間違っ溶液です。 double数学の必要性相対の比較は、1.0の大きさから遠く離れた良い計算を保証します。

// Rarely the right thing to do. 
#define EPSILON DBL_EPSILON 
if(fabs(matrix->items[from]) < EPSILON){ 

これは非常に文脈依存です@Weather Vaneです。


しかしOPの本当の問題はここに確かにある:「プログラムを実行しようとしたとき、このような場合には掛けるか、その組み合わせで割るかどうかに応じて、INFまたはNaNに数字を埋めます。」。 partial pivotingで排除するなど、さまざまな手法を使用してこの問題を回避できます。

の問題を解決するには、コードとサンプルデータを投稿するのが最適です。

+1

一般的に数値的安定性のためのアルゴリズムを構造化すること、そして特にこの目的のために部分的なピボットを行うことについてよく見ています。数学を良いプログラムに変換することは、式を選択した言語の構文に変換するほど簡単ではありません。 –

+1

@JohnBollinger真。行列操作を受容的に計算すると、さまざまな落とし穴が隠されます。私は部分的なピボットコードで何年も、 'abs()'と 'fabs()'ではなく、警告が不十分であるという最大要素を見つけるためのバグがあった。エラーはすべての要素| 1.0未満であった - 0.0の除算が後で発生した。 – chux

+0

'(1.0 * DBL_EPSILON)'のポイントは何ですか?実際に何かを乗算することはできますか? – rici

関連する問題