🚗

自動微分

2024/03/25に公開

https://github.com/gen740/Autodiff

自動微分

自動微分とは数値微分のことではなく、ライプニッツ則やテイラー展開などの解析的な手法を用いて自動的に微分を導き出す方法のことである。

はじめに

  • 以下では (x(t),y(t))(x,y)と省略表記する
  • 微分は以下のような表記ができる。
  • f(x)の一つの変数に従う微分
\begin{align*} f(x, y) &= u_0(x) \\ \dot{f}(x, y) &= u_1(x, \dot{x}) \\ \ddot{f}(x, y) &= u_2(x, \dot{x}, \ddot{x}) \\ \vdots \\ \frac{\partial^n f(x, y)}{\partial t^n} &= u_n(x, \dot{x}, \ddot{x}, \cdots \frac{\partial^n x}{\partial t^n}) \end{align*}
  • f(x, y)のような二つの変数に従う微分
\begin{align*} f(x, y) &= u_0(x, y) \\ \dot{f}(x, y) &= u_1(x, \dot{x}, y, \dot{y}) \\ \ddot{f}(x, y) &= u_2(x, \dot{x}, \ddot{x}, y, \dot{y}, \ddot{y}) \\ \vdots \\ \frac{\partial^n f(x,y)}{\partial t^n} &= u_n(x, \dot{x}, \ddot{x}, \cdots \frac{\partial^n x}{\partial t^n}, y, \dot{y}, \ddot{y}, \cdots \frac{\partial^n y}{\partial t^n}) \end{align*}
  • n回微分の関数は変数のn回微分までで表すことができる。
  • 自動微分ではここのu_0 \sim ~u_nの関係式を導出し、実装することで実現される

単項演算子

  • f(x)で表されるような単項演算を行うもの
  • 例えば簡単な関数である \exp(x) を考える
\begin{align} \exp(x) &= \exp(x) \\ \frac{\partial \exp(x)}{\partial t} &= \dot{x} \exp(x) \\ \frac{\partial^2 \exp(x)}{\partial t^2} &= \ddot{x}\exp(x) + \dot{x}^2\exp(x) \\ \frac{\partial^3 \exp(x)}{\partial t^3} &= \frac{\partial^3 x}{\partial t^3}\exp(x) + \ddot{x}\dot{x}\exp(x) + 2\dot{x}\exp(x) + \dot{x}^3\exp(x) \end{align}
  • これから法則を導き出すのは少し骨が折れるが、一個前の微分に注目をするという視点に気づけば
\frac{\partial^n \exp(x)}{\partial t^n} = \sum^{n-1}_{i=0}C^{n-1}_i \frac{\partial^{n-i} x}{\partial t^{n-i}} \frac{\partial^{i} \exp(x)}{\partial t^{i}} ~~ ~~~\text{if} ~~~ (n\ge1)
  • と定式化できることに気づくであろう
  • これと同じような定式化は、 \sin,\cos,\tan,f^{-1}(x)などの単項演算子で定義できる

二項演算子

  • 例えば簡単なライプニッツ則を思い出すと
\begin{align} xy &= xy \\ \frac{\partial (xy)}{\partial t} &= \dot{x}y + x\dot{y} \\ \frac{\partial^2(xy)}{\partial t^2} &= \ddot{x}y + 2\dot{x}\dot{y} +\ddot{y} \end{align}
  • のような関係式を思い浮かべることができ簡単な考察からこれらの係数が Combination であることに気づくことができる。
\frac{\partial^n (xy)}{\partial t^n} = \sum^n_{i=0} C^n_i \frac{\partial^i x}{\partial t^i} \frac{\partial^{(n-i)} y}{\partial t^{(n-i)}}
  • これらは -,+,\div,\timesの二項演算においても同様な法則を見つけ出せる。

実装

さてここまでお膳立てをすれば、実装は実に単純である。実装する順序としては。

  • 値とn回微分までを記録した n+1 個のベクトルを持つ
  • それぞれの演算子をオーバーロードして、上で求めたような規則に従って計算を行う

そうすれば、任意の初等関数からなる関数を、変数の微分の値の演算によって求めることができる。

GitHubで編集を提案

Discussion