web-dev-qa-db-ja.com

MATLABで数値微分を計算する最良の方法は何ですか?

(注:これはコミュニティーWikiを対象としています。)

ポイントのセットがあるとしますxi= {x0x1x2 ,... xn}および対応する関数値fi= f(xi {f0f1f2 ,..., fn}、ここでfx)は、一般に、未知の関数です。)==(状況によっては、fx)は前もって行われますが、わからない知っているfx)事前に知っておいてください。) 各点でfx)の導関数を近似する良い方法は何ですかxiつまり、dfi== d/dxfi== dfxi)/ dx各ポイントでxi

残念ながら、MATLABには非常に優れた汎用の数値微分ルーチンがありません。これの理由の1つは、適切なルーチンを選択することが難しい場合があるためです。

それでは、どのような方法がありますか?どのようなルーチンが存在しますか?特定の問題に適したルーチンをどのように選択できますか?

MATLABで区別する方法を選択する場合、いくつかの考慮事項があります:

  1. シンボリック関数またはポイントのセットはありますか?
  2. グリッドは等間隔か不等間隔ですか?
  3. ドメインは定期的ですか?周期的な境界条件を想定できますか?
  4. どのレベルの精度を求めていますか?与えられた許容範囲内で導関数を計算する必要がありますか?
  5. 関数が定義されているのと同じ点で導関数が評価されることは重要ですか?
  6. デリバティブの複数の次数を計算する必要がありますか?

続行するには最良の方法は何ですか?

17
jvriesem

これらはほんの一部の簡単で汚い提案です。うまくいけば、誰かがそれらを参考にしてくれるでしょう!

1。シンボリック関数またはポイントのセットはありますか?

  • シンボリック関数がある場合は、導関数を解析的に計算できる可能性があります。 (たぶん、それが簡単だったら、あなたはこれをやっていたでしょうし、ここでは別の方法を探していません。)
  • シンボリック関数があり、導関数を分析的に計算できない場合は、常に点のセットで関数を評価し、このページにリストされている他の方法を使用して導関数を評価できます。
  • ほとんどの場合、ポイントのセット(xi、fi)があり、次のいずれかの方法を使用する必要があります。

2。グリッドは等間隔か不等間隔ですか?

  • グリッドの間隔が等間隔である場合、有限差分スキームを使用することをお勧めします(Wikipediaの記事 ここ または ここを参照) )。ただし、周期的な境界条件を使用している場合を除きます(以下を参照)。 ここ は、グリッド上の常微分方程式を解くコンテキストでの有限差分法の適切な紹介です(特にスライド9〜14を参照)。これらの方法は、一般に計算効率が高く、実装が簡単で、方法のエラーは、それを導出するために使用されるテイラー展開の打ち切りエラーとして簡単に推定できます。
  • グリッドの間隔が不均一の場合でも、有限差分スキームを使用できますが、式はより難しく、精度はグリッドの均一性によって非常に大きく変化します。グリッドが非常に不均一である場合、特定のポイントでの導関数を計算するために、おそらく大きなステンシルサイズ(より多くの隣接ポイント)を使用する必要があります。補間多項式(多くの場合 Lagrange多項式 )を作成し、その多項式を微分して導関数を計算します。たとえば、 this StackExchangeの質問を参照してください。多くの場合、これらの方法を使用してエラーを推定することは困難です(ただし、そうしようとした人もいます: here および here )。 Fornbergの方法 は、このような場合に非常に便利です。
  • ステンシルにはドメイン外のポイントが含まれることが多いため、ドメインの境界で注意する必要があります。一部の人々は、「ゴーストポイント」を導入するか、境界条件をさまざまな次数の導関数と組み合わせて、これらの「ゴーストポイント」を排除し、ステンシルを簡略化します。別のアプローチは、右側または左側の有限差分法を使用することです。
  • Here'sexcellent有限差分法の「チートシート」。低次の中央揃え、右辺、左辺のスキームを含みます。私はそれがとても便利だと思うので、私のワークステーションの近くにこれのプリントアウトを保管します。

