6.2 行列式與反矩陣:解開方程組的鑰匙#
本節目標#
- 理解行列式的幾何意義:面積與體積的縮放倍率
- 學會用
det()計算行列式,並掌握「可逆 ⟺ det ≠ 0」 - 手算 \(2 \times 2\) 反矩陣,與 SymPy 的
inv()對照 - 用 Cramer 法則與
solve、linsolve解聯立方程組 - 認識矩陣的秩
rank(),並實驗 det = 0 時方程組的解數
行列式:面積的縮放倍率#
對一個 \(2 \times 2\) 矩陣
行列式不只是一道公式。把 \(A\) 想成一個線性變換:它把平面上以 \((1,0)\) 、 \((0,1)\) 為兩邊的單位正方形,變成以 \((a, c)\) 、 \((b, d)\) 為兩邊的平行四邊形。這個平行四邊形的面積恰好是 \(|ad - bc|\) 。
也就是說:** \(\det(A)\) 是這個變換對面積的縮放倍率**(帶正負號,負號代表翻轉)。三維時, \(\det(A)\) 是體積縮放倍率;更高維就是「超體積」倍率。
一個關鍵推論:如果 \(\det(A) = 0\) ,表示變換把空間「壓扁」了(正方形被壓成一條線或一點),資訊丟失,變換不可逆。
用 det() 計算行列式#
from sympy import Matrix
A = Matrix([[3, 1],
[2, 4]])
print(A.det()) # 3*4 - 1*2 = 10
行列式有兩個好用的性質(可以寫程式驗證):
- \(\det(AB) = \det(A)\det(B)\) :先 \(B\) 後 \(A\) 的縮放倍率,等於兩者倍率相乘
- \(\det(A^T) = \det(A)\)
from sympy import Matrix
A = Matrix([[1, 2], [3, 4]])
B = Matrix([[2, 0], [1, 3]])
print(A.det() * B.det()) # 10
print((A * B).det()) # 10,相等!
可逆條件與 inv()#
\(2 \times 2\) 矩陣的反矩陣有經典公式:
手算 \(A = \begin{pmatrix} 3 & 1 \\ 2 & 4 \end{pmatrix}\) : \(\det(A) = 10\) ,所以
用 SymPy 對照:
from sympy import Matrix
A = Matrix([[3, 1],
[2, 4]])
print(A.inv())
# Matrix([[2/5, -1/10], [-1/5, 3/10]])
驗證反矩陣的定義 \(A A^{-1} = A^{-1} A = I\) :
I2 = A * A.inv()
print(I2) # Matrix([[1, 0], [0, 1]])
print(A.inv() * A == I2) # True(這裡 I2 是單位矩陣)
當 \(\det(A) = 0\) 時,反矩陣不存在,inv() 會直接報錯:
S = Matrix([[1, 2],
[2, 4]])
print(S.det()) # 0
try:
S.inv()
except Exception as e:
print("出錯了:", e) # Matrix is not invertible (nonzero determinant?)...
用矩陣解聯立方程組#
有了反矩陣,方程組 \(A\mathbf{x} = \mathbf{b}\) 的解就是 \(\mathbf{x} = A^{-1}\mathbf{b}\) (當 \(\det(A) \neq 0\) 時)。
考慮
from sympy import Matrix
A = Matrix([[3, 1],
[2, 4]])
b = Matrix([9, 16])
print(A.inv() * b) # Matrix([[2], [3]]),即 x=2, y=3
更推薦的寫法是直接用矩陣的 solve 方法(不需要真的算反矩陣,計算更快也更穩定):
print(A.solve(b)) # Matrix([[2], [3]])
也可以用第 2 章介紹過的 linsolve(線性方程組求解器):
from sympy import linsolve, symbols
x, y = symbols('x y')
sol = linsolve([3*x + y - 9, 2*x + 4*y - 16], (x, y))
print(sol) # {(2, 3)}
三種方法殊途同歸,但 A.solve(b) 最能凸顯「矩陣方程」的觀點。
Cramer 法則:用行列式解方程組#
Cramer 法則說:當 \(\det(A) \neq 0\) 時,方程組 \(A\mathbf{x} = \mathbf{b}\) 的第 \(i\) 個未知數,是把 \(A\) 的**第 \(i\) 行換成 \(\mathbf{b}\) ** 後的行列式除以 \(\det(A)\) :
以 \(\begin{cases} 3x + y = 9 \\ 2x + 4y = 16 \end{cases}\) 為例:
用 SymPy 完整實作:
from sympy import Matrix
A = Matrix([[3, 1],
[2, 4]])
b = Matrix([9, 16])
A1 = A.copy(); A1[:, 0] = b # 把第 1 行換成 b
A2 = A.copy(); A2[:, 1] = b # 把第 2 行換成 b
x = A1.det() / A.det()
y = A2.det() / A.det()
print(x, y) # 2 3
# 與 solve 的結果對照
from sympy import solve, symbols
xs, ys = symbols('x y')
print(solve([3*xs + ys - 9, 2*xs + 4*ys - 16], (xs, ys))) # {x: 2, y: 3}
Cramer 法則計算量大、實務上不常用,但它把「解」完全用行列式表達出來,理論上非常漂亮。
矩陣的秩:rank()#
秩(rank)是矩陣中「真正獨立的列(或行)」的數量。它告訴我們方程組真正的資訊量:
from sympy import Matrix
A = Matrix([[1, 2],
[2, 4]])
print(A.rank()) # 1:兩列成比例,只有 1 列是獨立的
B = Matrix([[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
print(B.rank()) # 3:滿秩
對 \(n \times n\) 方陣,有一條美麗的等價關係鏈:
動手實驗:det = 0 時,方程組何時有無窮多解?#
當 \(\det(A) = 0\) ,方程組要嘛無解、要嘛有無窮多解——但什麼時候是哪一種?讓我們做實驗。
from sympy import Matrix
# 情況一:無窮多解
# x + 2y = 3 和 2x + 4y = 6 是同一條方程(第二條是第一條的兩倍)
A1 = Matrix([[1, 2],
[2, 4]])
b1 = Matrix([3, 6])
print(A1.det(), A1.rank()) # 0 1
print(A1.rank(), Matrix.hstack(A1, b1).rank()) # 1 1,秩相等 → 有解
print(A1.solve(b1)) # Matrix([[3 - 2*t], [t]]),含自由參數 t 的無窮多解
# 情況二:無解
# x + 2y = 3 和 2x + 4y = 7:兩條「平行」的方程
b2 = Matrix([3, 7])
print(A1.rank(), Matrix.hstack(A1, b2).rank()) # 1 2,增廣矩陣秩更大 → 無解
try:
A1.solve(b2)
except Exception as e:
print("無解:", e)
實驗結論可以用秩寫成判別法:
- \(\operatorname{rank}(A) = \operatorname{rank}([A|\mathbf{b}]) = n\) :唯一解
- \(\operatorname{rank}(A) = \operatorname{rank}([A|\mathbf{b}]) < n\) :無窮多解
- \(\operatorname{rank}(A) < \operatorname{rank}([A|\mathbf{b}])\) :無解
再做一個延伸實驗,掃描不同的 \(\mathbf{b}\) ,觀察解數的變化:
from sympy import Matrix
A = Matrix([[1, 2],
[2, 4]])
for k in range(4, 9):
b = Matrix([3, k])
try:
sol = A.solve(b)
print(f"b = (3, {k}):有無窮多解,例如 {sol.subs('t', 0).T}")
except Exception:
print(f"b = (3, {k}):無解")
你會發現只有 \(k = 6\) (即 \(\mathbf{b}\) 落在被壓扁後那條線上)時才有解——這正是「det = 0 把空間壓扁」的幾何真相:方程組有解 ⟺ \(\mathbf{b}\) 沒被壓扁丟掉。
小結與練習#
本節重點:
- \(\det(A)\) 是線性變換對(超)體積的縮放倍率; \(\det = 0\) 代表空間被壓扁
- 可逆 ⟺ \(\det \neq 0\) ⟺ 滿秩 ⟺ 方程組有唯一解
- \(2 \times 2\) 反矩陣公式 \(A^{-1} = \frac{1}{ad-bc}\begin{pmatrix} d & -b \\ -c & a \end{pmatrix}\) ;SymPy 用
inv() - 解方程組:
A.solve(b)、linsolve、Cramer 法則三種途徑 - 秩判別法: \(\operatorname{rank}(A)\) 與 \(\operatorname{rank}([A|\mathbf{b}])\) 的比較決定解數
練習:
- 計算 \(A = \begin{pmatrix} 2 & 7 \\ 1 & 4 \end{pmatrix}\) 的行列式與反矩陣,先手算再對照
inv()。 - 用三種方法(
A.solve(b)、linsolve、Cramer 法則)解 \(\begin{cases} 2x - y = 0 \\ x + 3y = 7 \end{cases}\) ,確認答案一致。 - 驗證 \(\det(AB) = \det(A)\det(B)\) :任取兩個 \(3 \times 3\) 矩陣檢查。
- 構造一個 \(3 \times 3\) 的矩陣 \(A\) ,使得 \(\det(A) = 0\) 但 \(A\) 不是零矩陣,並求出 \(\operatorname{rank}(A)\) 。
- 對 \(A = \begin{pmatrix} 1 & 2 \\ 2 & 4 \end{pmatrix}\) ,找出所有使方程組 \(A\mathbf{x} = \mathbf{b}\) 恰好有無窮多解的 \(\mathbf{b} = (3, k)^T\) 中的 \(k\) ,並用幾何語言(壓扁、直線)解釋原因。