(ここは工事中。 前項の Julia 言語によるプログラムと同じことをするプログラムを実現する。)
| rk1ex1.py |
# rk1ex1.py --- dx/dt=x (0<t<1), x(0)=1 をRunge-Kutta法で解く
# JuliaプログラムのPythonバージョン
# rk1ex1.jl(http://nalab.mind.meiji.ac.jp/~mk/labo/text/intro-ode-simulation/node25.html)
# Runge-Kutta法であるが、応用が効きにくい形。参考プログラム。
# シェルから起動したときコマンド・ライン引数を見るあたりは、参考になるかも。
import sys
def testrungekutta(Tmax=1.0, N=10):
t0=0.0
x0=1.0
print('#N=%d Tmax=%f' % (N,Tmax))
print('# t x')
#Runge-Kutta法
dt=(Tmax-t0)/N
t=t0
x=x0
for j in range(N):
k1=dt*f(t,x)
k2=dt*f(t+dt/2,x+k1/2)
k3=dt*f(t+dt/2,x+k2/2)
k4=dt*f(t+dt,x+k3)
x += (k1+2*k2+2*k3+k4) / 6.0
t = t0 + (j+1) * dt
print('%.4f %.7f' % (t, x))
def f(t,x):
return x
if __name__ == "__main__":
argc = len(sys.argv)
if argc == 1:
testrungekutta()
elif argc == 2:
testrungekutta(float(sys.argv[1]))
elif argc == 3:
testrungekutta(float(sys.argv[1]), int(sys.argv[2]))
|
| 実行の仕方 |
% python rk1ex1.py
#N=10 Tmax=1.000000 # t x 0.1000 1.1051708 0.2000 1.2214026 0.3000 1.3498585 0.4000 1.4918242 0.5000 1.6487206 0.6000 1.8221180 0.7000 2.0137516 0.8000 2.2255396 0.9000 2.4596014 1.0000 2.7182797 % |
次は van der Pol 方程式の問題のJuliaによるプログラムである。 Tmax, N を実行時に入力できるような工夫を入れてみた。 また計算結果を rk2ex1.data というファイルに出力している。
| rk2ex1.py |
# rk2ex1.py --- Runge-Kutta method for van der Pol equation
# JuliaプログラムのPythonバージョン
# rk2ex1.jl(http://nalab.mind.meiji.ac.jp/~mk/labo/text/intro-ode-simulation/node25.html)
# お勧めという訳でもないが、それなりに応用が効く。
import sys
import numpy as np
def rungekutta(f,t,x,dt,args=()):
k1=dt*f(t,x,args=args)
k2=dt*f(t+dt/2, x+k1/2,args=args)
k3=dt*f(t+dt/2, x+k2/2,args=args)
k4=dt*f(t+dt, x+k3,args=args)
return x + (k1 + 2 * k2 + 2 * k3 + k4) / 6
# van der Pol方程式
def f(t, x, args=(1.0,)):
# return np.array([x[1],-x[0]+mu*(1.0-x[0]*x[0])*x[1]])
mu=args[0]
y=np.empty(np.size(x))
y[0]=x[1]
y[1]=-x[0]+mu*(1.0-x[0]*x[0])*x[1]
return y
def testrungekutta(Tmax=50.0, N=1000):
mu=1.0
t0=0.0
x0=np.array([0.1,0.1])
print('#N=%d Tmax=%f' % (N,Tmax))
print('# t x')
#Runge-Kutta法
dt=(Tmax-t0)/N
t=t0
x=x0
with open('rk2ex1.data', mode='w') as fout:
print('%f %f %f' % (t, x[0], x[1]))
print('%f %f %f' % (t, x[0], x[1]), file=fout)
for j in range(N):
x=rungekutta(f,t,x,dt,args=(mu,))
t = t0 + (j+1) * dt
print('%f %f %f' % (t, x[0], x[1]))
print('%f %f %f' % (t, x[0], x[1]), file=fout)
if __name__ == "__main__":
argc = len(sys.argv)
if argc == 1:
testrungekutta()
elif argc == 2:
testrungekutta(float(sys.argv[1]))
elif argc == 3:
testrungekutta(float(sys.argv[1]), int(sys.argv[2]))
|
| 実行の仕方 |
|
% python rk2ex1.py
% gnuplot gnuplot> plot "rk2ex1.data" using 2:3 with l gnuplot> quit
% python rk2ex1.jl 100 2000
|
gnuplot を使わず、解軌道を直接描くのも簡単である。
| rk2ex1plot.py |
# rk2ex1.py --- Runge-Kutta method for van der Pol equation
# JuliaプログラムのPythonバージョン
# rk2ex1.jl(http://nalab.mind.meiji.ac.jp/~mk/labo/text/intro-ode-simulation/node25.html)
# お勧めという訳でもないが、それなりに応用が効く。
import sys
import numpy as np
import matplotlib.pyplot as plt
def rungekutta(f,t,x,dt,args=()):
k1=dt*f(t,x,args=args)
k2=dt*f(t+dt/2, x+k1/2,args=args)
k3=dt*f(t+dt/2, x+k2/2,args=args)
k4=dt*f(t+dt, x+k3,args=args)
return x + (k1 + 2 * k2 + 2 * k3 + k4) / 6
# van der Pol方程式
def f(t, x, args=(1.0,)):
# return np.array([x[1],-x[0]+mu*(1.0-x[0]*x[0])*x[1]])
mu=args[0]
y=np.empty(np.size(x))
y[0]=x[1]
y[1]=-x[0]+mu*(1.0-x[0]*x[0])*x[1]
return y
def testrungekutta(Tmax=50.0, N=1000):
mu=1.0
t0=0.0
x0=np.array([0.1,0.1])
print('#N=%d Tmax=%f' % (N,Tmax))
print('# t x')
#Runge-Kutta法
dt=(Tmax-t0)/N
t=np.linspace(t0,Tmax,N+1)
x=np.empty((N+1,2))
x[0]=x0
print('%f %f %f' % (t[0], x[0,0], x[0,1]))
for j in range(N):
x[j+1]=rungekutta(f,t,x[j],dt,args=(mu,))
print('%f %f %f' % (t[j+1], x[j+1,0], x[j+1,1]))
plt.plot(x[:,0],x[:,1])
plt.show()
if __name__ == "__main__":
argc = len(sys.argv)
if argc == 1:
testrungekutta()
elif argc == 2:
testrungekutta(float(sys.argv[1]))
elif argc == 3:
testrungekutta(float(sys.argv[1]), int(sys.argv[2]))
|