lectures:r201504
2階常微分方程式
共通部分
$z=y'=\frac{{\rm d}}{{\rm d}x}y$と置くのでこの部分はすべて共通。
double dydx(double x, double y, double z) { return z; }
問題によって変更する部分
$x, y, y'(=z), y''$で書かれた式を$y''=\cdots$の形に直して、その右辺の式を計算する関数をここに定義する。 例は、$y''+2y'+y=1$すなわち$y''=1-2y'-y=1-2z-y$の場合の例になっている。
double dzdx(double x, double y, double z) { double ret; ret = 1.0 - 2.0*z - y; return ret; }
また、問題や用途によって「繰り返し回数」、「初期値」、「刻み幅」は適当なものに適宜変更せよ。
int i, n = 100; /* 繰り返し回数 */ double x = 0.0, y = 0.0, z = 0.0; /* 初期値 */ double dx = 0.01; /* 刻み幅 */
オイラー法-2階版
#include <stdio.h> #include <math.h> double dydx(double x, double y, double z); double dzdx(double x, double y, double z); int main(void) { int i, n = 100; /* 繰り返し回数 */ double x = 0.0, y = 0.0, z = 0.0; /* 初期値 */ double dx = 0.01; /* 刻み幅 */ double dy, dz; printf("%f %f %f\n", x, y, z); for (i=0; i<n; i++) { dy = dydx(x, y, z)*dx; dz = dzdx(x, y, z)*dx; x = x + dx; y = y + dy; z = z + dz; printf("%f %f %f\n", x, y, z); } return 0; }
修正オイラー法-2階版
#include <stdio.h> #include <math.h> double dydx(double x, double y, double z); double dzdx(double x, double y, double z); int main(void) { int i, n = 100; /* 繰り返し回数 */ double x = 0.0, y = 0.0, z = 0.0; /* 初期値 */ double dx = 0.01; /* 刻み幅 */ double dy1, dy2, dz1, dz2; printf("%f %f %f\n", x, y, z); for (i=0; i<n; i++) { dy1 = dydx(x, y, z)*dx; dz1 = dzdx(x, y, z)*dx; dy2 = dydx(x + dx, y + dy1, z +dz1)*dx; dz2 = dzdx(x + dx, y + dy1, z +dz1)*dx; x = x + dx; y = y + (dy1 + dy2)/2.0; z = z + (dz1 + dz2)/2.0; printf("%f %f %f\n", x, y, z); } return 0; }
ルンゲ・クッタ法-2階版
#include <stdio.h> #include <math.h> double dydx(double x, double y, double z); double dzdx(double x, double y, double z); int main(void) { int i, n = 100; /* 繰り返し回数 */ double x = 0.0, y = 0.0, z = 0.0; /* 初期値 */ double dx = 0.01; /* 刻み幅 */ double dy1, dy2, dy3, dy4, dz1, dz2, dz3, dz4; printf("%f %f %f\n", x, y, z); for (i=0; i<n; i++) { dy1 = dydx(x, y, z)*dx; dz1 = dzdx(x, y, z)*dx; dy2 = dydx(x + dx/2., y + dy1/2., z +dz1/2.)*dx; dz2 = dzdx(x + dx/2., y + dy1/2., z +dz1/2.)*dx; dy3 = dydx(x + dx/2., y + dy2/2., z + dz2/2.)*dx; dz3 = dzdx(x + dx/2., y + dy2/2., z + dz2/2.)*dx; dy4 = dydx(x + dx, y + dy3, z + dz3)*dx; dz4 = dzdx(x + dx, y + dy3, z + dz3)*dx; x = x + dx; y = y + (dy1 + 2.0*(dy2 + dy3) + dy4)/6.0; z = z + (dz1 + 2.0*(dz2 + dz3) + dz4)/6.0; printf("%f %f %f\n", x, y, z); } return 0; }
lectures/r201504.txt · 最終更新: 2022/08/23 13:34 by 127.0.0.1