概要

常微分方程式

\[\cfrac{dx(t)}{dt} = f(x, t)\]

を解く手法の一つ。

(前進)オイラー法

手順

  • 刻み幅 $\Delta t$
  • 初期値 $x(t_0) = x_0$

として、漸化式

\[\begin{eqnarray} x(t_{n+1}) &=& x(t_n) + f(x_n, t_n) \Delta t \\ \\ t_{n+1} &=& t_n + \Delta t \end{eqnarray}\]

により更新していく。

誤差

初期値 $x(t_0)$ から漸化式により数値的に求めた解 $x(t_n)$ は、

\[\begin{eqnarray} x(t_n) &=& x(t_{n-1}) + f(x(t_{n-1}), t_{n-1}) \Delta t \\ &=& x(t_{n-2}) + f(x(t_{n-2}), t_{n-2}) \Delta t + f(x(t_{n-1}), t_{n-1}) \Delta t \\ &=& \cdots \\ &=& x(t_0) + \sum_{i=0}^{n-1} f(x(t_i), t_i) \Delta t \end{eqnarray}\]

また、解析的に求めた解 $x(t_n)$ は、

\[\begin{eqnarray} x(t_n) &=& x(t_0) + \int_{t_0}^{t_n} \cfrac{dx(t)}{dt} dt \\ &=& x(t_0) + \int_{t_0}^{t_n} f(x(t), t) dt \end{eqnarray}\]

よって数値解と解析解の誤差は、

\[x_\mathrm{error}(t_n) = \sum_{i=0}^{n-1} f(x(t_i), t_i) \Delta t - \int_{t_0}^{t_n} f(x(t), t) dt\]

$\Delta t \to 0$ の極限を取れば、右辺第一項は和の極限による定積分の定義そのものであり、

\[\lim_{\Delta t \to 0} \sum_{i=0}^{n-1} f(x(t_i), t_i) \Delta t = \int_{t_0}^{t_n} f(x(t), t) dt\]

したがって、

\[\lim_{\Delta t \to 0} x_\mathrm{error}(t_n) = 0\]

すなわち、$\Delta t$ を小さく取れば取るほど解析解と数値解の誤差は小さくなる。

具体例

例1

\[\cfrac{dx(t)}{dt} = 2t-1,\qquad x(0) = 0\]

解析解

微分方程式を解くと、積分定数を $C$ として

\[x(t) = t^2-t + C\]

初期値 $x(0) = 0$ より $C=0$ となるので、

\[x(t) = t^2-t\]

数値解

漸化式は

\[x(t_{n+1}) = x(t_n) + (2t_n-1) \Delta t\]
def x_poly(t):
    return t**2 - t

def dxdt_poly(t, x):
    return 2*t-1

x0 = 0
t1, t2 = 0, 1.0
draw_euler_result(x_poly, dxdt_poly, x0, t1, t2)

euler-method

euler-method-error

例2

\[\cfrac{dx(t)}{dt} = 3t^2-6t+2,\qquad x(0) = -1\]

解析解

微分方程式を解くと、積分定数を $C$ として

\[x(t) = t^3 - 3t^2 + 2t + C\]

初期値 $x(0) = -1$ より $C=-1$ となるので、

\[x(t) = t^3 - 3t^2 + 2t - 1\]

数値解

漸化式は

\[x(t_{n+1}) = x(t_n) + (3t_n^2 - 6t_n + 2) \Delta t\]
def x_poly2(t):
    return t**3 - 3*t**2 + 2*t - 1

def dxdt_poly2(t, x):
    return 3*t**2 - 6*t + 2

x0 = - 1
t1, t2 = 0, 2.5
draw_euler_result(x_poly2, dxdt_poly2, x0, t1, t2)

euler-method_3

euler-method-error_3

例3

\[\cfrac{dx(t)}{dt} = \sin t,\qquad x(0) = 0\]

解析解

微分方程式を解くと、積分定数を $C$ として

\[x(t) = - \cos t + C\]

初期値 $x(0) = 0$ より $C=1$ となるので、

\[x(t) = - \cos t + 1\]

数値解

漸化式は

\[x(t_{n+1}) = x(t_n) + \cos t_n \cdot \Delta t\]
def x_trig(t):
    return - np.cos(t) + 1

def dxdt_trig(t, x):
    return np.sin(t)

x0 = 0
t1, t2 = 0, np.pi*10
draw_euler_result(x_trig, dxdt_trig, x0, t1, t2)

euler-method_2

euler-method-error_2