跳轉到

09.2 微分方程#

本節目標#

  • 理解常微分方程(ODE)的基本概念:階數、通解與特解
  • 學會用 dsolve() 解三種典型方程:分離變數型、一階線性、二階常係數
  • 掌握特徵方程與二階齊次解的關係(銜接 6.3 的多項式求根)
  • 用 ics 參數給定初值條件,求出唯一的特解
  • 動手實驗:改變參數求解並畫出解曲線族

微分方程的概念#

微分方程是「含有未知函數導數的方程」。例如:

\[ y' = ky \quad\text{(一階)}, \qquad y'' + y = 0 \quad\text{(二階)} \]
  • 階數:方程中出現的最高導數階數
  • 通解:滿足方程的解的一般形式,含有任意常數( \(n\) 階方程有 \(n\) 個)
  • 特解:用初值條件(如 \(y(0) = 1,\ y'(0) = 0\) )把常數定下來後的解

在 SymPy 中,未知函數必須先用 Function 宣告成「函數符號」:

from sympy import symbols, Function

t = symbols('t')
y = Function('y')(t)   # y 是 t 的未知函數

print(y.diff(t))    # Derivative(y(t), t)
print(y.diff(t, 2)) # Derivative(y(t), t, t)

dsolve() 用法:分離變數型#

指數成長模型 \(y' = ky\) 是最經典的分離變數型方程: \(\dfrac{dy}{y} = k\,dt\) ,積分得 \(y = Ce^{kt}\) 。

from sympy import symbols, Function, dsolve, exp, Eq

t, k = symbols('t k')
y = Function('y')

sol = dsolve(y(t).diff(t) - k*y(t), y(t))
print(sol)   # Eq(y(t), C1*exp(k*t))

dsolve(方程, y(t)) 的第一個參數也可以直接給 Eq(...) 形式。帶初值條件時用 ics 參數,以字典 {y(0): 1} 表示:

sol = dsolve(y(t).diff(t) - k*y(t), y(t), ics={y(0): 5})
print(sol)   # Eq(y(t), 5*exp(k*t))

一階線性方程#

一階線性方程的標準型:

\[ y' + p(t)\, y = q(t) \]

解法是找積分因子 \(\mu(t) = e^{\int p\,dt}\) ,但 SymPy 的 dsolve 會自動分類並求解:

from sympy import Function, dsolve, symbols

t = symbols('t')
y = Function('y')

# y' + y = t
sol = dsolve(y(t).diff(t) + y(t) - t, y(t))
print(sol)
# Eq(y(t), C1*exp(-t) + t - 1)

# 帶初值條件 y(0) = 2
sol2 = dsolve(y(t).diff(t) + y(t) - t, y(t), ics={y(0): 2})
print(sol2)
# Eq(y(t), 2*exp(-t) + t - 1)

二階常係數與特徵方程(銜接 6.3)#

對齊次方程 \(ay'' + by' + cy = 0\) ,假設解為 \(y = e^{rt}\) ,代入後得到特徵方程:

\[ ar^2 + br + c = 0 \]

這正是第 6.3 節學過的一元二次多項式方程!三種情況:

判別式 \(b^2 - 4ac\) 解的形式
\(> 0\) (相異實根) \(y = C_1 e^{r_1 t} + C_2 e^{r_2 t}\)
\(= 0\) (重根) \(y = (C_1 + C_2 t)e^{rt}\)
\(< 0\) (共軛複根 \(\alpha \pm \beta i\) ) \(y = e^{\alpha t}(C_1 \cos \beta t + C_2 \sin \beta t)\)

**範例: \(y'' + y = 0\) **。特徵方程 \(r^2 + 1 = 0\) 有根 \(r = \pm i\) ,所以解是正弦與餘弦的組合:

from sympy import Function, dsolve, symbols, Eq

t = symbols('t')
y = Function('y')

sol = dsolve(y(t).diff(t, 2) + y(t), y(t))
print(sol)
# Eq(y(t), C1*sin(t) + C2*cos(t))

# 用 6.3 的 solve 解特徵方程,驗證根確實是 ±i
r = symbols('r')
from sympy import solve
print(solve(r**2 + 1, r))   # [-I, I]

帶初值條件 \(y(0) = 1,\ y'(0) = 0\) (初始位移 1、初速 0 的單擺/彈簧振盪):

sol = dsolve(y(t).diff(t, 2) + y(t), y(t),
             ics={y(0): 1, y(t).diff(t).subs(t, 0): 0})
print(sol)   # Eq(y(t), cos(t))

再看一個阻尼振盪: \(y'' + 2y' + 5y = 0\) ,判別式 \(4 - 20 < 0\) ,解中有 \(e^{-t}\) 衰減因子:

sol = dsolve(y(t).diff(t, 2) + 2*y(t).diff(t) + 5*y(t), y(t),
             ics={y(0): 1, y(t).diff(t).subs(t, 0): 0})
print(sol)
# Eq(y(t), (cos(2*t) + sin(2*t)/2)*exp(-t))

動手實驗:參數變動與解曲線族#

實驗一:改變成長率 \(k\) ,畫出 \(y' = ky\) 、 \(y(0) = 1\) 的解曲線族,觀察 \(k\) 的正負如何決定成長或衰退:

import numpy as np
import matplotlib.pyplot as plt
from sympy import symbols, Function, dsolve, lambdify

t, k = symbols('t k')
y = Function('y')

ts = np.linspace(0, 3, 200)
for kv in [-1, -0.5, 0.5, 1, 2]:
    sol = dsolve(y(t).diff(t) - k*y(t), y(t), ics={y(0): 1})
    f = lambdify(t, sol.rhs.subs(k, kv))
    plt.plot(ts, f(ts), label=f'k = {kv}')

plt.axhline(0, color='gray', lw=0.5)
plt.legend()
plt.title("$y' = ky,\\ y(0)=1$,不同 k 的解")
plt.xlabel('t'); plt.ylabel('y')
plt.show()

實驗二:阻尼振盪 \(y'' + 2y' + cy = 0\) ,掃過不同的 \(c\) ,從欠阻尼到過阻尼:

ts = np.linspace(0, 10, 500)
for cv in [1, 2, 5, 10]:
    sol = dsolve(y(t).diff(t, 2) + 2*y(t).diff(t) + cv*y(t), y(t),
                 ics={y(0): 1, y(t).diff(t).subs(t, 0): 0})
    f = lambdify(t, sol.rhs)
    plt.plot(ts, f(ts), label=f'c = {cv}')

plt.legend()
plt.title('阻尼振盪:c 越大衰減越快')
plt.xlabel('t'); plt.ylabel('y')
plt.show()

觀察重點: \(c = 1\) 時明顯振盪(欠阻尼,複根); \(c = 10\) 時單調衰減(過阻尼,相異實根)。臨界值 \(c = 1\) 對應重根 \(r = -1\) ,正好是判別式為零的情形——特徵方程的理論與圖形完全吻合。

小結與練習#

本節重點

  • 未知函數用 Function('y')(t) 宣告,導數用 .diff(t)
  • dsolve(方程, y(t)) 自動分類並求解;ics={y(0): ..., y'(0): ...} 給初值條件
  • 分離變數型、一階線性、二階常係數是三大基本類型
  • 二階常係數的解由特徵方程 \(ar^2 + br + c = 0\) 的根決定(複習 6.3)
  • lambdify 把符號解轉成數值函數,方便畫圖

練習

  1. 解 \(y' = y\cos t\) (分離變數型),並驗證解確實滿足方程。
  2. 解 \(y' - 2ty = t\) (一階線性),帶初值條件 \(y(0) = 0\) 。
  3. 解 \(y'' - 4y' + 4y = 0\) , \(y(0) = 1\) , \(y'(0) = 0\) ,並說明為什麼解中有 \(t e^{2t}\) 項。
  4. 實驗:對 \(y'' + y = 0\) 分別設 \(y(0) = 1, y'(0) = 0\) 與 \(y(0) = 0, y'(0) = 1\) ,畫出兩條解曲線,確認它們是 \(\cos t\) 與 \(\sin t\) 。