3。ドメインは定期的ですか?周期的な境界条件を想定できますか?

  • ドメインが周期的である場合、フーリエスペクトル法を使用して非常に高い次数の精度で導関数を計算できます。この手法は、パフォーマンスをいくらか犠牲にして高精度を実現します。実際、Nポイントを使用している場合、導関数の推定は約Nオーダーの精度になります。詳細については、(例) this WikiBook を参照してください。
  • 多くの場合、フーリエ法は、素朴に実装された離散フーリエ変換(DFT)が採用するO(N ^ 2)アルゴリズムではなく、高速フーリエ変換(FFT)アルゴリズムを使用しておおよそO(N log(N))パフォーマンスを実現します。
  • 関数とドメインが周期的でない場合は、フーリエスペクトル法を使用しないでください。 周期的でない関数で使用しようとすると、大きなエラーと望ましくない「リンギング」現象が発生します。
  • 任意の次数の導関数を計算するには、1)グリッド空間からスペクトル空間への変換(O(N log(N)))、2)スペクトル波数によるフーリエ係数の乗算(O(N))、および2)anが必要です。スペクトル空間からグリッド空間への逆変換(ここでもO(N log(N)))。
  • フーリエ係数にスペクトル波数を掛けるときは注意が必要です。 FFTアルゴリズムのすべての実装には、スペクトルモードと正規化パラメーターの独自の順序があるようです。たとえば、MATLABでこれを実行する場合の注意事項については、Math StackExchangeの this question に対する回答を参照してください。

4。どのレベルの精度を求めていますか?与えられた許容範囲内で導関数を計算する必要がありますか?

  • 多くの場合、1次または2次の有限差分スキームで十分です。精度を高めるには、より高次のテーラー展開を使用して、より高次の項を削除できます。
  • 特定の許容範囲内で導関数を計算する必要がある場合は、必要なエラーのある高次のスキームを探してみてください。
  • 多くの場合、誤差を減らすための最良の方法は、有限差分スキームでグリッド間隔を減らすことですが、これが常に可能であるとは限りません。
  • 高次有限差分スキームでは、ほとんどの場合、より大きなステンシルサイズ(より多くの隣接ポイント)が必要になることに注意してください。これは境界で問題を引き起こす可能性があります。 (ゴーストポイントに関する上記の説明を参照してください。)

5。関数が定義されているのと同じ点で導関数が評価されることは重要ですか?

  • MATLABには、隣接する配列要素間の差を計算するdiff関数が用意されています。これは、一次の前方微分(または前方有限差分)スキームを介して近似導関数を計算するために使用できますが、推定は低次推定です。 difflink )に関するMATLABのドキュメントで説明されているように、長さNの配列を入力すると、長さN-1の配列が返されます。この方法を使用してNポイントで導関数を推定すると、N-1ポイントでのみ導関数の推定値が得られます。 (昇順でソートされている場合、これは不均一なグリッドで使用できることに注意してください。)
  • ほとんどの場合、すべての点で評価される導関数が必要です。つまり、diffメソッド以外のものを使用したいということです。

