5.3 對角化與矩陣冪次#
本節目標#
- 理解 \(A = PDP^{-1}\) 的幾何意義:換到特徵基底下,變換只是單純的伸縮
- 掌握可對角化的條件與手算流程
- 學會 \(A^n = PD^nP^{-1}\) 這個「神器」,並用 NumPy 驗證
- 用
np.linalg.eig實作對角化,對照np.linalg.matrix_power - 知道什麼情況下對角化會失敗(Jordan 標準型預告)
幾何直覺:換一個好用的座標系#
第 1 章說過:矩陣就是座標系之間的翻譯官。同一個變換, 用不同的基底描述,難度天差地別。
\(A = \begin{bmatrix} 4 & 1 \\ 2 & 3 \end{bmatrix}\) 在標準基底下看起來 「亂七八糟」,但我們已經找到它的兩個特徵方向 \(\mathbf{v}_1 = \begin{bmatrix} 1 \\ 1 \end{bmatrix}\) (伸縮 5 倍)、 \(\mathbf{v}_2 = \begin{bmatrix} 1 \\ -2 \end{bmatrix}\) (伸縮 2 倍)。
如果改用 \(\mathbf{v}_1, \mathbf{v}_2\) 當基底,這個變換就變得無聊透頂: 沿 \(\mathbf{v}_1\) 拉 5 倍、沿 \(\mathbf{v}_2\) 拉 2 倍,僅此而已。 用矩陣語言說:在特徵基底下, \(A\) 變成對角矩陣——
把三個基底之間的翻譯串起來,就是本節的核心公式:
其中 \(P\) 的行是特徵向量: \(P = \begin{bmatrix} | & | \\ \mathbf{v}_1 & \mathbf{v}_2 \\ | & | \end{bmatrix}\) 。 讀這條式子的正確方式是從右往左:
- \(P^{-1}\) :把座標換到特徵基底
- \(D\) :在特徵基底上各自伸縮(超簡單!)
- \(P\) :換回標準基底
對角化的手算流程#
條件: \(n \times n\) 矩陣 \(A\) 可對角化 ⟺ \(A\) 有 \(n\) 個線性獨立的特徵向量。
流程(以 5.2 節的 \(A\) 為例):
- 求特徵值: \(\lambda = 5, 2\) (相異實根 → 一定可對角化)
- 解出特徵向量: \(\mathbf{v}_1 = \begin{bmatrix} 1 \\ 1 \end{bmatrix}\) 、 \(\mathbf{v}_2 = \begin{bmatrix} 1 \\ -2 \end{bmatrix}\)
- 組裝:
- 驗證 \(PDP^{-1} = A\) (或等價地 \(AP = PD\) ,手算時這個更好檢查)。
import numpy as np
A = np.array([[4.0, 1.0],
[2.0, 3.0]])
vals, P = np.linalg.eig(A)
D = np.diag(vals)
print(P @ D @ np.linalg.inv(P)) # 應還原出 A
print(np.allclose(P @ D @ np.linalg.inv(P), A)) # True
\(A^n = PD^nP^{-1}\) :對角化的真正威力#
為什麼費這麼大勁換座標?因為對角矩陣的冪次超好算—— 對角線各自乘 \(n\) 次方就好:
而中間的 \(P^{-1}P\) 會互相抵消:
複雜的矩陣連乘,瞬間化簡成「換座標 → 算 \(n\) 次方 → 換回來」。
對照實驗:算 \(A^{10}\) ,一路是 \(5^{10} \approx 9765625\) 這種大數字, 傳統矩陣乘法要跑 9 次矩陣乘法,對角化只要一次 \(D^{10}\) :
import numpy as np
A = np.array([[4.0, 1.0],
[2.0, 3.0]])
# 方法一:暴力連乘
A10_direct = np.linalg.matrix_power(A, 10)
# 方法二:對角化
vals, P = np.linalg.eig(A)
A10_diag = P @ np.diag(vals ** 10) @ np.linalg.inv(P)
print(np.allclose(A10_direct, A10_diag)) # True
print(A10_direct)
當 \(n\) 很大或矩陣很大時,差距更明顯: matrix_power 需要 \(O(\log n)\) 次矩陣乘法,每次是 \(O(n^3)\) ; 對角化路線則把問題降為純數字的 \(n\) 次方。 而且它給出閉式公式——例如 \((A^n)_{11}\) 是 \(\lambda_1^n\) 與 \(\lambda_2^n\) 的 線性組合,這正是下一節推 Fibonacci 通項公式的鑰匙。
不可對角化的例子#
回到 5.2 節的剪切矩陣 \(S = \begin{bmatrix} 1 & 1 \\ 0 & 1 \end{bmatrix}\) : 特徵值 \(\lambda = 1\) 是重根,但獨立特徵向量只有 \(\begin{bmatrix} 1 \\ 0 \end{bmatrix}\) 一個。 \(P\) 凑不出兩個獨立的行 → ** \(P\) 不可逆** → 對角化失敗。
S = np.array([[1.0, 1.0], [0.0, 1.0]])
vals, P = np.linalg.eig(S)
print(P) # 兩行幾乎相同
print(np.abs(np.linalg.det(P))) # ~ 0,P 不可逆!
# 硬要做的話會得到垃圾:
try:
print(P @ np.diag(vals) @ np.linalg.inv(P))
except np.linalg.LinAlgError as e:
print("對角化失敗:", e)
直覺上:剪切的「歪掉程度」無法只用兩個方向的伸縮表達—— 它還需要一個「微微傾倒」的動作。完整的描述需要 Jordan 標準型 (在對角線旁邊加 1 的準對角形式),那是更進階課程的主題; 本書遇到不可對角化的情況時,一律改用數值方法(如第 6 章的 SVD)處理。
好消息是:不可對角化是稀有事件。隨機抽一個矩陣,幾乎必可對角化; 實對稱矩陣更是永遠可對角化(而且特徵向量還能取成互相垂直,譜定理)。
實驗:驗證 \(PDP^{-1} = A\)#
import numpy as np
import linalg_viz as viz
rng = np.random.default_rng(42)
for k in range(5):
A = rng.integers(-4, 5, size=(2, 2)).astype(float)
vals, P = np.linalg.eig(A)
if np.linalg.matrix_rank(P) < 2:
print(f"實驗 {k}: A = {A.tolist()} 不可對角化(特徵向量不足),跳過")
continue
D = np.diag(vals)
A_back = P @ D @ np.linalg.inv(P)
ok = np.allclose(A_back, A)
print(f"實驗 {k}: A = {A.tolist()} 還原成功 = {ok}")
# 幾何驗證:特徵方向在變換下只伸縮
viz.plot_grid_transform(A)
viz.draw_eigenvectors(vals, P) # 特徵方向 = 不變的軸
viz.title(f"實驗 {k}: 特徵值 {np.round(vals, 2)}")
viz.show()
跑完五次實驗你會發現:只要 \(P\) 滿秩, \(PDP^{-1}\) 總是精準還原 \(A\) ; 偶爾撞上不可對角化的矩陣(例如恰好抽到剪切型)時, eig 回傳的兩行特徵向量會幾乎平行——那就是警訊。
小結與練習#
本節重點#
- \(A = PDP^{-1}\) :特徵基底下,變換只是各方向的伸縮; \(P\) 的行是特徵向量, \(D\) 的對角線是特徵值
- 可對角化 ⟺ 有 \(n\) 個線性獨立特徵向量(相異特徵值保證成立;重根可能不成立)
- \(A^n = PD^nP^{-1}\) :把矩陣冪次化為純數字冪次,並能導出閉式公式
- 剪切矩陣不可對角化;完整的理論需要 Jordan 標準型(本書點到為止)
- 實對稱矩陣永遠可對角化
練習#
- 對角化 \(A = \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix}\) (手算), 並用 NumPy 驗證 \(PDP^{-1} = A\) 。這個矩陣的幾何意義是什麼?
- 用 \(A^n = PD^nP^{-1}\) 手算練習 1 中 \(A^{2}\) 、 \(A^{3}\) , 你發現規律了嗎?(提示: \(A^2 = I\) 。)
- 寫函式
diagonalize(A):回傳(P, D, 可否對角化), 用np.linalg.matrix_rank判斷。測試 5 個隨機矩陣與剪切矩陣。 - 計算 \(\begin{bmatrix} 2 & 0 \\ 0 & 3 \end{bmatrix}^{100}\) 的對角線, 估算數量級(用
np.log10),體會冪次成長之快。 - 挑戰:證明若 \(A\mathbf{v} = \lambda\mathbf{v}\) ,則 \(A^n\mathbf{v} = \lambda^n\mathbf{v}\) , 並說明這與 \(A^n = PD^nP^{-1}\) 是同一件事的兩種講法。