上一章说解方程组的解有三种情况,怎么判断?答案藏在行列式和逆矩阵里。本章讲这两个概念,以及它们和"可逆""唯一解"的关系。
19.1 逆矩阵:矩阵的"倒数"
实数里,5 的倒数是 1/5,因为 5 × (1/5) = 1。
矩阵也有类似的"倒数",叫逆矩阵,记作 A⁻¹:
A × A⁻¹ = I (I 是单位矩阵)A 的逆矩阵 A⁻¹ 满足:A 乘 A⁻¹ 等于单位矩阵(矩阵世界里的"1")。
用逆矩阵解方程
如果 A 有逆矩阵,那么 Ax = b 的解是:
x = A⁻¹ · b因为:A⁻¹·(A·x) = A⁻¹·b → (A⁻¹·A)·x = A⁻¹·b → I·x = A⁻¹·b → x = A⁻¹·b。
但注意:虽然数学上对,工程上不建议用
A.inverse() * b解方程(慢且数值不稳定)。Eigen 里用A.分解().solve(b)更优。逆矩阵更多用于"理解概念"。
19.2 行列式:一个数,描述矩阵的"缩放倍数"
每个方阵都有一个行列式(determinant),记作 det(A) 或 |A|,它是一个数。
行列式的几何意义(以 2×2 为例):矩阵表示的变换,把面积放大/缩小了多少倍。
2×2 矩阵的行列式公式:
det([ a b ]) = a×d - b×c ([ c d ])例:det([1 2; 3 4]) = 1×4 - 2×3 = 4 - 6 = -2。
行列式 = 0 意味着什么
det(A) = 0 时,矩阵 A 不可逆(叫奇异矩阵)。这时:
- 方程组无解或无穷多解(没有唯一解)
- 矩阵的变换把空间"压扁"了(面积/体积变成 0)
det(A) ≠ 0 时,A 可逆,方程组有唯一解。
这就是判断方程组有没有唯一解的关键:看行列式是否为 0。这是数学上的判据;到了代码里怎么落地(以及为什么不能直接写
det == 0),19.4 会说。
19.3 判断可逆、求解
#include<Eigen/Dense>#include<iostream>intmain(){Eigen::Matrix2d A;A<<2,1,1,3;// 行列式doubledet=A.determinant();std::cout<<"det(A) = "<<det<<std::endl;// 5 ≠ 0,可逆// 逆矩阵Eigen::Matrix2d Ainv=A.inverse();std::cout<<"A^{-1} =\n"<<Ainv<<"\n\n";// 验证 A * A^{-1} = Istd::cout<<"A * A^{-1} =\n"<<A*Ainv<<"\n\n";return0;}存成ch19.cpp,按附录 C.3 编译运行,实际输出:
det(A) = 5 A^{-1} = 0.6 -0.2 -0.2 0.4 A * A^{-1} = 1 0 0 1det(A) = 5不为 0,所以可逆;A * A^{-1}打印出来正好是单位矩阵。有些矩阵相乘回去会得到1 1e-16这种带浮点残渣的结果,那是正常现象(见第 21 章末尾的说明),看的是"接近不等于"。
19.4 矩阵的秩(rank)
秩(rank)是另一个重要概念:矩阵"真正包含多少独立信息",等于它线性无关的行(或列)的最大个数。
- 满秩方阵(rank = 阶数):可逆,方程组有唯一解
- 秩不足:不可逆,信息有冗余
Eigen::MatrixXdA(3,3);A<<1,2,3,4,5,6,7,8,9;// 第 3 行 = 2×第2行 - 第1行,线性相关,秩不足Eigen::FullPivLU<Eigen::Matrix3d>lu(A);std::cout<<"rank = "<<lu.rank()<<std::endl;// 2,不是 3std::cout<<"det = "<<A.determinant()<<std::endl;// 打印 6.66134e-16,不是 0,见下面说明这个矩阵数学上的行列式是 0,秩是 2(不满秩),所以不可逆。
⚠ 但代码里别写
if (det == 0)(实测 Eigen 5.0 + g++ 16.1):上面这段跑出来的其实是rank = 2 det = 6.66134e-16
rank()给的 2 是准确的;determinant()给的不是 0,而是6.66134e-16这种浮点残渣——机器精度的正常产物,原因见第 21 章末尾的说明。所以工程上判断"奇异/接近奇异"要用秩(lu.rank() < 矩阵阶数)或者带容差的比较(std::abs(det) < 1e-12),绝不能直接和 0 比相等。本书第 29 章 29.5 给出的检查写法就是这种带容差的比较,第 30 章则用分解对象的info()和rank()判断成败——都不是拿行列式和 0 比相等。
19.5 概念关系总结
| 概念 | 含义 | 关系 |
|---|---|---|
| 行列式 det(A) | 变换的面积/体积缩放倍数 | =0 则不可逆 |
| 逆矩阵 A⁻¹ | 矩阵的"倒数" | 存在 ⟺ det≠0 |
| 秩 rank(A) | 独立信息的数量 | 满秩 ⟺ 可逆 |
| 唯一解 | 方程组恰有一解 | ⟺ 可逆 |
一句话记忆:det ≠ 0 ⟺ 满秩 ⟺ 可逆 ⟺ 方程组有唯一解。
19.6 小结
- 逆矩阵 A⁻¹ 满足 A·A⁻¹ = I,是矩阵的"倒数"。
- 行列式 det(A) 描述变换的缩放倍数;=0 则不可逆。
- 秩 rank 描述独立信息量;满秩才可逆。
- 可逆 ⟺ det≠0 ⟺ 满秩 ⟺ 唯一解。
- 代码里判断奇异用
rank()或带容差的比较,别写det == 0(实测会给你6.66134e-16)。 - 解方程用
.solve(),别用.inverse()硬乘。
下一章,学习特征值与特征向量——矩阵的"指纹"。
练习题
- 计算 2×2 矩阵 [3 1; 1 2] 的行列式,判断是否可逆。
- 用 Eigen 求该矩阵的逆矩阵,验证 A·A⁻¹ = I。
- 求一个行列式为 0 的矩阵(提示:让两行成比例),验证它不可逆。做完留意
determinant()实际打印的数——它通常不是 0,见 19.4 的说明。 - 用自己的话说说行列式和秩分别描述了矩阵的什么。
- 为什么解方程推荐用
.solve()而不是.inverse() * b?