6。導関数の複数の次数を計算する必要がありますか?

  • 格子点関数の値と、これらの点での1次および2次の導関数がすべて相互に依存する方程式系を設定できます。これは、通常のように隣接する点でテイラー展開を組み合わせることによって見つけることができますが、微分項をキャンセルするのではなく保持し、隣接する点のそれらと一緒にリンクします。これらの方程式は、線形代数を介して解くことができ、1次導関数だけでなく2次導関数(または適切に設定されている場合は高次)も与えることができます。これらはcombined有限差分スキームと呼ばれ、compact有限差分スキームと組み合わせて使用​​されることが多いと思います。次に説明します。
  • コンパクトな有限差分スキーム( link )。これらのスキームでは、計画行列を設定し、行列ソルブを介してすべてのポイントで同時に導関数を計算します。それらは通常、同等の精度の通常の有限差分法よりも少ないステンシルポイントを必要とするように設計されているため、「コンパクト」と呼ばれます。それらはすべての点をリンクする行列方程式を含むため、特定のコンパクトな有限差分スキームは「スペクトルのような解像度」を持っていると言われます(例 Leleの1992論文 -excellent!)、つまり、すべてのノード値に応じてスペクトルスキームを模倣し、このため、すべての長さスケールで精度を維持します。対照的に、典型的な有限差分法は局所的にのみ正確です(たとえば、ポイント#13の導関数は通常、ポイント#200の関数値に依存しません)。
  • 現在の研究分野は、コンパクトなステンシルで複数の派生物をどのように解決すればよいかです。そのような研究の結果を組み合わせたコンパクトな有限差分法は強力で広く適用できますが、多くの研究者は特定のニーズ(パフォーマンス、精度、安定性、または流体力学などの特定の研究分野)。

すぐに使えるルーチン

  • 上記のように、diff関数( link からドキュメントへ)を使用して、隣接する配列要素間の大まかな微分を計算できます。
  • MATLABのgradientルーチン( link からドキュメントへ)は、多くの目的に最適なオプションです。 2次の中央差分スキームを実装します。複数の次元で導関数を計算し、任意のグリッド間隔をサポートするという利点があります。 (この明白な省略を指摘してくれた@thewaywewalkに感謝!)

  • 私はFornbergの方法(上記を参照)を使用して小さなルーチン(nderiv_fornberg)任意のグリッド間隔で1次元の有限差分を計算します。使いやすいと思います。境界には6ポイントの両面ステンシルを使用し、内部には中央に5ポイントのステンシルを使用します。これは、MATLAB File Exchange here で入手できます。

結論

数値微分の分野は非常に多様です。上記の方法ごとに、独自の利点と欠点のセットを持つ多くのバリアントがあります。この投稿は、数値微分の完全な扱いではありません。

アプリケーションはそれぞれ異なります。うまくいけば、この投稿が興味のある読者に、自分のニーズに合った方法を選択するための考慮事項とリソースの整理されたリストを提供します。

このコミュニティWikiは、MATLABに固有のコードスニペットと例で改善される可能性があります。

19
jvriesem

私はこれらの特定の質問にもっとあると思います。したがって、私はこの主題について次のようにさらに詳しく説明しました:

(4)Q:どのレベルの精度を求めていますか?与えられた許容範囲内で導関数を計算する必要がありますか?

A:数値微分の精度は、対象のアプリケーションにとって主観的です。通常、それが機能する方法は、NDインフォワード問題を使用して導関数を近似し、対象の信号から特徴を推定する場合、ノイズの摂動に注意する必要があります。通常、このようなアーチファクトには高周波成分が含まれており、微分器の定義により、ノイズ効果は$ i\omega ^ n $の大きさで増幅されます。したがって、微分器の精度を上げる(多項式の精度を上げる)ことはまったく役に立ちません。この場合、微分のノイズの影響をキャンセルできるはずです。これは、ケースケードの順序で実行できます。最初に信号を平滑化してから、微分します。しかし、これを行うより良い方法は、「ローパス微分器」を使用することです。 MATLABライブラリの良い例は here です。

ただし、これが当てはまらず、ソルベントPDEなどの逆問題でNDを使用している場合、微分器のグローバルな精度は非常に重要です。どのブナディ条件(BC)が問題に適しているかによって、設計はそれに応じて適応されます。サンプのルールは、既知の数値精度を高めることで、フルバンド微分器です。適切なBCを処理する微分行列を設計する必要があります。上記のリンクを使用して、このような設計に対する包括的なソリューションを見つけることができます。

(5)導関数が関数の定義と同じ点で評価されることは重要ですか?A:はい、絶対にあります。同じグリッドポイントでのNDの評価は「集中型」と呼ばれ、ポイントを外れた「交互配置」スキームと呼ばれます。奇数次の導関数を使用すると、集中NDは微分器の周波数応答の精度を逸脱することに注意してください。したがって、そのような設計を逆問題で使用している場合、これは近似を混乱させます。また、逆のことは、スタガードスキームで利用される微分の偶数次数の場合にも当てはまります。上記のリンクを使用して、このテーマに関する包括的な説明を見つけることができます。

(6)導関数の複数の次数を計算する必要がありますか?これは、手元のアプリケーションに完全に依存します。私が提供した同じリンクを参照して、複数の派生デザインを処理できます。

2