(ここは工事中。 前項の 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])) |