5.2 特徵值計算#
本節目標#
- 完整手算一個 \(2 \times 2\) 矩陣的特徵值與特徵向量
- 學會兩個速算技巧: \(\lambda_1 + \lambda_2 = \mathrm{tr}(A)\) 、 \(\lambda_1 \lambda_2 = \det(A)\)
- 熟練使用
np.linalg.eig,並理解它的輸出格式(含單位化的特徵向量) - 認識重根與「特徵向量不夠用」的情況(為對角化鋪路)
- 學會解讀複數特徵值背後的幾何訊息
2×2 手算完整流程#
以 \(A = \begin{bmatrix} 4 & 1 \\ 2 & 3 \end{bmatrix}\) 為例,走一遍標準流程。
第 1 步:寫出特徵方程
第 2 步:因式分解求根
**第 3 步:把每個 \(\lambda\) 代回 \((A - \lambda I)\mathbf{v} = \mathbf{0}\) **
\(\lambda = 5\) 時:
\(\lambda = 2\) 時:
注意特徵向量只定方向、不定長度: \(\begin{bmatrix} 1 \\ 1 \end{bmatrix}\) 、 \(\begin{bmatrix} 100 \\ 100 \end{bmatrix}\) 都是 \(\lambda = 5\) 的特徵向量。 習慣上我們把它單位化(除以自己的長度),方便比較與計算:
import numpy as np
A = np.array([[4.0, 1.0],
[2.0, 3.0]])
vals, vecs = np.linalg.eig(A)
print("特徵值:", vals) # [5. 2.]
print("特徵向量(單位化):")
print(vecs) # 每一行是 1/sqrt(2) 之類
# 驗證 A v = lambda v
for i in range(2):
v = vecs[:, i]
print(A @ v, vals[i] * v) # 兩者應幾乎相同
速算技巧:跡與行列式#
把特徵多項式展開成一般式( \(2 \times 2\) 情形):
由根與係數關係立刻得到兩個好用一輩子的公式:
驗證剛剛的例子: \(\mathrm{tr}(A) = 4 + 3 = 7 = 5 + 2\) ✓, \(\det(A) = 12 - 2 = 10 = 5 \times 2\) ✓。
速算的實戰用法——用檢驗代替死算:
def check_eigen_2x2(A, lam1, lam2):
"""用跡與行列式快速驗證兩個候選特徵值"""
tr = A[0, 0] + A[1, 1]
det = np.linalg.det(A)
ok1 = np.isclose(lam1 + lam2, tr) and np.isclose(lam1 * lam2, det)
return ok1
A = np.array([[4.0, 1.0], [2.0, 3.0]])
print(check_eigen_2x2(A, 5, 2)) # True
print(check_eigen_2x2(A, 5, 3)) # False(和對了,積錯)
另一個妙用:不用解二次方程就能判斷特徵值的性質 (判別式 \(\Delta = \mathrm{tr}^2 - 4\det\) ):
| 判別式 | 特徵值性質 | 幾何 |
|---|---|---|
| \(\Delta > 0\) | 兩個相異實根 | 兩個不動方向 |
| \(\Delta = 0\) | 重根 | 可能只有一個方向(見下節) |
| \(\Delta < 0\) | 共軛複根 | 旋轉成分,無實不動方向 |
np.linalg.eig 的完整用法#
import numpy as np
A = np.array([[4.0, 1.0],
[2.0, 3.0]])
eigvals, eigvecs = np.linalg.eig(A)
必須記住的三件事:
eigvals:形狀(n,)的一維陣列,可能含複數(dtype 會自動變 complex)eigvecs:形狀(n, n),第i行(column)是對應eigvals[i]的單位特徵向量 ——是「第i行」不是「第i列」,初學者最常搞錯- 特徵向量已自動單位化(長度為 1),且 NumPy 只保證方向正確, 正負號與順序可能與手算不同——這完全合法,因為特徵向量本來就能差一個常數倍
print(np.linalg.norm(eigvecs[:, 0])) # 1.0(已單位化)
print(A @ eigvecs[:, 0] - eigvals[0] * eigvecs[:, 0]) # ~ 0
只要特徵值、不要特徵向量時用較省記憶的:
np.linalg.eigvals(A) # array([5., 2.])
重根與「特徵向量不夠用」的陷阱#
看剪切矩陣 \(S = \begin{bmatrix} 1 & 1 \\ 0 & 1 \end{bmatrix}\) :
代回 \((S - I)\mathbf{v} = \mathbf{0}\) :
兩次的特徵值,卻只解出一條特徵直線。 \(2 \times 2\) 的矩陣,我們希望有兩個獨立特徵向量把平面撐起來, 這裡卻缺了一個——這種矩陣不可對角化(5.3 節詳談, 需要 Jordan 標準型才能完全描述它)。
S = np.array([[1.0, 1.0], [0.0, 1.0]])
vals, vecs = np.linalg.eig(S)
print(vals) # [1. 1.]
print(vecs) # 兩行幾乎平行!獨立特徵向量只有一個
print(np.linalg.matrix_rank(vecs)) # 1 < 2,不夠用
判斷準則(先記結論,5.3 節證明): \(\lambda\) 的重數(在特徵多項式中出現的次數) 等於對應獨立特徵向量個數時,矩陣才可對角化。 實對稱矩陣永遠滿足這條件,所以永遠可對角化。
複數特徵值的觀察與解讀#
theta = np.pi / 6
R = np.array([[np.cos(theta), -np.sin(theta)],
[np.sin(theta), np.cos(theta)]])
vals, vecs = np.linalg.eig(R)
print(vals)
# [0.8660254+0.5j 0.8660254-0.5j] —— 共軛成對出現
print(np.abs(vals)) # [1. 1.] 模長 = 1
print(np.angle(vals)) # [ 0.5236 -0.5236] = ±30°
複數特徵值永遠共軛成對( \(a \pm bi\) ),而且藏著兩個幾何訊息:
- 模長 \(|\lambda| = \sqrt{a^2 + b^2}\) :這個「旋轉」附帶的伸縮倍數。 旋轉矩陣的 \(|\lambda| = 1\) ,正好對應「旋轉不改變長度」
- 輻角 \(\arg(\lambda)\) :就是旋轉角 \(\theta\) 本身! \(2 \times 2\) 實矩陣若特徵值為 \(a \pm bi\) ,它在幾何上等價於 「伸縮 \(|\lambda|\) 倍 + 旋轉 \(\arg\lambda\) 」(這正是複數乘法的幾何意義)
# 一般化的「伸縮 + 旋轉」矩陣
r, theta = 1.5, np.pi / 3
B = r * np.array([[np.cos(theta), -np.sin(theta)],
[np.sin(theta), np.cos(theta)]])
vals = np.linalg.eigvals(B)
print(np.abs(vals), np.angle(vals)) # [1.5 1.5] [1.047 -1.047],完全吻合
這也解釋了為什麼需要複數:不是數學家故意刁難, 而是「旋轉」這個幾何動作本來就住在複數世界裡。
小結與練習#
本節重點#
- 手算流程: \(\det(A - \lambda I) = 0\) 求特徵值 → 代回解 \((A - \lambda I)\mathbf{v} = \mathbf{0}\) 求特徵向量
- 速算: \(\lambda_1 + \lambda_2 = \mathrm{tr}(A)\) 、 \(\lambda_1\lambda_2 = \det(A)\) ; 判別式 \(\mathrm{tr}^2 - 4\det\) 判斷實根或複根
np.linalg.eig回傳(eigvals, eigvecs),特徵向量按行存放、已單位化- 重根可能伴隨特徵向量不足(剪切矩陣),此矩陣不可對角化
- 複數特徵值共軛成對:模長 = 伸縮倍數、輻角 = 旋轉角
練習#
- 手算 \(A = \begin{bmatrix} 1 & 2 \\ 2 & 4 \end{bmatrix}\) 的特徵值 (提示: \(\det(A) = 0\) ,所以有一個 \(\lambda = 0\) ),並解出兩個特徵向量。
- 用跡與行列式速算驗證練習 1 的答案,再用
np.linalg.eig對照。 - 對 \(B = \begin{bmatrix} 0 & -1 \\ 1 & 0 \end{bmatrix}\) ( \(90°\) 旋轉) 計算特徵值,解讀模長與輻角。
- 寫一個函式
is_diagonalizable_2x2(A):用np.linalg.eig判斷 獨立特徵向量是否為 2 個(提示:np.linalg.matrix_rank(vecs) == 2), 分別用對角矩陣與剪切矩陣測試。 - 挑戰:證明實矩陣的複數特徵值必共軛成對 (提示:對 \(\det(A - \lambda I) = 0\) 取共軛,利用 \(A\) 是實矩陣)。