単振動の方程式の初期値問題
![]() |
![]() |
(B.6) |
これは2次元の微分方程式である点が、Malthusモデルとは違っていて、 計算の仕方、可視化の仕方に少し違いがある。それを実例で示そう。
このやり方を応用して、Lotka-Volterra 方程式を解くことも出来る。
| shm1.py -- scipy.integrate odeint() で解く |
# shm1.py --- simple harmonic motion
#
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
# X=[X[0],X[1]]=(x,x'), f(X)=(X[1],-ω^2 X[0]]
def shm(x, t, omega2):
return [x[1], -omega2 * x[0]]
omega = 1; omega2 = omega * omega
t0=0; T=20; n=100; t=np.linspace(t0, T, n+1)
x0=1; v0=0; X0=[x0,v0]
X=odeint(shm, X0, t, args=(omega2,))
plt.title("単振動: x''=-ω^2 x, ω="+str(omega)+", (x(0),x'(0))=("+str(x0)+','+str(v0)+')')
plt.plot(t,X[:,0],'b', label='x')
plt.plot(t,X[:,1],'g', label='v')
plt.legend(loc='best')
plt.xlabel('t')
plt.ylabel('x and dx/dt')
plt.grid()
plt.show()
|
と
のグラフを描いたわけであるが、
解曲線 (ベクトル値関数
のグラフ) は、
内の曲線である。
それを描くにはどうすればよいかは後述する。
(このプログラムでは、タイトルに日本語を使っている。 現時点では、自分で設定しないと日本語が表示されずに文字化けして、 警告が表示される。設定法については、 付録H.3 を見よ。 設定が面倒な場合は、プログラム内の “単振動” を削ればよい。)
初期値を色々変えた複数の解を求め、それらの解軌道 (解の像) を描いてみよう。
| shm2.py |
# shm2.py --- simple harmonic motion
#
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
# X=[X[0],X[1]]=(x,x'), f(X)=(X[1],-ω^2 X[0]]
def shm(x, t, omega2):
return [x[1], -omega2 * x[0]]
omega = 1; omega2 = omega * omega
t0=0; T=20; n=100; t=np.linspace(t0, T, n+1)
for i in range(0,30):
x0=0.1*i; v0=0; X0=[x0,v0]
X=odeint(shm, X0, t, args=(omega2,))
plt.plot(X[:,0],X[:,1])
plt.title("単振動: x''=-ω^2 x, ω="+str(omega)+"の相図")
plt.legend(loc='best')
plt.xlim(-2,2)
plt.ylim(-2,2)
plt.xlabel('x')
plt.ylabel('dx/dt')
plt.grid()
plt.show()
|
解のグラフと解軌道の両方を描くプログラム例も紹介しておく。 こちらは (半分気分転換で) scipy.integrate の solve_ivp() を使う。
まず、
,
のグラフと、解軌道を描く。
| shm_graph_orbit.py |
# shm_graph_orbit.py --- simple harmonic motion
# coding: utf-8
#
import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt
# x=(x1, x2), f(x)=(x2,-ω^2 x_1)
def shm(t, x, omega):
return [x[1], -omega*omega*x[0]]
omega=2.5
x0=[1.0,0.0]
Tmax=20.0
sol=solve_ivp(shm, [0.0, Tmax], x0, args=(omega,),
dense_output=True, rtol=1e-10,atol=1e-10)
n=2000
t=np.linspace(0.0, Tmax, n+1)
x = sol.sol(t)
plt.figure(figsize=(15,5))
plt.subplot(121)
plt.plot(t,x.T)
plt.xlabel('t')
plt.legend(['x', 'v=dx/dt'], shadow=True)
plt.title('simple harmonic motion (t-x,v)')
plt.subplot(122)
plt.xlim(-1.0,1.0)
plt.plot(x[0], x[1], "-")
plt.xlabel("x")
plt.ylabel("v")
plt.title("orbit in xv-plane")
plt.show()
|
いわゆる解曲線というのは
のグラフのことだから、
3次元空間の中の曲線である。これも描いてみよう。
| shm_graph_orbit_v2.py |
# shm_graph_orbit_v2.py --- simple harmonic motion
# coding: utf-8
#
import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt
# x=(x1, x2), f(x)=(x2,-ω^2 x_1)
def shm(t, x, omega):
return [x[1], -omega*omega*x[0]]
omega=2.5
x0=[1.0,0.0]
Tmax=20.0
sol=solve_ivp(shm, [0.0, Tmax], x0, args=(omega,),
dense_output=True, rtol=1e-10,atol=1e-10)
n=2000
t=np.linspace(0.0, Tmax, n+1)
x = sol.sol(t)
fig=plt.figure(figsize=(15,5))
plt.subplot(131)
plt.plot(t,x.T)
plt.xlabel('t')
plt.ylabel('x,v')
plt.legend(['x', 'v=dx/dt'], shadow=True)
plt.title('simple harmonic motion (t-x,v), ω='+str(omega))
plt.subplot(132)
plt.xlim(-1.0,1.0)
plt.plot(x[0], x[1], "-")
plt.xlabel("x")
plt.ylabel("v")
plt.title("orbit in xv-plane")
# SIR空間での軌道
# 3DAxesを追加
ax = fig.add_subplot(133, projection='3d')
# 軸ラベルを設定
ax.set_xlabel("$t$")
ax.set_ylabel("$x$")
ax.set_zlabel("$v$")
#曲線を描画
ax.plot(t, x[0], x[1])
plt.title("solution curve")
plt.show()
|
桂田 祐史