微分方程式とは?基本概念と分類をわかりやすく解説

はじめに

物理学や工学の世界では、「ある量が時間とともにどのように変化するか」を記述する場面が数多く登場します。ニュートンの運動方程式、電気回路の電圧・電流の関係、化学反応の濃度変化――これらはすべて 微分方程式 によって記述されます。

本記事では、微分方程式とは何か、どのように分類されるのかを丁寧に解説し、物理・工学での具体例を紹介します。最後に Python を使って微分方程式を数値的に解く方法も示します。

前提知識

この記事を読む前に、以下の記事を読んでおくと理解が深まります。

微分方程式とは何か

微分方程式とは、未知関数とその導関数(微分)を含む等式 のことです。

たとえば、未知関数 $y(x)$ に対して

$$ \frac{dy}{dx} = ky $$

という関係が成り立つとき、これは微分方程式です。ここで $k$ は定数です。この式は「$y$ の変化率が $y$ 自身に比例する」ことを意味しており、人口増加や放射性崩壊のモデルとして広く用いられます。

ポイントは、未知なのは 数値 ではなく 関数 だという点です。代数方程式 $2x + 3 = 0$ の解は数 $x = -3/2$ ですが、微分方程式の解は関数 $y(x) = Ce^{kx}$($C$ は任意定数)のように関数の形で得られます。

なぜ微分方程式が重要か

自然界の法則の多くは、ある物理量の 変化率 に関する法則として表現されます。

  • ニュートンの第2法則: 力は質量と加速度の積 → $F = m\ddot{x}$(位置の2階微分)
  • フックの法則 + 減衰: バネと減衰の復元力 → $m\ddot{x} + c\dot{x} + kx = 0$
  • オームの法則 + キャパシタ: RC回路の過渡応答 → $RC\dot{v} + v = V_0$
  • 放射性崩壊: 崩壊率が現在量に比例 → $dN/dt = -\lambda N$

つまり、微分方程式を解くことは、自然現象の時間発展や空間分布を予測すること に直結します。これが微分方程式を学ぶ最大の理由です。

常微分方程式(ODE)と偏微分方程式(PDE)の違い

微分方程式は、含まれる独立変数の数によって大きく2つに分類されます。

常微分方程式(ODE: Ordinary Differential Equation)

未知関数が 1つの独立変数 のみに依存する場合の微分方程式です。

$$ m\frac{d^2 x}{dt^2} = -mg $$

ここでは未知関数 $x(t)$ は時間 $t$ のみに依存しています。

偏微分方程式(PDE: Partial Differential Equation)

未知関数が 複数の独立変数 に依存する場合の微分方程式です。

$$ \frac{\partial u}{\partial t} = \alpha \frac{\partial^2 u}{\partial x^2} $$

これは熱伝導方程式であり、未知関数 $u(x, t)$ は位置 $x$ と時間 $t$ の2つの独立変数に依存しています。偏微分 $\partial$ が登場するのが特徴です。

本記事シリーズでは、まず常微分方程式(ODE)に焦点を当てて解説を進めます。

階数による分類

微分方程式に含まれる 最高階の導関数の次数 を、その微分方程式の 階数(order) と呼びます。

1階の微分方程式

$$ \frac{dy}{dx} = f(x, y) $$

未知関数の1階導関数 $dy/dx$ が最高階の導関数です。

2階の微分方程式

$$ \frac{d^2 y}{dx^2} + p(x)\frac{dy}{dx} + q(x)y = g(x) $$

未知関数の2階導関数 $d^2y/dx^2$ が最高階です。振動やバネ-マスダンパ系の方程式はこの形をしています。

n階の微分方程式

一般に $n$ 階の微分方程式は次のように表されます。

$$ F\!\left(x,\, y,\, \frac{dy}{dx},\, \frac{d^2 y}{dx^2},\, \dots,\, \frac{d^n y}{dx^n}\right) = 0 $$

実用上は1階と2階が最も頻繁に登場します。

線形と非線形の違い

微分方程式の分類でもう1つ重要なのが、線形か非線形か という区別です。

線形微分方程式

未知関数 $y$ とその導関数が 1次の項としてのみ 現れる(積や累乗がない)微分方程式を線形と呼びます。一般的な $n$ 階線形微分方程式は次の形をしています。

$$ a_n(x)\frac{d^n y}{dx^n} + a_{n-1}(x)\frac{d^{n-1} y}{dx^{n-1}} + \cdots + a_1(x)\frac{dy}{dx} + a_0(x)y = g(x) $$

係数 $a_i(x)$ は $x$ の関数であってもよいですが、$y$ やその導関数に依存してはなりません。

非線形微分方程式

$y$ やその導関数の積、累乗、三角関数などが含まれる場合は非線形です。

$$ \frac{dy}{dx} = y^2 \quad \text{(非線形: } y \text{ の2乗が含まれる)} $$

$$ \frac{d^2 \theta}{dt^2} + \frac{g}{L}\sin\theta = 0 \quad \text{(非線形: } \sin\theta \text{ が含まれる)} $$

