<?php /* 初期設定 */ $n = 2; $x = array($n); $dx = array($n); $g = array(4); for ($i1 = 0; $i1 < 4; $i1++) $g[$i1] = array($n); $time = 0.0; $h = 0.01; $x[0] = 0.0; $x[1] = 0.0; /* 計算と出力 */ for ($i1 = 0; $i1 < 101; $i1++) { printf("time = %f, x = %f\n", $time, $x[0]); $time = rkg($time, $h, $x, $dx, $g, $n, "snx"); } /****************/ /* 微係数の計算 */ /****************/ function snx($time, $x, &$dx) { $dx[0] = $x[1]; $dx[1] = -2.0 * $x[0] - 3.0 * $x[1] + 1.0; } /*******************************************/ /* ルンゲ・クッタ法 dx/dt=f(t,x) */ /* time : 現在の時間 */ /* h : 時間刻み幅 */ /* x : 現在の状態 */ /* dx : 微係数(f(t,x):snxで計算する)*/ /* g : 作業域(g[4][n]) */ /* n : 微分方程式の次数 */ /* sub : 微係数を計算する関数の名前 */ /* return : time+h */ /*******************************************/ function rkg($time, $h, &$x, $dx, $g, $n, $sub) { $h2 = 0.5 * $h; $sub($time, $x, $dx); for ($i1 = 0; $i1 < $n; $i1++) $g[0][$i1] = $h * $dx[$i1]; $time += $h2; for ($i1 = 0; $i1 < $n; $i1++) $g[1][$i1] = $x[$i1] + 0.5 * $g[0][$i1]; $sub($time, $g[1], $dx); for ($i1 = 0; $i1 < $n; $i1++) $g[1][$i1] = $h * $dx[$i1]; for ($i1 = 0; $i1 < $n; $i1++) $g[2][$i1] = $x[$i1] + 0.5 * $g[1][$i1]; $sub($time, $g[2], $dx); for ($i1 = 0; $i1 < $n; $i1++) $g[2][$i1] = $h * $dx[$i1]; $time += $h2; for ($i1 = 0; $i1 < $n; $i1++) $g[3][$i1] = $x[$i1] + $g[2][$i1]; $sub($time, $g[3], $dx); for ($i1 = 0; $i1 < $n; $i1++) $g[3][$i1] = $h * $dx[$i1]; for ($i1 = 0; $i1 < $n; $i1++) $x[$i1] = $x[$i1] + ($g[0][$i1] + 2.0 * $g[1][$i1] + 2.0 * $g[2][$i1] + $g[3][$i1]) / 6.0; return $time; } ?>