これまで言及されていなかったと思われるのは、不安定なアルゴリズムと悪条件の問題の概念です。前者を最初に取り上げますが、これは初心者の数値学者にとってより頻繁な落とし穴のようです。
(逆数)黄金比のべき乗の計算を検討してくださいφ=0.61803…
。それについて移動するための1つの可能な方法は、漸化式を使用することでφ^n=φ^(n-2)-φ^(n-1)
始まる、φ^0=1
とφ^1=φ
。お気に入りのコンピューティング環境でこの再帰を実行し、結果を正確に評価された能力と比較すると、重要な数字のゆっくりとした侵食が見つかります。Mathematicaでのインスタンスの例を次に示します:
ph = N[1/GoldenRatio];
Nest[Append[#1, #1[[-2]] - #1[[-1]]] & , {1, ph}, 50] - ph^Range[0, 51]
{0., 0., 1.1102230246251565*^-16, -5.551115123125783*^-17, 2.220446049250313*^-16,
-2.3592239273284576*^-16, 4.85722573273506*^-16, -7.147060721024445*^-16,
1.2073675392798577*^-15, -1.916869440954372*^-15, 3.1259717037102064*^-15,
-5.0411064211886014*^-15, 8.16837916750579*^-15, -1.3209051907825398*^-14,
2.1377864756200182*^-14, -3.458669982359108*^-14, 5.596472721011714*^-14,
-9.055131861349097*^-14, 1.465160458236081*^-13, -2.370673237795176*^-13,
3.835834102607072*^-13, -6.206507137114341*^-13, 1.004234127360273*^-12,
-1.6248848342954435*^-12, 2.6291189633497825*^-12, -4.254003796798193*^-12,
6.883122762265558*^-12, -1.1137126558640235*^-11, 1.8020249321541067*^-11,
-2.9157375879969544*^-11, 4.717762520172237*^-11, -7.633500108148015*^-11,
1.23512626283229*^-10, -1.9984762736468268*^-10, 3.233602536479646*^-10,
-5.232078810126407*^-10, 8.465681346606119*^-10, -1.3697760156732426*^-9,
2.216344150333856*^-9, -3.5861201660070964*^-9, 5.802464316340953*^-9,
-9.388584482348049*^-9, 1.5191048798689004*^-8, -2.457963328103705*^-8,
3.9770682079726053*^-8, -6.43503153607631*^-8, 1.0412099744048916*^-7,
-1.6847131280125227*^-7, 2.725923102417414*^-7, -4.4106362304299367*^-7,
7.136559332847351*^-7, -1.1547195563277288*^-6}
の結果φ^41
は間違った符号を持ち、さらに早い段階で計算された値と実際の値はφ^39
共通の数字を共有しません(3.484899258054952
* ^-9 for the computed version against the true value
7.071019424062048 *^-9
)。したがって、アルゴリズムは不安定であり、不正確な算術演算ではこの再帰式を使用しないでください。これは、再帰式の固有の性質によるものです。この再帰には「減衰」および「成長」ソリューションがあり、代替の「成長」ソリューションがある場合、前方ソリューションによって「減衰」ソリューションを計算しようとします数値的悲嘆のため。したがって、数値アルゴリズムが安定していることを確認する必要があります。
さて、条件の悪い問題の概念に移りましょう:数値的に何かを行う安定した方法があるかもしれませんが、それはあなたのアルゴリズムでは解決できないということです。これは問題自体の問題であり、解決方法ではありません。数値の標準的な例は、いわゆる「ヒルベルト行列」を含む線形方程式の解法です。
行列は、条件の悪い行列の標準的な例です。大きなヒルベルト行列を持つシステムを解こうとすると、不正確な解が返される可能性があります。
以下はMathematicaのデモです。正確な算術の結果を比較します
Table[LinearSolve[HilbertMatrix[n], HilbertMatrix[n].ConstantArray[1, n]], {n, 2, 12}]
{{1, 1}, {1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1, 1}, {1, 1, 1, 1, 1,
1}, {1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1,
1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}}
および不正確な算術
Table[LinearSolve[N[HilbertMatrix[n]], N[HilbertMatrix[n].ConstantArray[1, n]]], {n, 2, 12}]
{{1., 1.}, {1., 1., 1.}, {1., 1., 1., 1.}, {1., 1., 1., 1., 1.},
{1., 1., 1., 1., 1., 1.}, {1., 1., 1., 1., 1., 1., 1.},
{1., 1., 1., 1., 1., 1., 1., 1.}, {1., 1., 1., 1., 1., 1., 1., 1., 1.},
{1., 1., 1., 0.99997, 1.00014, 0.999618, 1.00062, 0.9994, 1.00031,
0.999931}, {1., 1., 0.999995, 1.00006, 0.999658, 1.00122, 0.997327,
1.00367, 0.996932, 1.00143, 0.999717}, {1., 1., 0.999986, 1.00022,
0.998241, 1.00831, 0.975462, 1.0466, 0.94311, 1.04312, 0.981529,
1.00342}}
(Mathematicaで試してみた場合、悪条件が現れることを警告するいくつかのエラーメッセージに気付くでしょう。)
どちらの場合も、単に精度を上げるだけでは解決できません。避けられない数字の浸食を遅らせるだけです。
これはあなたが直面するかもしれないものです。解決策は難しいかもしれません。最初は、図面に戻るか、他の人があなたよりも優れた解決策を見つけたかどうかを調べるために、ジャーナル/書籍/その他何でも探します。第二に、あなたはあきらめるか、より扱いやすい何かにあなたの問題を再定式化します。
ダイアン・オレアリーからの引用をお送りします。
人生は悪条件の問題を投げかけるかもしれませんが、不安定なアルゴリズムに落ち着く正当な理由はありません。