python で微分方程式を特には
from scipy.integrate import odeint
を使用する.
以下では下記コマンドで適宜ライブラリを追加してほしい.
pip install scipy
pip install numpy
pip install matplotlib japanize-matplotlib
微分方程式
微分方程式を解く.
例として自由落下運動を使用する.
重力 と空気抵抗 が働くとすると,運動方程式は以下のようになる.
これを の時に として微分方程式を python で解いて描画する.
以下コードを示す.
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
import japanize_matplotlib
# 微分方程式の定義
def func(v, t, m, k, g):
dvdt = - k * ( v - m * g / k ) / m
return dvdt
# 質量と係数と重力加速度を指定
m = 100.0
k = 10.0
g= 9.8
# 速度 v の初期値を指定
v = 0.0
# t を 0 から 10 で 1000 個取る
t = np.linspace(0.0, 200.0, 1000)
# 連立常微分方程式をとく
var_list = odeint(func, v, t, args=(m, k, g))
# 以下描画
fig = plt.figure(figsize=(6.4 * 1, 4.8))
ax1 = fig.add_subplot(1, 1, 1, xlabel='$t$', ylabel='速度')
ax1.plot(t, var_list[:, 0], label="$v$")
ax1.legend()
ax1.grid()
fig.savefig(f'AirResistance.png')

終端速度は となるのでうまく描画されている.
参考
連立微分方程式
続いて連立微分方程式を解く.
例として振動現象を上げる.
と v の濃度が
で与えられる.
初期値を のとき として描画する.
以下コードを示す.
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
import japanize_matplotlib
def func(var, t, epsilon, a, b, c, I):
dudt = ( - var[0] * ( var[0] - a ) * ( var[0] - 1 ) - var[1] + I ) / epsilon
dvdt = b * var[0] - c * var[1]
return [dudt, dvdt]
epsilon = 0.05
a = 2.5
b = 2
c = 1
I = 2
# t を 0 から 10 で 1000 個取る
t = np.linspace(0.0, 10.0, 1000)
# u,v の初期値を 0 とする
var_init = [0, 0]
# 連立常微分方程式をとく
var_list = odeint(func, var_init, t, args=(epsilon, a, b, c, I))
# 以下描画
fig = plt.figure(figsize=(6.4 * 2, 4.8))
ax1 = fig.add_subplot(1, 2, 1, xlabel='$t$', ylabel='濃度')
ax2 = fig.add_subplot(1, 2, 2, xlabel='$u$', ylabel='$v$')
ax1.plot(t, var_list[:, 0], label="$u$")
ax1.plot(t, var_list[:, 1], label="$v$")
ax1.legend()
ax1.grid()
ax2.plot(var_list[:, 0], var_list[:, 1], label="")
ax2.grid()
fig.savefig(f'VibrationPhenomena.png')
