第 10 章 逆矩阵
学习目标
- 理解逆矩阵的定义与几何意义(逆变换)
- 推导二阶逆矩阵公式,记住可逆条件
- 掌握高斯-约当消元求逆的原理与步骤
- 会用逆矩阵解线性方程组
- 会用 NumPy 与 PyTorch 求逆矩阵,并能识别奇异矩阵
10.1 从数的倒数到矩阵的逆
数的世界里,每个非零数 都有倒数 ,满足
矩阵的世界里,扮演「1」这个角色的,是单位矩阵 (第 7 章验证过:)。
逆矩阵:若 是 阶方阵,存在 阶方阵 满足
则称 可逆, 叫 的逆矩阵。不存在逆矩阵的方阵叫奇异矩阵。
几何意义:矩阵是变换,逆矩阵就是逆变换。旋转 90° 的矩阵,逆矩阵是旋转 ;拉伸 2 倍的矩阵,逆矩阵是压缩到一半。先变换再逆变换,等于什么都没做():

10.2 二阶逆矩阵公式:一步一步推导
import matplotlib.pyplot as plt
from matplotlib import font_manager
for f in font_manager.findSystemFonts():
if any(k in f for k in ("NotoSansCJK", "NotoSansSC", "wqy", "SimHei", "msyh", "PingFang")):
font_manager.fontManager.addfont(f)
plt.rcParams["font.sans-serif"] = ["Noto Sans CJK SC", "WenQuanYi Zen Hei", "SimHei", "Microsoft YaHei", "PingFang SC"]
plt.rcParams["axes.unicode_minus"] = False
import numpy as np
A = np.array([[1.0, 0.5],
[0.0, 1.0]]) # 剪切变换
square = np.array([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0], [0.0, 0.0]])
fig, axes = plt.subplots(1, 3, figsize=(14, 4.5))
def draw(ax, pts, title, color):
ax.plot(pts[:, 0], pts[:, 1], color=color, linewidth=2)
ax.fill(pts[:, 0], pts[:, 1], color=color, alpha=0.15)
ax.axhline(0, color="black", linewidth=1)
ax.axvline(0, color="black", linewidth=1)
ax.set_xlim(-1, 2.6)
ax.set_ylim(-0.5, 2.2)
ax.set_aspect("equal")
ax.grid(True, linestyle=":", alpha=0.5)
ax.set_title(title)
draw(axes[0], square, "原图", "tab:blue")
draw(axes[1], square @ A.T, "A 变换后", "tab:red")
draw(axes[2], square @ A.T @ np.linalg.inv(A).T, "A⁻¹ 还原", "tab:green")
fig.savefig("book/public/figs/fig10-inverse.png", dpi=120, bbox_inches="tight")
plt.close(fig)设
假设逆矩阵存在,设 。条件 写成 4 个方程:
逐元素展开,先看第一列:
由第二个方程 ( 时),代入第一个方程:
于是 。再看第二列,同理得到:
把结果收拢:
其中 正是 。所以:
口诀:主对角线互换(),副对角线变号( 加负号),整体除以行列式。行列式为 0 时公式无意义——这就是「 时不可逆」的代数来源。
验证:,,所以
import numpy as np
A = np.array([[1.0, 2.0],
[3.0, 4.0]])
det = A[0, 0] * A[1, 1] - A[0, 1] * A[1, 0]
inv = (1 / det) * np.array([[A[1, 1], -A[0, 1]],
[-A[1, 0], A[0, 0]]])
print("手推公式:", inv)
print("np.linalg.inv:", np.linalg.inv(A))
print("A @ inv = I?", np.allclose(A @ inv, np.eye(2)))运行输出:
手推公式: [[-2. 1. ]
[ 1.5 -0.5]]
np.linalg.inv: [[-2. 1. ]
[ 1.5 -0.5]]
A @ inv = I? True10.3 高斯-约当消元:对任意阶矩阵求逆
公式只适合二阶(三阶的伴随公式极其繁琐)。通用办法是高斯-约当消元:把 和单位矩阵并排写在一起,
然后用行初等变换,把左边变成单位矩阵——右边同时变成的就是 :
为什么有效?每做一次行初等变换,都相当于给整个矩阵(左右两边)左乘一个初等矩阵 。假设一共做了 次,左边变成:
那么乘积 就是 (因为 ),而它恰好作用在了右边的 上:
用代码实现,并顺手解决第 8 章留的「主元为 0 换行」问题:
import numpy as np
def invert_gauss_jordan(A):
"""用高斯-约当消元求方阵的逆;不可逆时抛出异常"""
n = A.shape[0]
M = np.array(A, dtype=float)
I = np.eye(n)
for col in range(n):
pivot = col + np.argmax(np.abs(M[col:, col]))
if M[pivot, col] == 0:
raise np.linalg.LinAlgError("矩阵不可逆")
M[[col, pivot]] = M[[pivot, col]]
I[[col, pivot]] = I[[pivot, col]]
# 把主元化为 1
factor = M[col, col]
M[col] /= factor
I[col] /= factor
# 消去其他行的这一列
for row in range(n):
if row != col:
f = M[row, col]
M[row] -= f * M[col]
I[row] -= f * I[col]
return I
A = np.array([[2.0, 1.0, 0.0],
[1.0, 3.0, 1.0],
[0.0, 1.0, 2.0]])
inv = invert_gauss_jordan(A)
print("高斯-约当求逆:\n", inv)
print("与库一致?", np.allclose(inv, np.linalg.inv(A)))
print("A @ A⁻¹ = I?", np.allclose(A @ inv, np.eye(3)))运行输出:
高斯-约当求逆:
[[ 0.625 -0.25 0.125]
[-0.25 0.5 -0.25 ]
[ 0.125 -0.25 0.625]]
与库一致? True
A @ A⁻¹ = I? True10.4 用逆矩阵解方程组
方程 两边同时左乘 :
鸡兔同笼的矩阵形式 、:
import numpy as np
A = np.array([[1.0, 1.0],
[2.0, 4.0]])
b = np.array([35.0, 94.0])
x = np.linalg.inv(A) @ b
print("用逆矩阵解:", x)
print("直接 solve:", np.linalg.solve(A, b))运行输出:
用逆矩阵解: [23. 12.]
直接 solve: [23. 12.]实践上,解方程组通常直接用高斯消元(np.linalg.solve)而不是先求逆——求逆本身就要解 组方程组,更慢、误差更大。但「 的解是 」这个关系是理论基石,务必理解。
10.5 不可逆的情况
奇异矩阵(行列式为 0)求逆会报错:
# 预期错误:LinAlgError
import numpy as np
A = np.array([[1.0, 2.0],
[2.0, 4.0]]) # 两行成比例,det = 0
print(np.linalg.inv(A))报错信息是 LinAlgError: Singular matrix——矩阵是奇异的,没有逆。这和第 9 章的等价链完全一致: ⟺ 列相关 ⟺ 变换压扁空间 ⟺ 不可逆。
PyTorch 求逆:
import torch
A = torch.tensor([[1.0, 2.0],
[3.0, 4.0]])
inv = torch.linalg.inv(A)
print("torch A⁻¹:\n", inv)
print("验证 A @ A⁻¹:\n", A @ inv)运行输出:
torch A⁻¹:
tensor([[-2.0000, 1.0000],
[ 1.5000, -0.5000]])
验证 A @ A⁻¹:
tensor([[ 1.0000e+00, 0.0000e+00],
[-4.7684e-07, 1.0000e+00]])验证结果里出现 这样的极小值,是浮点舍入误差;它约等于 0,说明 确实是单位矩阵。判断是否为单位矩阵时用 torch.allclose(A @ inv, torch.eye(2)) 更可靠。
动手实践
- 用公式求 的逆,验证 ,再用
np.linalg.inv对比。 - 判断 、 是否可逆,说明理由。
- 用 10.3 的
invert_gauss_jordan求一个 3×3 对角矩阵的逆,观察结果有什么规律。 - 用逆矩阵解 ,写出 与 的每一步。
- 给
np.linalg.inv一个奇异矩阵,记录并解读报错信息。
常见错误
| 错误写法/理解 | 原因 |
|---|---|
| 把逆矩阵写成「每个元素取倒数」 | 逆矩阵是「矩阵整体求逆」,不是逐元素求倒数; 这类对角矩阵才恰好是逐元素倒数 |
| 忘了除以 | 公式里 必不可少,它是整个矩阵的缩放因子 |
| 认为所有方阵都有逆 | 只有 的方阵可逆;奇异矩阵没有逆 |
| 把 写成 | 矩阵乘法不交换,必须左乘: |
| 混淆「求逆」与「转置」 | 是逆矩阵, 是转置,一般不同 |
章末练习
基础
- 用公式求下列矩阵的逆,并验证 :
- 判断下列矩阵是否可逆:、。
- 用
np.linalg.inv验证第 1 题的结果。
提高
- 用逆矩阵解方程组写出 与最终解的完整步骤。
- 证明:若 可逆,则 ;若 、 都可逆,则 。提示:后者验证 ,注意交换顺序。
挑战
- 二阶矩阵 的逆公式,用高斯-约当消元重新推导一遍,并与 10.2 的结论对照。
- 若 可逆且 ,证明解唯一:假设还有 满足方程,推出 。
章末自测
- 的逆是?
- A.
- B.
- C.
- D. 不存在
- 矩阵 可逆的充要条件是?
- A.
- B.
- C. 是对称矩阵
- D. 的元素都非零
- A.
- B.
- C.
- D.
- 奇异矩阵是?
- A. 行列式为 0 的矩阵
- B. 有逆的矩阵
- C. 单位矩阵
- D. 对角矩阵
- 用逆矩阵解 ,正确的是?
- A.
- B.
- C.
- D.
- 高斯-约当求逆中,竖线右边最初放的是?
- A.
- B.
- C.
- D. 零矩阵
- 若 ,则 ?
- A. 不可逆
- B. 可逆
- C. 是零矩阵
- D. 是单位矩阵
- 下列哪个矩阵不可逆?
- A.
- B.
- C.
- D.
- (A、B 可逆)
- A.
- B.
- C.
- D.
- 实际解大型方程组时,推荐的做法是?
- A. 先求逆再乘
- B. 直接高斯消元(
np.linalg.solve) - C. 逐元素取倒数
- D. 转置再求逆
