f(x)
最大の精度を確保するために、通常プログラムで計算された の微分はどのように行われますか?
私はニュートン・ラフソン法を実装していますが、関数の導関数を取得する必要があります。
f(x)
最大の精度を確保するために、通常プログラムで計算された の微分はどのように行われますか?
私はニュートン・ラフソン法を実装していますが、関数の導関数を取得する必要があります。
(f(x + h) - f(x - h)) / 2 * h
導関数を数値的に近似するための通常のアプローチである@erikkallenに同意します。ただし、適切なステップサイズhを取得することは少し微妙です。
(の近似誤差は、小さくなるf(x + h) - f(x - h)) / 2 * h
につれて減少します。つまり、可能な限り小さくh
する必要があります。ただし、小さくなると、分子はほぼ等しい数を減算する必要があるため、浮動小数点減算による誤差が増加します。小さすぎると、減算には多くの精度があります。したがって、実際には、近似誤差と数値誤差の組み合わせを最小限に抑える、小さすぎない値を選択する必要があります。h
h
h
h
経験則として、マシンの精度 のように、最小の倍精度数はh = SQRT(DBL_EPSILON)
どこにあるかを試すことができます。またはを使用できるようにするためです。DBL_EPSILON
e
1 + e != 1
DBL_EPSILON
10^-15
h = 10^-7
10^-8
詳細については、微分方程式のステップサイズの選択に関するこれらの注意事項を参照してください。
Newton_Raphsonは、2つの関数f(x)とその導関数f'(x)を持つことができると想定しています。関数として使用できる導関数がなく、元の関数から導関数を推定する必要がある場合は、別の求根アルゴリズムを使用する必要があります。
ウィキペディアの求根アルゴリズムは、数値解析テキストと同様にいくつかの提案を提供します。
1) 最初のケース:
— 相対丸め誤差、double の場合は約 2^{-16}、float の場合は 2^{-7}。
合計エラーを計算できます。
ダブルフローティング操作を使用しているとします。したがって、 hの最適値は 2sqrt(DBL_EPSILON/ f''(x) ) です。あなたはf''(x)を知りません。しかし、この値を見積もる必要があります。たとえば、f''(x)が約 1 の場合、hの最適値は 2^{-7} ですが、f''(x)が約 10^6 の場合、hの最適値は 2^{- 10}!
2) 2 番目のケース:
2 番目の近似誤差は、最初の近似誤差よりも速く 0 になる傾向があることに注意してください。しかし、f'''(x) が非常に遅れている場合は、最初のオプションがより望ましいです。
最初のケースでは h は e に比例しますが、2 番目のケースでは h は e^{1/3} に比例することに注意してください。二重浮動演算の場合、e^{1/3} は 2^{-5} または 2^{-6} です。(f'''(x) は約 1 だと思います)。
どちらの方法が良いですか?f''(x) と f'''(x) がわからない場合、またはこれらの値を推定できない場合は不明です。2番目のオプションが望ましいと考えられています。しかし、f'''(x) が非常に大きいことがわかっている場合は、最初のものを使用します。
h の最適値は? f''(x) と f'''(x) が約 1 であると仮定します。また、二重浮動演算を使用すると仮定します。次に、最初のケースでは h は約 2^{-8} であり、最初のケースでは h は約 2^{-5} です。f''(x) または f'''(x) がわかっている場合は、この値を修正します。
fprime(x) = (f(x+dx) - f(x-dx)) / (2*dx)
いくつかの小さな dx の場合。
h を選択するための John Cook の提案を確実に考慮に入れる必要がありますが、通常、導関数を近似するために中心差を使用することは望ましくありません。主な理由は、前方差分を使用する場合、追加の関数評価が必要になることです。つまり、
f'(x) = (f(x+h) - f(x))/h
次に、ニュートン法のためにすでに計算する必要があるため、f(x) の値を無料で取得します。スカラー方程式がある場合、これはそれほど大したことではありませんが、x がベクトルの場合、f'(x) は行列 (ヤコビアン) であり、それを近似するために追加の関数評価を n 回行う必要があります。中心差アプローチを使用します。
f(x)について何を知っていますか?ブラック ボックスとして f しかない場合、できることは導関数を数値的に近似することだけです。しかし、精度は通常それほど良くありません。
f を計算するコードに手を加えることができれば、はるかに優れた結果が得られます。「自動微分」を試してみてください。そのための便利なライブラリがいくつかあります。ちょっとしたライブラリ マジックを使えば、関数を導関数を自動的に計算する関数に簡単に変換できます。簡単な C++ の例については、このドイツ語のディスカッションのソース コードを参照してください。
上記のJohnD.Cooksの回答に加えて、浮動小数点の精度だけでなく、関数f(x)のロバスト性も考慮することが重要です。たとえば、金融では、f(x)が実際にはモンテカルロシミュレーションであり、f(x)の値にノイズが含まれているのが一般的なケースです。これらの場合、非常に小さいステップサイズを使用すると、導関数の精度が大幅に低下する可能性があります。
通常、信号ノイズは微分品質に何よりも影響を与えます。f(x) にノイズがある場合、Savtizky-Golay は優れた平滑化アルゴリズムであり、適切な導関数を計算するためによく使用されます。簡単に言えば、SG は多項式をデータにローカルに適合させ、この多項式を使用して導関数を計算できます。
ポール