2番目の例は振り子の運動方程式です。$\sin\theta \approx \theta$ と近似すれば線形になりますが、厳密には非線形です。

線形微分方程式は 重ね合わせの原理 が成り立つため、解の構造が明確で解析しやすいという利点があります。

一般解と特殊解、初期条件

一般解

微分方程式の解のうち、任意定数を含む最も一般的な形 の解を 一般解 と呼びます。

$n$ 階の微分方程式の一般解には、通常 $n$ 個の任意定数が含まれます。たとえば、2階の微分方程式

$$ \frac{d^2 y}{dx^2} = 0 $$

の一般解は

$$ y = C_1 x + C_2 $$

です。ここで $C_1, C_2$ は任意定数です。

特殊解(特解)

一般解の任意定数に具体的な値を代入して得られる解を 特殊解 と呼びます。上の例で $C_1 = 2,\ C_2 = 3$ とすれば、$y = 2x + 3$ が特殊解の1つです。

初期条件と初期値問題

任意定数を決定するために与える条件を 初期条件(または境界条件)と呼びます。$n$ 階の微分方程式には $n$ 個の初期条件が必要です。

たとえば1階の微分方程式

$$ \frac{dy}{dx} = ky, \quad y(0) = y_0 $$

の場合、初期条件 $y(0) = y_0$ から任意定数が $C = y_0$ と決まり、特殊解

$$ y(x) = y_0 e^{kx} $$

が得られます。微分方程式と初期条件をセットにしたものを 初期値問題(IVP: Initial Value Problem) と呼びます。

物理・工学での具体例

例1: 自由落下

質量 $m$ の物体が重力のみを受けて落下する場合、ニュートンの運動方程式は

$$ m\ddot{x} = -mg $$

です。ここで $x$ は鉛直上向きを正とした位置、$g$ は重力加速度です。両辺を $m$ で割ると

$$ \ddot{x} = -g $$

となります。これは2階の線形常微分方程式であり、2回積分することで一般解が得られます。

$$ \dot{x} = -gt + C_1 $$

$$ x = -\frac{1}{2}gt^2 + C_1 t + C_2 $$

初期条件 $x(0) = x_0$(初期位置)、$\dot{x}(0) = v_0$(初速度)を与えると

$$ x(t) = -\frac{1}{2}gt^2 + v_0 t + x_0 $$

という、おなじみの放物運動の式が得られます。

例2: バネ-マスダンパ系

質量 $m$ の物体がバネ定数 $k$ のバネと減衰係数 $c$ のダンパに接続されている場合の運動方程式は

$$ m\ddot{x} + c\dot{x} + kx = 0 $$

です。これは2階の線形常微分方程式であり、$c$ の値に応じて 過減衰臨界減衰不足減衰(振動) の3パターンの解が得られます。この方程式は機械工学や制御工学で極めて重要です。

例3: RC回路

抵抗 $R$ とキャパシタ $C$ が直列に接続された回路に一定電圧 $V_0$ を印加したとき、キャパシタ両端の電圧 $v(t)$ に関する方程式は

$$ RC\dot{v} + v = V_0 $$

です。これは1階の線形常微分方程式です。初期条件 $v(0) = 0$(キャパシタが初期放電状態)のもとで解くと

$$ v(t) = V_0\!\left(1 – e^{-t/(RC)}\right) $$

が得られます。時定数 $\tau = RC$ によってキャパシタの充電速度が決まります。

1階変数分離形の解法

最も基本的な解法として、変数分離形 の微分方程式を解いてみましょう。

変数分離形とは

次の形に書ける微分方程式を変数分離形と呼びます。

$$ \frac{dy}{dx} = f(x)\,g(y) $$

右辺が $x$ のみの関数と $y$ のみの関数の積に分離できる場合です。

解法の手順

  1. 両辺を $g(y)$ で割り、$x$ と $y$ を左辺・右辺に分離します。

$$ \frac{1}{g(y)}\,dy = f(x)\,dx $$

  1. 両辺を積分します。

$$ \int \frac{1}{g(y)}\,dy = \int f(x)\,dx + C $$

  1. 積分を実行して $y$ について解きます。

具体例: $dy/dx = ky$

指数関数的増加・減衰を記述する微分方程式 $dy/dx = ky$ を解きます。

ステップ1: 変数を分離します。ここで $f(x) = k$、$g(y) = y$ です。

$$ \frac{1}{y}\,dy = k\,dx $$

ステップ2: 両辺を積分します。

$$ \int \frac{1}{y}\,dy = \int k\,dx $$

$$ \ln|y| = kx + C’ $$

ここで $C’$ は積分定数です。

ステップ3: 両辺の指数関数を取ります。

$$ |y| = e^{kx + C’} = e^{C’} e^{kx} $$

$C = \pm e^{C’}$ とまとめると、一般解は

$$ y = Ce^{kx} $$

となります。初期条件 $y(0) = y_0$ を与えると $C = y_0$ となり、特殊解

$$ y(x) = y_0 e^{kx} $$

