導関数の指定
関数FindRootはオプション
を,関数FindMinimum,FindMaximum,FindFitはオプションGradientを,ニュートン法はメソッドオプションの
を持つ.これらの導関数はすべて同一の基本的な構造で指定される.次は導関数の計算方法の指定の方法をまとめたものである.
| Automatic | 関数の記号的導関数を求める.記号的導関数が求まらない場合は有限差分近似を用いる |
| Symbolic | Automaticと同じ.ただし,有限差分を用いる際には警告メッセージを出す |
| FiniteDifference | 導関数の近似に有限差分を用いる |
| expression | 変数の局所的数値で与えられた expression を使い,導関数を評価する |
gradient,Jacobian,Hessian導関数の計算方法
導関数の基本的な指定とは,その計算方法である.しかし,導関数はすべてオプションも取る.オプションはリスト
を使って指定できる.次は導関数のオプションのまとめである.
gradient,Jacobian,Hessian導関数を計算する際のオプション
次はこれらがどのように使われるかの例である.
いくつかのユーティリティ関数を含むパッケージをロードする.
以下で,変数の数値についてのみ評価することのみを意図する関数を定義する.
Method->"Newton"とするだけで,FindMinimumはlstolメッセージを出す.それは,導関数についての十分な情報がないために最小値を解くことができなかったからである.
次は,
FindMinimumが勾配とヘッセを計算するために有限差分を使わなければならない場合に取るステップを示したものである.
次のように導関数を指定する勾配オプションを使うことができる.
勾配の記号式を使って

の最小値を計算する.
| Out[4]= |  |
記号的な導関数が常に得られる訳ではない.有限差分からの確度がさらに必要であれば,関数の評価回数を多くするという犠牲を払うことで,差分の精度次数をデフォルトの1よりも大きくすることができる.
勾配の計算に二次精度の有限差分を使って

の最小値を計算する.
| Out[5]= |  |
ヘッセ行列を近似するために使われる勾配の計算には関数の評価が使われるので,関数の評価回数ははるかに多くなる.(与えられた情報からはこのための記号式は得られないので,ヘッセ行列は有限差分で計算される.)
から与えられる関数,勾配,ヘッセ行列の評価回数についての情報は極めて役に立つ.EvaluationMonitorオプションにより,これが可能になっている.次はそれぞれのタイプの評価の回数を単純に数えるだけの簡単な例である.(評価が行われたときの値を集めるために,プロットはReapとSowを使って作成される.)
次はカウンタでステップ数と関数の数,勾配,ヘッセ行列の評価回数の記録を取りながら最小値を計算する.
| Out[6]= |  |
このような方法は,同様の特徴を持つ問題のクラスでどのようなメソッドおよび/またはメソッドのパラメータを使うと最も成功しやすいかを見極めるのに大変役に立つ.
Mathematica が関数の記号的な構造にアクセスできるときは,必要に応じて自動的に関数およびその導関数の構造分析を行い,SparseArrayオブジェクトを使って導関数を表す.それに続く数値線形代数で疎な構造が使えるので,これは全体的な探索効率に大きく影響する.Mathematica に構造分析ができないときは,一般に構造は密であると仮定される.しかし,導関数の疎な構造がどのようなものか分かっていれば,
メソッドオプションでこれを指定し,導関数の計算(有限差分を使うと,評価回数が大幅に減少できる)とそれに続く線形代数の両方で効率を大幅に上げることができる.これはベクトル値変数を扱うときには特に重要である.この側面をうまく表しているのが,非常に疎な構造を持つ拡張Rosenbrock関数の問題である
次は

パッケージを使って
FindRootで解ける,1000の変数を持った拡張Rosenbrock関数を記号形式で取り出す.
Out[7]//Short= |
| |  |
| Out[8]= |  |
このように単純な形式の関数では,関数のベクトル形式を書くのは簡単である.べクトル形式では,たとえ自動コンパイルを使っても,記号形式のときよりも関数の評価が格段に速くなる.
拡張Rosenbrock関数のベクトル形式を定義する.これは評価効率が大変よい.
Out[10]//Short= |
| |  |
評価にベクトル変数とベクトル関数を使って問題を解く.
| Out[11]= |  |
この関数の解は,評価は速いが,全体としてはより遅くなる.
パターンのためにヤコビ行列が記号分析に対して不透明なので,ヤコビ行列を有限差分で計算しなければならないからである.これは有限差分が遅いというよりも,ヤコビ行列のすべての列を得るために関数を100回評価しなければならないからである.構造が分かっていれば,ヤコビ行列を得るための評価が2回にできる.この関数ではヤコビ行列の構造は極めて単純である.
| Out[12]= |  |
以下で実際のヤコビ行列の構造を知った上で問題を解く.コストが目覚ましく改善されているのが分かる.
| Out[13]= |  |
疎な構造が与えられると,評価して疎な構造のテンプレートで指定される位置に対応する値になるような記号式で値を計算することも可能である.値は,SparseArrayで定められている位置に直接対応しなければならない(この順序はArrayRulesを使って見ることができる).指標の矛盾しない順序を知る方法のひとつに,行列を2度転置するというものがある.こうするとSparseArrayの指標が辞書順で並べられる.
以下で非零構造の行列を2度転置して指標を並べ替える.
| Out[14]= |  |
次は非零構造の行列における指標位置に対応するヤコビ行列における非零要素を返す関数を定義する.
| Out[16]= |  |
この場合,疎なヤコビ行列を使ってもそれほど速くなる訳ではない.これは,ヤコビ行列があまりに疎なために,ヤコビ行列の有限差分近似が2度の関数評価でしか求められないためと,問題が最小値付近で非常にうまく定義されているので,ヤコビ行列での追加の確度がさほどの差を生まないためである.