跳轉到

5.2 微分#

本節目標#

  • 從導數的定義出發,理解「瞬時變化率」與切線斜率的關係
  • 熟練使用 diff(),包括高階導數
  • 對照手算法則(鏈鎖律、乘法則、除法則)與 SymPy 的自動計算
  • 學會隱函數微分 idiff 與找極值的完整流程

導數的定義#

函數 \(f\) 在 \(x = a\) 處的導數定義為:

\[ f'(a) = \lim_{h \to 0} \frac{f(a+h) - f(a)}{h} \]

幾何意義: \(\dfrac{f(a+h) - f(a)}{h}\) 是割線斜率;讓 \(h \to 0\) ,割線轉成切線,斜率就是 \(f'(a)\) 。物理意義:位移對時間的導數是瞬時速度。

SymPy 可以直接用定義算導數——這是檢驗理解的好方法:

from sympy import symbols, limit, sin, diff

x, h = symbols('x h')
f = sin(x)

# 用定義算 sin 的導數
limit((sin(x + h) - sin(x)) / h, h, 0)   # cos(x)

diff():一行搞定#

實務上用 diff():

diff(sin(x))            # cos(x)
diff(x**3)              # 3*x**2
diff(x**x, x)           # x**x*(log(x) + 1)  ← 對數微分,SymPy 秒解

第三個例子值得停留一下: \(x^x\) 是手算的難題(底數指數都是 \(x\) ),需要先取對數。SymPy 不必你提醒,自動選對策略。

切線方程計算#

過點 \((a, f(a))\) 的切線方程是:

\[ y = f(a) + f'(a)(x - a) \]

完整流程:定義函數 → 求導 → 代入 → 組裝直線。

from sympy import symbols, diff, solve
import matplotlib.pyplot as plt
import numpy as np

x = symbols('x')
f = x**2          # 範例函數
a = 1             # 切點

fp = diff(f, x)                 # 導數 2x
slope = fp.subs(x, a)           # 切線斜率 2
tangent = f.subs(x, a) + slope * (x - a)   # y = 1 + 2(x-1) = 2x - 1
print(tangent)                  # 2*x - 1

畫圖驗證切線確實「貼著」曲線:

xs = np.linspace(-1, 2.5, 200)
plt.plot(xs, xs**2, label='$f(x)=x^2$')
plt.plot(xs, 2*xs - 1, '--', label='tangent at $x=1$')
plt.scatter([1], [1], color='red', zorder=3)
plt.legend()
plt.show()

法則對照:SymPy 自動處理 vs 手算#

乘法則: \((uv)' = u'v + uv'\)

以 \(f(x) = x^2 \sin x\) 為例,手算:

\[ (x^2 \sin x)' = 2x \sin x + x^2 \cos x \]

SymPy 給出相同結果(內部就是套乘法則):

u, v = x**2, sin(x)
diff(u * v)                    # 2*x**2*cos(x) + 2*x*sin(x)(順序可能不同)
diff(u) * v + u * diff(v)      # 手動套乘法則,一致!

除法則: \(\left( \dfrac{u}{v} \right)' = \dfrac{u'v - uv'}{v^2}\)

from sympy import cos, simplify

expr = sin(x) / x
diff(expr)                              # (x*cos(x) - sin(x))/x**2
simplify((diff(u := sin(x), x) * x - u * 1) / x**2)  # 同上

鏈鎖律: \((f(g(x)))' = f'(g(x)) \cdot g'(x)\)

以 \(\sin(x^2)\) 為例,手算:外層 \(\sin\) 的導數 \(\cos\) 乘上內層導數 \(2x\) :

diff(sin(x**2))     # 2*x*cos(x**2)

多層巢狀也難不倒它:

diff(sin(cos(exp(x))))   # -sin(cos(exp(x)))*exp(x)*cos(exp(x))

展開來看,這正是鏈鎖律一層一層剝開的結果。建議的學習法:每遇到一個法則,先自己手算,再讓 SymPy 驗算——把它當成永不疲倦的助教。

隱函數微分(idiff)#

像 \(x^2 + y^2 = 1\) 這樣的方程, \(y\) 沒有明確寫成 \(x\) 的函數,稱為隱函數。對它微分要把 \(y\) 視為 \(y(x)\) ,兩邊對 \(x\) 微分:

\[ 2x + 2y \cdot y' = 0 \implies y' = -\frac{x}{y} \]

SymPy 用 idiff 直接處理:

from sympy import idiff

y = symbols('y')
eq = x**2 + y**2 - 1

dydx = idiff(eq, y, x)     # -x/y
# 圓上點 (1/2, sqrt(3)/2) 的切線斜率:
dydx.subs({x: sympy.Rational(1, 2), y: sympy.sqrt(3)/2})   # -sqrt(3)/3

高階導數#

diff 的第三個參數指定階數,或連續呼叫:

diff(x**4, x, 1)     # 4*x**3
diff(x**4, x, 2)     # 12*x**2
diff(x**4, x, 3)     # 24*x
diff(x**4, x, 4)     # 24
diff(x**4, x, 5)     # 0(多項式微到底歸零)
diff(sin(x), x, 4)   # sin(x) ← 四階繞一圈回來

\(\sin\) 的導數以 4 為週期循環,這個性質在 5.4 節推導它的泰勒級數時是關鍵。

臨界點找極值:完整流程#

找 \(f(x) = x^3 - 3x\) 的極值,標準四步驟:

① 微分 → **② 解 \(f'(x) = 0\) ** → ③ 二階判別 → ④ 結論

from sympy import solve

f = x**3 - 3*x
fp = diff(f, x)          # 3*x**2 - 3
crit = solve(fp, x)      # [-1, 1] ← 臨界點

fpp = diff(f, x, 2)      # 6*x(二階導數)
for c in crit:
    val = fpp.subs(x, c)
    kind = "極小" if val > 0 else ("極大" if val < 0 else "無法判定")
    print(f"x = {c}, f'' = {val} → {kind}, f = {f.subs(x, c)}")
# x = -1: f'' = -6 → 極大, f = 2
# x =  1: f'' =  6 → 極小, f = -2

判別原理: \(f'' > 0\) 表示切線斜率正在遞增,曲線開口向上(谷底 → 極小); \(f'' < 0\) 則開口向下(峰頂 → 極大)。

動手實驗:畫 \(f\) 與 \(f'\) 疊圖看關係#

導數的正負控制原函數的升降。把兩者畫在同一張圖上,關係一目了然:

import numpy as np
import matplotlib.pyplot as plt

f = x**3 - 3*x
fp = diff(f, x)

flam = lambdify(x, f, 'numpy')
fplam = lambdify(x, fp, 'numpy')

xs = np.linspace(-2.5, 2.5, 400)
plt.plot(xs, flam(xs), label='$f(x)=x^3-3x$')
plt.plot(xs, fplam(xs), '--', label="$f'(x)=3x^2-3$")
plt.axhline(0, color='gray', lw=0.5)
plt.scatter([-1, 1], [0, 0], color='red', zorder=3, label="f' = 0")
plt.legend()
plt.show()

觀察重點:

  1. \(f' > 0\) 的區間( \(x < -1\) 與 \(x > 1\) ), \(f\) 正在上升。
  2. \(f' < 0\) 的區間( \(-1 < x < 1\) ), \(f\) 正在下降。
  3. \(f' = 0\) 的紅點處, \(f\) 恰好出現峰頂與谷底。
  4. 再疊一條 \(f'' = 6x\) :它與 \(x\) 軸的交點( \(x=0\) )正是 \(f\) 的反曲點——凹凸性翻轉之處。

建議把 f 換成 \(x^3 - 3x^2\) 或 \(\sin(x)\) 重跑一次,每次都先預測再驗證。

小結與練習#

  • 導數 \(= \lim_{h\to0} \frac{f(a+h)-f(a)}{h} =\) 切線斜率 \(=\) 瞬時變化率。
  • diff(expr, x, n) 求 \(n\) 階導數;idiff 處理隱函數。
  • 鏈鎖律、乘法則、除法則 SymPy 全自動處理,適合用來驗算手算結果。
  • 找極值流程:diff → solve \(f'=0\) → f'' 判別正負。

練習

  1. 用定義(limit)驗證 \(x^2\) 的導數是 \(2x\) 。
  2. 求 \(f(x) = x e^{-x}\) 的極值點,並判斷是極大還是極小。
  3. 用 idiff 求橢圓 \(\frac{x^2}{4} + y^2 = 1\) 在 \(x = 1\) 、 \(y > 0\) 處的切線方程。
  4. 對 \(f(x) = \sin(x)\) 畫 \(f\) 、 \(f'\) 、 \(f''\) 三線疊圖,描述三者相位差。