たとえば、大きなヤコビ行列を扱う場合、数値コードの複雑さをどのように扱うのですか?


10

連立方程式の非線形システムを解いていて、離散化システムのヤコビアンを計算しました。結果は本当に複雑です。以下は(のみ!)行列の最初の 3列です。×9

部分ヤコビ行列

(一部には、数値スキームが安定性のために指数関数近似を必要とするため、複雑さが生じます。)

ヤコビアンを使用した数値コードの実装について、かなり一般的な質問があります。

先に進んで、このマトリックスをコードに実装できます。しかし、私の直感は、非常に複雑であり、エラーを導入せざるを得ないため、数日(場合によっては数週間!)の面倒なデバッグを期待するように言っています。数値コードでこのような複雑さに対処するにはどうすればよいのでしょうか?シンボリックパッケージから自動コード生成を使用しますか(その後、コードを手動で微調整します)?

最初に、有限差分近似を使用して分析ヤコビアンをデバッグする予定ですが、落とし穴に注意する必要がありますか?コード内の同様の問題にどのように対処しますか?

更新

私はこれをPythonでコーディングし、sympyを使用してヤコビアンを生成しました。たぶん、コード生成機能を使用できますか?


ヤコビ式を生成するためにどのコンピューター代数システムを使用していますか?Mapleを使用している場合は、codegenその中にあるパッケージを確認することをお勧めします。これにより、式のそれぞれまたはすべてに対してコンパクトで効率的なCまたはFortranコードが自動的に生成されます。
ペドロ

ここには非常に多くの有用な回答があります。1つを選択しても意味がありません。これをコミュニティWikiの投稿にする必要がありますか?
boyfarrell 2013

回答:


6

一言:モジュール性

ヤコビアンには、独自の関数として記述できる反復表現がたくさんあります。同じ操作を複数回記述する理由はありません。これにより、デバッグが容易になります。一度だけ書いた場合、エラーの場所は1つしかありません(理論上)。

モジュラーコードを使用すると、テストも簡単になります。行列全体をテストするのではなく、ヤコビアンの各コンポーネントのテストを作成できます。たとえば、関数am()をモジュラー方式で記述した場合、その関数の健全性テストを簡単に記述したり、正しく区別しているかどうかを確認したりできます。

もう1つの提案は、ヤコビ行列を組み立てるための自動微分ライブラリを調べることです。エラーがないことを保証するものではありませんが、独自のものを書くよりデバッグ/エラーが少ないでしょう。あなたがそれを見たいと思うかもしれないいくつかはここにあります:

  • Sacado(Sandia Labs)
  • ADIC(アルゴンヌ)

申し訳ありませんが、Pythonを使用していることがわかりました。ScientificPythonはADをサポートしています。


いいアドバイス。多くの場合、中間式は独自の関数を持つ必要はありません。それらを中間変数に格納するだけです。
David Ketcheson 2013

5

ここでは、ストーリーを前に、いくつかの注意点を説明します。ずっと前、私はちょうど始めたばかりの時に仲間と一緒に働きました。彼はやや厄介な目的で、解決すべき最適化問題を抱えていました。彼の解決策は、最適化のための分析的導関数を生成することでした。

私が見た問題は、これらの派生物が厄介であるということでした。Macsymaを使用して生成され、fortranコードに変換されたものは、それぞれ数十の継続ステートメントでした。実際、継続ステートメントの最大数を超えたため、Fortranコンパイラーはそのことに腹を立てました。その問題を回避できるフラグを見つけましたが、他にも問題がありました。

  • CAシステムで一般的に生成される長い式では、大幅な減算キャンセルのリスクがあります。多数の大きな数値を計算します。それらすべてが互いに打ち消し合って小さな数値が得られることを見つけるだけです。

  • 多くの場合、分析的に生成された導関数は、有限差分を使用して数値的に生成された導関数よりも実際に評価にコストがかかります。n個の変数の勾配には、目的関数を評価するコストのn倍以上かかる場合があります。(多くの用語はさまざまな派生語で再利用できるため、時間を節約できる可能性がありますが、コンピューター生成の式を使用する代わりに、慎重に手動でコーディングする必要があります。また、厄介な数学をコーディングするときはいつでも式では、エラーの確率は簡単ではありません。これらの導関数が正確であることを確認してください。)

私の話の要点は、これらのCA生成式には独自の問題があるということです。面白いことに、私の同僚は問題の複雑さを実際に誇りに思っていました。代数が非常に厄介だったので、彼は本当に難しい問題を明らかに解決していたのです。彼が考えていなかったのは、その代数が実際に正しいことを計算しているかどうか、正確に計算しているかどうか、そして効率的に実行しているかどうかでした。

このプロジェクトの当時私が上級者だったとしたら、暴動行為を彼に読んだことでしょう。彼のプライドにより、有限差分ベースの勾配が適切であるかどうかさえチェックせずに、おそらく不必要に複雑なソリューションを使用するようになりました。この最適化を実行するために、おそらく1週間の時間を費やしたに違いない。少なくとも、生成された勾配を注意深くテストするように彼に助言したでしょう。正確でしたか?差分微分と比較して、どれほど正確でしたか?実際、今日のツールには、微分予測の誤差の推定値を返すツールもあります。これは、MATLABで記述した(微分)適応微分コードにも当てはまります。

コードをテストします。派生物を検証します。

ただし、これを行う前に、他のより優れた最適化スキームがオプションであるかどうかを検討してください。たとえば、指数フィッティングを行っている場合、分割された非線形最小二乗法(分離可能な最小二乗法と呼ばれることもあります。これはSeber and Wildが本で使用した用語だと思います。)パラメータのセットを本質的に線形のセットと本質的に非線形のセットに分割することです。非線形パラメーターでのみ機能する最適化を使用します。これらのパラメータが「既知」である場合、本質的に線形のパラメータは、単純な線形最小二乗法を使用して推定できます。このスキームは、最適化のパラメータースペースを削減します。線形パラメーターの開始値を見つける必要がないため、問題がより堅牢になります。これにより、検索スペースの次元が減少するため、問題がより迅速に実行されます。もう一度私は供給しましたこの目的のためのツールですが、MATLABのみです。

分析的導関数を使用する場合は、それらをコード化して用語を再利用します。これは重大な時間の節約になる可能性があり、実際にバグを減らして、自分の時間を節約する可能性があります。しかし、それらの数をチェックしてください!


5

考慮すべきいくつかの戦略があります。

  1. CASを使用してシンボリック形式の導関数を見つけ、導関数を計算するためのコードをエクスポートします。

  2. 自動微分(AD)ツールを使用して、関数を計算するコードからの導関数を計算するコードを生成します。

  3. 有限差分近似を使用してヤコビアンを近似します。

自動微分は、ヤコビアン全体を計算するためのより効率的なコードを生成し、記号計算を使用して行列の各エントリの式を生成することができます。有限差分は、導関数を再確認するための良い方法です。



1

BrianBorcherの優れた提案に加えて、実数値関数のもう1つの可能なアプローチは、複素数ステップ微分近似を使用することです(この記事(ペイウォール)およびこの記事を参照)。場合によっては、このアプローチにより、関数の変数の値を実数から複素数に変更する代わりに、より正確な数値導関数が得られます。2番目の記事では、複雑なステップ関数の近似が壊れる可能性があるいくつかのケースをリストしています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.