#*********************************/
# 微分方程式(ルンゲ・クッタ法) */
# 例:d2x/dt+3dx/dt+2x=1 */
# coded by Y.Suganuma */
#*********************************/
#***************/
# 微係数の計算 */
#***************/
snx = Proc.new { |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 : 微分方程式の次数 */
# snx : 微係数を計算する関数の名前 */
# return : time+h */
#******************************************/
def rkg(time, h, x, dx, g, n, &sub)
h2 = 0.5 * h
sub.call(time, x, dx)
for i1 in 0 ... n
g[0][i1] = h * dx[i1]
end
time += h2
for i1 in 0 ... n
g[1][i1] = x[i1] + 0.5 * g[0][i1]
end
sub.call(time, g[1], dx)
for i1 in 0 ... n
g[1][i1] = h * dx[i1]
end
for i1 in 0 ... n
g[2][i1] = x[i1] + 0.5 * g[1][i1]
end
sub.call(time, g[2], dx)
for i1 in 0 ... n
g[2][i1] = h * dx[i1]
end
time += h2
for i1 in 0 ... n
g[3][i1] = x[i1] + g[2][i1]
end
sub.call(time, g[3], dx)
for i1 in 0 ... n
g[3][i1] = h * dx[i1]
end
for i1 in 0 ... n
x[i1] = x[i1] + (g[0][i1] + 2.0 * g[1][i1] + 2.0 * g[2][i1] + g[3][i1]) / 6.0
end
return time
end
# 初期設定
n = 2
x = Array.new(n)
dx = Array.new(n)
g = Array.new(4)
for i1 in 0 ... 4
g[i1] = Array.new(n)
end
time = 0.0
h = 0.01
x[0] = 0.0
x[1] = 0.0
# 計算と出力
for i1 in 0 ... 101
printf("time = %f, x = %f\n", time, x[0])
time = rkg(time, h, x, dx, g, n, &snx)
end