自動微分(1) — 1変数の場合

前回の記事が適当すぎたので仕切り直しを。

「値と微分係数を同時に計算する型」AutoDiff型は,R×Rに適当な演算を入れたものと考えられる。微分を考える変数を x,微分を計算したい点を t とするとき,第一成分を「x=t における値」,第二成分を「x=t における微分係数」と考える。AutoDiff型の値を y=(y0,y1) とすると,y はある関数 f について y=(f(t),f(t)) となっている。h(x)=g(f(x)) という関数があったとき,すでに得られている f(t),f(t) の値を使って h(t),h(t) を計算したいとする。合成関数の微分はh(x)=g(f(x))f(x)で与えられるので、ここに x=t を代入すればh(t)=g(f(t))f(t)=g(y0)y1となる。h(t) はもちろん h(t)=g(y0) で与えられる。

今度は k(x)=g(l(x)) という関数を考えてみよう。x=t における l の値と l の値はすでに計算されているとして、これを z=(z0,z1)=(l(t),l(t)) とおく。このとき,先ほどと同じように k(t)=g(z0)k(t)=g(z0)z1 がわかる。

このようにして,g という関数は、AutoDiff型からAutoDiff型への関数を定める。この関数を g とすると,AutoDiff型の値 (y0,y1) を与えた時の g の値はg(y0,y1)=(g(y0),g(y0)y1)となる。AutoDiff型が「これまで計算した関数の値と微分係数」を表す型だとすれば,g という関数は「これまで計算した関数に g という関数を合成した時の、関数の値と微分係数」を表す型である。

上の説明では gg を区別して書いたが、実際のプログラミングでは関数や演算子のオーバーロード、あるいは型クラスを使って、g に相当する関数も同じ演算子・関数名で書けるようにするのが普通である。

いくつかの演算について、AutoDiff型を R×R とみなしたときの計算方法を与えておく。(x0,x1)±(y0,y1)=(x0±y0,x1±y1)(x0,x1)(y0,y1)=(x0y0,x1y0+x0y1)(x0,x1)/(y0,y1)=(x0/y0,(x1y0x0y1)/y20),g:RR(微分可能) に対し、g((x0,x1))=(g(x0),g(x0)x1),g:R×RR(微分可能) に対し、g((x0,x1),(y0,y1))=(g(x0,y0),gx(x0,y0)x1+gy(x0,y0)y1),となる。

文章書くのだるい。気が向いたら続く。

Spread the love