web-dev-qa-db-ja.com

C / C ++での派生物の実装

f(x)の導関数は、最大の精度を確保するためにプログラムで通常どのように計算されますか?

Newton-Raphson メソッドを実装していますが、関数の導関数を取得する必要があります。

21
vehomzzz

@erikkallenに同意します。_(f(x + h) - f(x - h)) / 2 * h_は、導関数を数値的に近似するための通常のアプローチです。ただし、正しいステップサイズhを取得するのは少し微妙です。

f(x + h) - f(x - h)) / 2 * hの近似誤差は、hが小さくなるほど小さくなります。つまり、hをできるだけ小さくする必要があります。ただし、hが小さくなるほど、分子はほぼ等しい数を減算する必要があるため、浮動小数点減算からの誤差が増加します。hが小さすぎると、減算の精度が大幅に失われる可能性があります。したがって、実際には、 近似エラーと数値エラーの組み合わせを最小にするhの小さな値。

経験則として、h = SQRT(DBL_EPSILON)を試すことができます。ここで、_DBL_EPSILON_は、マシン精度で_1 + e != 1_になるような最小の倍精度数eです。 _DBL_EPSILON_は_10^-15_の略なので、_h = 10^-7_または_10^-8_を使用できます。

詳細については、微分方程式のステップサイズの選択に関する notes を参照してください。

60
John D. Cook

Newton_Raphsonは、2つの関数f(x)とその導関数f '(x)があると想定しています。導関数が関数として利用できず、元の導関数から導関数を推定する必要がある場合次に、別のルート検索アルゴリズムを使用する必要があります。

ウィキペディアの根の発見 は、数値分析のテキストと同様にいくつかの提案を提供します。

10
user151019

alt text

alt text

1)最初のケース:

alt text

alt text —相対丸め誤差。doubleの場合は約2 ^ {-16}、floatの場合は2 ^ {-7}。

総誤差を計算できます:

alt text

ダブルフローティング操作を使用しているとします。したがって、hの最適値は2sqrt(DBL_EPSILON /f ''(x))です。 f ''(x)はわかりません。ただし、この値を見積もる必要があります。たとえば、f ''(x)が約1の場合、hの最適値は2 ^ {-7}です。 f ''(x)が約10 ^ 6の場合、hの最適値は2 ^ {-10}です!

2)2番目のケース:

alt text

2番目の近似誤差は、最初の近似誤差よりも0になる傾向があることに注意してください。しかし、f '' '(x)が非常に大きい場合は、最初のオプションの方がより望ましいです。

alt text

最初のケースでは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であるとします。また、2つの浮動小数点演算を使用するとします。最初のケースでは、hは約2 ^ {-8}、最初のケースではhは約2 ^ {-5}です。 f ''(x)またはf '' '(x)がわかっている場合は、この値を修正してください。

9
Alexey Malistov

John Pickのhの選択に関する提案を間違いなく考慮に入れたいと思いますが、微分を近似するために中央の差を使用することは通常ありません。主な理由は、前方差分を使用すると、追加の関数評価が必要になることです。つまり、

f'(x) = (f(x+h) - f(x))/h

次に、f(x))の値を無料で取得します。これは、ニュートン法ですでに計算する必要があるためです。これは、スカラー方程式がある場合はそれほど重要ではありませんが、 xがベクトルの場合、f '(x)は行列(ヤコビアン)であり、中心化差分アプローチを使用してそれを近似するには、n回の追加の関数評価を行う必要があります。

5
MikeT
fprime(x) = (f(x+dx) - f(x-dx)) / (2*dx)

小さなdxの場合。

5
erikkallen

F(x)について何を知っていますか?ブラックボックスとしてfしかない場合は、導関数を数値的に近似することしかできません。しかし、精度は通常それほど良くありません。

Fを計算するコードに触れることができれば、muchをよりよく実行できます。 "自動微分" を試してください。そのためのいくつかの素敵なライブラリがあります。少しライブラリマジックを使用すると、関数を簡単に導関数を自動的に計算するものに変換できます。簡単なC++の例については、 これのソースコード ドイツ語の説明を参照してください。

5
sellibitze

上記のJohn D. Cooksの回答に加えて、浮動小数点の精度だけでなく、関数f(x)のロバスト性も考慮することが重要です。たとえば、金融では、f(x)が実際にはモンテカルロシミュレーションであり、f(x)の値がこれらの場合、非常に小さなステップサイズを使用すると、導関数の精度が大幅に低下する可能性があります。

3
Rickard

通常、信号ノイズは、何よりもデリバティブの品質に影響を与えます。 f(x)にノイズがある場合、Savtizky-Golayは優れた平滑化アルゴリズムであり、良い導関数の計算によく使用されます。簡単に言うと、SGは多項式をローカルでデータに適合させ、この多項式を使用して導関数を計算できます。

ポール

1
Paul