Chapter 2
高次の差分法 (Runge-kutta 法)
2.1 Toyler 法
一般に

という形に近似して計算する方法を差分法といいます。もっともシンプルな形はオイラー法ですがこれをもっと精度のよい 近似にするには

と Toyler (テイラー)展開したものを使えばいいのです。これを Toyler 法といいます。たとえば2次までとる と

です。ここで

から

というふうに次々にyのn回微分が求まるので基本的に何次でも計算できます。ただ、実はこのテイラー法はあまり使われ
ません。何でかというとが簡単なときはいいですが複雑な場合計算がすごく面倒になります。そしてもうひとつ
は、そんな面倒な計算をしないで済む方法が別にあるからです。
2.2 Runge-kutta 法
さて、上で言った別の方法というのがこの Runge-kutta (ルンゲ - クッタ)法です。この方法の目的はの微分を
使わずに次数を上げることです。そのためにちょっと数式をいじりますががんばってついてきてください。これから2次の
Runge-kutta (ルンゲ - クッタ)法を導きますが以下


だとすると

と差分法にするにあたって

という適当なの足し合わせにしてやります。なぜこの形かと言えばこうするとうまくいくからなんです(笑)さ
て, まず
を展開します

これを元の式にいれ
![yn+1 = yn + hF(xn,yn,h)
[ ( )]
= yn + h αf(xn,yn)+ β f(xn,yn)+ ph∂f-(xn,yn) + qhf (xn,yn)∂f-(xn,yn) + O(h2)
∂x ∂y
= y + h(α+ β)f(x ,y )+ h2(βp∂f(xn,yn)+ βqf(x ,y )∂f(xn,yn))+ O (h3)
n n n ∂x n n ∂y](prog38x.png)

![2 2
yn+1 = yn + hdyn + h dyn-+ O (h3)
dx 22! dx2
= yn + h-df-+ h [∂f-+ f∂f-]+ O(h3)
dx 2!∂x ∂y](prog40x.png)

よって

ここでは任意です。そのため同じ2次のルンゲ - クッタでもいくつか存在します。ふつう
で
す。
具体的に書くと、の場合
![1
yn+1 = yn +-h [f(xn,yn)+ f(xn + h,yn + hf(xn,yn))]
2](prog46x.png)
なので実際の計算手順は


#include <stdio.h>
#include <math.h> int main(void){ double x[3] ={1,0,0}; double u[3] ={0}; double y[3] ={0}; double v[3] ={1,0,0}; int k; for(k=1;k <= 100; k++){ u[1] =u[0]+ -0.2 * x[0] / sqrt(y[0]*y[0]+x[0]*x[0]); x[1] =x[0]+ 0.2 * u[0]; v[1] =v[0]+ -0.2 * y[0] / sqrt(y[0]*y[0]+x[0]*x[0]); y[1] =y[0]+ 0.2 * v[0]; u[2] =u[0]+ -0.2 * x[1] / sqrt(y[1]*y[1]+x[1]*x[1]); x[2] =x[0]+ 0.2 * u[1]; v[2] =v[0]+ -0.2 * y[1] / sqrt(y[1]*y[1]+x[1]*x[1]); y[2] =y[0]+ 0.2 * v[1]; u[0] =(u[1]+u[2])/2; x[0] =(x[1]+x[2])/2; v[0] =(v[1]+v[2])/2; y[0] =(y[1]+y[2])/2; if(k%2==0) printf("%f %f\n",x[0],y[0]); } return 0; } |
その結果はこちら
結果は明らかですね。オイラー法に比べるとメッシュの幅が一緒なのにこれほど違うんです。実際の物理でも RK 法は よく使われています。