が得られます。$k > 0$ のとき指数関数的増加、$k < 0$ のとき指数関数的減衰を表します。

Python による数値解法と可視化

微分方程式の解析解が求められない場合や、数値的に振る舞いを確認したい場合には、数値解法が有効です。Python の scipy.integrate.solve_ivp を使って、指数関数的増加と減衰の例を数値的に解き、可視化してみましょう。

import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp

# --- dy/dx = ky の数値解法 ---

# 微分方程式の右辺を定義(solve_ivp の形式に合わせる)
def exponential_ode(t, y, k):
    """dy/dt = k * y"""
    return k * y

# パラメータ設定
k_growth = 0.5    # 増加の場合の k
k_decay = -0.5    # 減衰の場合の k
y0 = [1.0]        # 初期条件 y(0) = 1
t_span = (0, 10)  # 解く区間
t_eval = np.linspace(0, 10, 200)  # 出力する時刻

# 数値解を求める(増加)
sol_growth = solve_ivp(
    exponential_ode,
    t_span,
    y0,
    t_eval=t_eval,
    args=(k_growth,),
    method="RK45"
)

# 数値解を求める(減衰)
sol_decay = solve_ivp(
    exponential_ode,
    t_span,
    y0,
    t_eval=t_eval,
    args=(k_decay,),
    method="RK45"
)

# 解析解(比較用)
y_exact_growth = y0[0] * np.exp(k_growth * t_eval)
y_exact_decay = y0[0] * np.exp(k_decay * t_eval)

# --- 可視化 ---
fig, axes = plt.subplots(1, 2, figsize=(12, 5))

# 指数関数的増加
axes[0].plot(sol_growth.t, sol_growth.y[0], "o", markersize=3, label="数値解 (solve_ivp)")
axes[0].plot(t_eval, y_exact_growth, "-", linewidth=2, label=f"解析解 $y = e^{{{k_growth}x}}$")
axes[0].set_xlabel("$x$", fontsize=13)
axes[0].set_ylabel("$y$", fontsize=13)
axes[0].set_title(f"指数関数的増加 ($k = {k_growth}$)", fontsize=14)
axes[0].legend(fontsize=11)
axes[0].grid(True, alpha=0.3)

# 指数関数的減衰
axes[1].plot(sol_decay.t, sol_decay.y[0], "o", markersize=3, label="数値解 (solve_ivp)")
axes[1].plot(t_eval, y_exact_decay, "-", linewidth=2, label=f"解析解 $y = e^{{{k_decay}x}}$")
axes[1].set_xlabel("$x$", fontsize=13)
axes[1].set_ylabel("$y$", fontsize=13)
axes[1].set_title(f"指数関数的減衰 ($k = {k_decay}$)", fontsize=14)
axes[1].legend(fontsize=11)
axes[1].grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig("ode_exponential.png", dpi=150, bbox_inches="tight")
plt.show()

print("=== 数値解と解析解の最大誤差 ===")
print(f"増加 (k={k_growth}): {np.max(np.abs(sol_growth.y[0] - y_exact_growth)):.2e}")
print(f"減衰 (k={k_decay}): {np.max(np.abs(sol_decay.y[0] - y_exact_decay)):.2e}")

このコードを実行すると、左のグラフに指数関数的増加($k = 0.5$)、右のグラフに指数関数的減衰($k = -0.5$)が描画されます。solve_ivp の数値解(マーカー)と解析解(実線)がほぼ完全に一致していることが確認できます。

solve_ivp は Runge-Kutta 法(デフォルトは RK45)を用いて微分方程式を数値的に解きます。引数の意味は以下のとおりです。

引数 説明
fun 微分方程式の右辺 $f(t, y)$ を定義した関数
t_span 独立変数の区間 $(t_0, t_f)$
y0 初期条件(リストまたは配列)
t_eval 解を出力する時刻の配列
args fun に渡す追加の引数(今回は $k$)
method 数値解法の種類("RK45", "RK23", "Radau" など)

まとめ

本記事では、微分方程式の基本概念を整理しました。

  • 微分方程式は 未知関数とその導関数の関係式 であり、解は関数として得られます。
  • 常微分方程式(ODE) は独立変数が1つ、偏微分方程式(PDE) は複数の独立変数を持ちます。
  • 微分方程式は 階数(最高階導関数の次数)と 線形性 によって分類されます。
  • 一般解 は任意定数を含み、初期条件 を与えることで 特殊解 が決定されます。
  • 自由落下、バネ-マスダンパ系、RC回路など、物理・工学の基本的な問題が微分方程式で記述されます。
  • 最も基本的な解法として 変数分離法 を用い、$dy/dx = ky$ の解 $y = Ce^{kx}$ を導出しました。
  • Python の scipy.integrate.solve_ivp を用いて、微分方程式を数値的に解く方法を示しました。

次の記事では、より体系的に 1階線形常微分方程式の解法(積分因子法)と 2階定数係数線形常微分方程式の解法(特性方程式法)を解説します。微分方程式の豊かな世界をさらに深く探っていきましょう。