![]() |
(9) |
オイラー法での数値計算では、計算の刻み幅は十分に小さいとして、
![]() |
(10) |
オイラー法では、次の漸化式に従い数値計算を進める。解である
が同じ手続きで計算できる。
実際にプログラムを行うときは、forやwhileを用いて繰り
返し計算を行い、結果の
と
は、配列x[i] や
y[i]に格納するのが常套手段である。
![]() |
この方法の計算のイメージは、図1の通りである。明らか に、出発点の導関数のみ利用しているために精度が悪いことが理解できる。式 も対称でないため、逆から計算すると元に戻らない。
先に示したように、オイラー法の精度は1次であるが、2次のルンゲ・
クッタ法では2次となる。今まで刻み幅をと記述していたが、簡単のため
と
表現する。
2次の精度ということは、テイラー展開より
![]() |
(12) |
式(13)から分かるように、の増分
を計算する
ためには、1階微分と2階微分の2項を満たす式が必要である。そうすると少なく
とも、2点の値が必要となる。2点として、計算区間の両端の導関数の値を
使う。この導関数は問題として与えられているので、計算は簡単である。そ
うして、区間の増分を
をパラメーターとした和で表すことに
する。即ち、以下の通りである。
![]() |
(15) |
![]() |
ということで、皆さんが常微分方程式を計算する必要が生じたときは、何はと もあれ4次のルンゲ・クッタで計算すべきである。普通の科学に携わる人にとっ て、4次のルンゲ・クッタは常微分方程式の最初で最後の解法である。
4次のルンゲ・クッタの公式は、式(18)に示す通りである。そし て、これは図3のように表すことができる。
#include <stdio.h> #include <math.h> #define IMAX 100001 double func(double x, double y); /*================================================================*/ /* main function */ /*================================================================*/ int main(void){ double x[IMAX], y[IMAX]; double final_x, h; double k1, k2, k3, k4; int ncal, i; /*--- set initial condition and cal range ---*/ x[0]=0.0; y[0]=0.0; final_x=10.0; ncal=10000; /* --- size of calculation step --- */ h=(final_x-x[0])/ncal; /* --- 4th Runge Kutta Calculation --- */ for(i=0; i < ncal; i++){ k1=h*func(x[i],y[i]); k2=h*func(x[i]+h/2.0, y[i]+k1/2.0); k3=h*func(x[i]+h/2.0, y[i]+k2/2.0); k4=h*func(x[i]+h, y[i]+k3); x[i+1]=x[i]+h; y[i+1]=y[i]+1.0/6.0*(k1+2.0*k2+2.0*k3+k4); } return 0; } /*================================================================*/ /* define function */ /*================================================================*/ double func(double x, double y){ double dydx; dydx=sin(x)*cos(x)-y*cos(x); return(dydx); }
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
||
![]() |
![]() |
![]() |
![]() |
|||||
![]() |
![]() |
![]() |
![]() |
|||||
![]() |
![]() |
![]() |
![]() |