数値微分を計算したい場合、ここで Bengt Fornbergが提示した(およびここで報告した)方法は非常に便利です(正確で実装が簡単です)。1988年からの元の論文の日付として、今日、より良い代替案があるかどうか(または(ほぼ)単純かつ正確に)知りたいのですが。
数値微分を計算したい場合、ここで Bengt Fornbergが提示した(およびここで報告した)方法は非常に便利です(正確で実装が簡単です)。1988年からの元の論文の日付として、今日、より良い代替案があるかどうか(または(ほぼ)単純かつ正確に)知りたいのですが。
回答:
良い質問。R. Baltenspergerによる「任意のコロケーションポイントに対する行列微分法の精度の向上」というタイトルの論文があります。私の意見では大したことではありませんが、ポイントがあります(2000年に登場する前に既に知られていました):定数関数の導関数がゼロである(これは数学的に正確に成り立つが、必ずしも数値表現では成り立たない)。
これは、n番目の導関数行列の行合計がゼロである必要があることを確認するのは簡単です。対角線エントリを調整することにより、つまりD (n )j jを設定することにより、この制約を実施するのが一般的です。= − N ∑ i = 1 i ≠ j D i j
さて、論文(およびその中の参考文献)は、導関数の誤差はゼロからの行合計の偏差のオーダーであると述べています。したがって、目標はこれらをできるだけ数値的に小さくすることです。
良い点は、Fornbergの手順がこの点で非常に良いように見えることです。以下の図では、さまざまな数のチェビシェフ-ロバットコロケーションポイントについて、正確な、つまり分析的な1次導関数行列とFornbergアルゴリズムによって導出された行列の動作を比較しました。
繰り返しになりますが、引用された論文の声明を信じて、これは、Fornbergアルゴリズムが微分に対してより正確な結果をもたらすことを意味します。
結論として、Fornbergの方法は非常に正確であり、の場合、分析式の結果よりも約3桁正確です。これは、ほとんどのアプリケーションで十分正確でなければなりません。さらに、Fornbergは彼の方法にこの事実を明示的に含めていないように見えるため、これは注目に値します(少なくとも2つのFornbergの論文には言及されていません)。
この例では、式(4)を簡単に含めることで、もう1桁の大きさを得ることができます。これは非常に単純なアプローチであり、各デリバティブに一度だけ適用されるため、使用しない理由はありません。
丸め誤差を減らすために式(1)の合計を評価するためのより洗練されたアプローチを使用するBaltensperger論文の方法では、誤差とほぼ同じ桁の誤差が得られます。したがって、少なくともこの例では、上記の「調整されたFornberg」メソッドとほぼ同等です。
連続関数の数値実装を区別しようとしていると仮定すると、多数の方法があります。
1)自動差別化。最も正確で一般的な方法。コードに問題があり、演算子のオーバーロードと引数依存のルックアップが必要です。これらの概念を理解するためにユーザーに負担をかけます。また、 sincを区別するなど、取り外し可能な特異点と格闘してい。
2)チェビシェフ変換。チェビシェフ多項式の範囲に関数を投影し、3項の繰り返しを区別します。超高速、非常に正確。ただし、コンパクトにサポートされている対象ドメインが必要です。選択したドメイン外部では、3項の繰り返しは不安定です。
3)有限差分。1Dで過小評価されています。Nick Highamの「数値計算のヒントとコツ」を参照してください。つまり、切り捨てエラーと丸めエラーのバランスを取る場合、ステップサイズを選択する必要はありません。自動的に選択できます。Boostでは、このアイデアを使用して(デフォルトで)型の正しい数字の6/7を回復します。(Highamは正しい桁の1/2の単純なケースのアイデアのみを示していますが、アイデアは簡単に拡張できます。)係数はFornbergの等間隔テーブルからのものですが、ステップサイズは関数が1ULPに評価できるという仮定の下で選択されます正確さ。欠点は、型の半分の桁を回復するのに2回の関数評価が必要であり、3/4桁の数字を回復するのに4回必要であるということです。1Dでは、悪いことではありません。高次元では壊滅的です。
4)複雑なステップ微分。使用。テイク単位の丸めであることを、これは、ほぼすべてのビットの正しい回復します。ただし、複雑なプレーンに関数を実装することは、その実際の導関数を手作業でコーディングするよりも一般に難しいため、ちょっとした不正行為です。まだクールなアイデアと特定の状況で便利です。
Fornbergのアルゴリズムを改善した人はいません(彼のやや最近の論文も参照してください)。余談ですが、数値微分を計算する方法として彼のアルゴリズムを見ることは正しくないと思われます。彼がやったことは、有限差分法の重みを計算する効率的なアルゴリズムを導き出すことだけです。彼の方法の利点は、一度に目的のデリバティブまでのすべてのデリバティブの重みを与えることです。
Fornbergメソッドの拡張に関する他の回答に加えて、より単純な代替案についての質問をここで取り上げます。
このために、ラグランジュ補間の微分係数をより直接生成する代替スキームをスケッチします。その実装には数行のコードしか必要なく、任意のグリッドで動作し、私の最初の実験によると、Fornbergのように正確です。
実装の基礎は虚数ステップ微分
ここでは、機械精度の順序の変数です。虚数ステップ微分は、微分値を安定して生成することが知られており、有限差分実装の数値的不安定性を被りません。
2番目の要素は、重心形式のいずれかで評価されるグリッド上のラグランジュ補間多項式。たとえば、
where
複素ステップ微分を使用するには、これらの式が複素数でも機能することを確認する必要があります引数。また、与えられた関数f(x)と係数のベクトルのため、我々はを通じて補間多項式を表しにより
アルゴリズムの概要は次のとおりです。Fornbergと同じ入力および出力パラメーターがありますが、非常に簡単です。
入力:
初期化
アルゴリズム
しばらく:
計算
複雑な工程誘導体による用すべてのと。
ここで、はの番目の行を示します。
セットo = o + 1;
出力するものを決定します。
点での有限差分係数のベクトル、ここで。これはFornbergが行うことです。
補間関数から派生順序。このためには、関数を入力する必要があります。関数値はでアルゴリズムへ。
バリアント2の補間関数を返すメタ関数。ただし、グリッド点で補間される任意の関数に対して。
個人的には、バリアント3が最も好きです。
Fornbergのように、このアルゴリズムはです。時間を見つけたら、精度、安定性などに関するより経験的な結果を投稿します。
数値微分の精度を高めるには、次の手順を実行します。
1)いくつかのステップサイズhに基づいて、お気に入りの高精度「標準」メソッドを選択します。
2)1)で選択した方法で、異なるが妥当なステップサイズhで何度も導関数の値を計算します。間隔(0.5 * H / 10、1.5 * H / 10)から乱数としてhを選択するたびに、Hは使用するメソッドの適切なステップサイズです。
3)結果を平均します。
結果は、絶対誤差wrtで2〜3桁大きくなる可能性があります。平均化されていない結果。