変数分離形は、1階常微分方程式の中で最も基本的かつ重要な形式の一つです。右辺が $x$ だけの関数と $y$ だけの関数の積で表せる場合、変数を分離して両辺を別々に積分することで解を求められます。
人口増加モデル、放射性崩壊、化学反応速度など、自然現象の多くが変数分離形の微分方程式で記述されます。本記事では、変数分離の手順を丁寧に解説し、具体的な応用例をPython実装とともに紹介します。
本記事の内容
- 変数分離形の定義と判別法
- 解法の手順
- 具体例(指数増減、ロジスティック方程式)
- Pythonでの数値解法と可視化
前提知識
この記事を読む前に、以下の記事を読んでおくと理解が深まります。
変数分離形とは
次の形の1階常微分方程式を変数分離形と呼びます。
$$ \frac{dy}{dx} = f(x) \cdot g(y) $$
右辺が $x$ だけの関数 $f(x)$ と $y$ だけの関数 $g(y)$ の積に分解できるのが特徴です。
解法の手順
$g(y) \neq 0$ のとき、次のように変数を分離します。
$$ \begin{align} \frac{dy}{dx} &= f(x) \cdot g(y) \\ \frac{1}{g(y)} \, dy &= f(x) \, dx \\ \int \frac{1}{g(y)} \, dy &= \int f(x) \, dx + C \end{align} $$
左辺は $y$ のみ、右辺は $x$ のみの積分となり、それぞれを独立に計算できます。
注意: $g(y_0) = 0$ となる $y_0$ が存在する場合、$y = y_0$ は定数解(平衡解)となります。この解は変数分離の過程で失われるため、別途確認が必要です。
具体例
例1: 指数増減 $y’ = ky$
最も基本的な変数分離形です。$k > 0$ なら指数増加、$k < 0$ なら指数減衰を表します。
$$ \begin{align} \frac{dy}{dx} &= ky \\ \frac{dy}{y} &= k \, dx \\ \int \frac{dy}{y} &= \int k \, dx \\ \ln|y| &= kx + C_0 \\ y &= Ce^{kx} \quad (C = \pm e^{C_0}) \end{align} $$
初期条件 $y(0) = y_0$ のとき、$C = y_0$ より $y = y_0 e^{kx}$ となります。
例2: ロジスティック方程式 $y’ = ry(1 – y/K)$
人口増加のモデルとして有名な方程式です。$r$ は増加率、$K$ は環境収容力です。
$$ \frac{dy}{dx} = ry\left(1 – \frac{y}{K}\right) $$
変数分離して部分分数分解します。
$$ \begin{align} \frac{dy}{y(1 – y/K)} &= r \, dx \\ \frac{K \, dy}{y(K – y)} &= r \, dx \end{align} $$
部分分数分解 $\frac{K}{y(K-y)} = \frac{1}{y} + \frac{1}{K-y}$ より、
$$ \begin{align} \int \left(\frac{1}{y} + \frac{1}{K-y}\right) dy &= \int r \, dx \\ \ln|y| – \ln|K – y| &= rx + C_0 \\ \ln\left|\frac{y}{K – y}\right| &= rx + C_0 \\ \frac{y}{K – y} &= Ae^{rx} \quad (A = e^{C_0}) \end{align} $$
$y$ について解くと、
$$ y = \frac{KAe^{rx}}{1 + Ae^{rx}} = \frac{K}{1 + \frac{1}{A}e^{-rx}} $$
初期条件 $y(0) = y_0$ より $A = y_0/(K – y_0)$ となり、
$$ \boxed{y(x) = \frac{K}{1 + \left(\frac{K}{y_0} – 1\right)e^{-rx}}} $$
$x \to \infty$ で $y \to K$(環境収容力に漸近)となることが確認できます。
例3: $y’ = \frac{x}{y}$
$$ \begin{align} y \, dy &= x \, dx \\ \int y \, dy &= \int x \, dx \\ \frac{y^2}{2} &= \frac{x^2}{2} + C \\ y^2 – x^2 &= 2C \end{align} $$
これは双曲線の族を表します。
Pythonでの実装
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
# --- 指数増減 y' = ky ---
k_vals = [0.5, -0.3, 1.0]
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
# 指数増減
t = np.linspace(0, 5, 200)
for k in k_vals:
y = np.exp(k * t)
axes[0].plot(t, y, label=f'k = {k}')
axes[0].set_xlabel('x')
axes[0].set_ylabel('y')
axes[0].set_title("指数増減 $y' = ky$, $y(0)=1$")
axes[0].legend()
axes[0].grid(True, alpha=0.3)
# --- ロジスティック方程式 ---
K = 100 # 環境収容力
r = 0.5 # 増加率
y0_vals = [5, 20, 50, 120]
def logistic(t, y):
return r * y * (1 - y / K)
t_span = [0, 20]
t_eval = np.linspace(0, 20, 300)
for y0 in y0_vals:
sol = solve_ivp(logistic, t_span, [y0], t_eval=t_eval)
axes[1].plot(sol.t, sol.y[0], label=f'$y_0 = {y0}$')
axes[1].axhline(y=K, color='k', linestyle='--', alpha=0.5, label=f'K = {K}')
axes[1].set_xlabel('t')
axes[1].set_ylabel('y')
axes[1].set_title(f"ロジスティック方程式 (r={r}, K={K})")
axes[1].legend()
axes[1].grid(True, alpha=0.3)
# --- y' = x/y (双曲線族) ---
x_range = np.linspace(-3, 3, 400)
for C in [-2, -1, 0, 1, 2]:
disc = x_range**2 + 2 * C
mask = disc > 0
axes[2].plot(x_range[mask], np.sqrt(disc[mask]), 'b-', alpha=0.6)
axes[2].plot(x_range[mask], -np.sqrt(disc[mask]), 'b-', alpha=0.6)
axes[2].set_xlabel('x')
axes[2].set_ylabel('y')
axes[2].set_title("$y' = x/y$ の解曲線(双曲線族)")
axes[2].set_xlim(-3, 3)
axes[2].set_ylim(-3, 3)
axes[2].set_aspect('equal')
axes[2].grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('separation_of_variables.png', dpi=150, bbox_inches='tight')
plt.show()
ロジスティック方程式のグラフから、初期値によらず解が環境収容力 $K$ に漸近する様子が確認できます。$y_0 > K$ の場合は減少しながら $K$ に近づきます。
まとめ
本記事では、変数分離形の微分方程式の解法を解説しました。
- 変数分離形は $y’ = f(x) \cdot g(y)$ の形
- $y$ と $x$ を左辺・右辺に分けて両辺を積分する
- $g(y) = 0$ の定数解を別途チェックする
- 指数増減 $y’ = ky$ やロジスティック方程式が代表例
- 部分分数分解と組み合わせて複雑な例にも対応できる
次のステップとして、以下の記事も参考にしてください。