Skip to content

线性方程组与秩:有没有解,解有几个

WARNING

🧪 Beta公测版本提示:教程主体已完成,正在优化细节,欢迎大家提Issue反馈问题或建议。

上一章把矩阵看成「捏空间」。这一章问更硬的一句:给定 Ab,方程 Ax=b 有没有解? 几何上是「直线 / 平面交不交」;代数上是「b 能不能写成 A 的各列的线性组合」。学完应能读懂最小二乘为何要写成 AAx^=Ab,以及「秩亏」为什么让训练炸掉。前置:线性代数直觉


一、Ax=b 三种结局

把两元方程看成平面上的直线 ax+by=c

几何代数
两线交于一点唯一解rank(A)=rank([Ab])=n
两线平行无解rank(A)<rank([Ab])
两线重合无穷多解rank(A)=rank([Ab])<n

n 是未知数个数。增广矩阵 [Ab]A 多一列 b:如果 b 带来了新的独立方向,方程互相打架。

Ax=b:交点、平行、重合

图解说明:左是唯一交点;中是平行无交;右把故事抬到三维(三张平面)。底栏那句话是列空间语言:列的线性组合能不能拼出 b

列空间 Col(A) 就是所有 Ax 能到达的点。有解 bCol(A)rank(A) 是列空间的维数,也等于非零行数(消元之后)。

保姆级数字例(与 demo.py 三组直线相同)。 未知数 n=2

  1. 唯一解。 x+y=2xy=0。两线斜率 $ -1$ 与 +1,交于 (1,1)。矩阵A=(1111),rank(A)=rank([Ab])=2.
  2. 无解。 x+y=2x+y=3。平行,永远差 1rank(A)=1,但增广矩阵第二行变成 [0 01],秩变成 2
  3. 无穷多解。 x+y=22x+2y=4。第二行是第一行的两倍,同一条直线。rank=1<2,自由未知数一个:令 x=t,则 y=2t

卡点。 「方程个数 = 未知数个数」既不保证有解,也不保证唯一。三张平行平面是三个方程两个……不对,三维里三张平面仍可能无交。真正起决定作用的是秩,不是「几个式子」。另一个卡点:浮点里几乎看不到「精确平行」,两条几乎平行的线会交出一个很远、对扰动极敏感的点——这就是病态。

逐步推导:三组直线怎样从秩读出唯一解 / 无解 / 无穷解(点击展开)

把直线 ax+by=c 写成一行 [a bc]

唯一。 两行 [1 12][1 10]。消元:第二行减第一行得 [0 22],于是 y=1,回代 x=1。两行都非零且不平行,rank=2=n

平行。 [1 12][1 13]。消元后第二行 [0 01]——左边全 0、右边 1,即 0=1A 的两行成比例,秩 1;多出来的 b 列让增广秩变成 2。列空间语言:A 的两列张成同一条直线(列 =(1,1) 的倍数),b=(2,3) 不在这条线上。

重合。 [1 12][2 24]。第二行 =2× 第一行,消元后整行变 0rank(A)=rank([Ab])=1<2。解集是一条直线,不是一个点。

一般判据(Rouché–Capelli):Ax=b 有解 rank(A)=rank([Ab]);有解时,自由未知数个数 =nrank(A)

两条直线的三种结局

图解说明:左交于橙点 (1,1);中平行;右两条线画成一条(虚线叠在实线上)。


二、高斯消元在干什么

把第 j 列的主元变成 1,再用它把同列其他行削成 0。部分主元(选绝对值最大的行对调)避免除以接近 0 的数。走完若主元全在,就得到唯一解;某列扫不到主元,秩就掉一档。

三维教科书例子(demo 与 gauss.hpp 同一组):

(211312212)(xyz)=(8113)(x,y,z)=(2,3,1).

demo.pygauss_solvegauss.hpp 写的是同一套循环。对照 numpy.linalg.solve 只为验算,不是再学一个黑盒。

最小二乘是「b 不在列空间里」时的退路:把 b 正交投影到 Col(A) 上再解。正规方程 AAx^=Ab 正是在投。线性回归见 线性回归

卡点。 主元接近 0 时,这一列几乎已经被前面的列表示了,继续除会把舍入误差放大到爆炸——部分主元能救命,但不能把病态矩阵变好。条件数大的意思是:b 动一点点,x 跑很远。训练里相关特征(两列几乎成比例)就是离散版的这件事。

逐步推导:3×3 消元走到 (2,3,1),以及正规方程从哪来(点击展开)

增广矩阵:

[2118312112123].

第一列主元 2R2R2+32R1R3R3+R1

[211801/21/210215].

第二列选 1/2(若做部分主元会与第三行对调,因为 |2|>|1/2|;手算沿用当前顺序,结果相同)。R3R34R2

[211801/21/210011].

回代:z=1z=1。第二行 12y+12(1)=1y=3。第一行 2x+3(1)=82x=4x=2。残差 Axb 在精确算术下为 0;浮点里应是机器精度量级,demo 会打印这个范数。

相关矩阵掉一档。 demo 第二张

B=(123246111)

第二行 =2× 第一行,所以 rank(B)=2(第三行与第一行独立)。numerical_rank 数大于阈值的奇异值个数:浮点里「精确相关」几乎不出现,要用阈值。练习就是在数这个个数。

最小二乘。bCol(A),没有 x 使 Ax=b。改成最小化 Axb22。令 f(x)=Axb2=(Axb)(Axb),梯度

f=2A(Axb).

令梯度为 0AAx^=Ab。几何:误差 bAx^ 必须垂直于每一列,也就是垂直于 Col(A)——投影的定义。AA 可逆当且仅当 A 列满秩;列相关时正规方程本身秩亏,要改用伪逆 / SVD / 岭回归(对角加 λI)。


三、秩、自由未知数、病态

  • 满秩方阵:可逆,唯一解。
  • 行线性相关(例如第二行是第一行的两倍):rank<n,要么无解要么自由变量。
  • 数值秩:奇异值大于阈值的个数。浮点里「精确相关」几乎不出现,要用阈值。练习就是在数这个个数。
  • 条件数大:解对 b 的扰动过敏。上一章提过名字,这里会在消元里碰到「主元特别小」。

自由未知数个数 =nrank(A)(在有解的前提下)。能控性、可观测性矩阵是否满秩,问的也是这件事,见 状态空间


四、代码在做什么

Python 画三组直线,并对手写 3×3 消元与 NumPy 对答案。C++ gauss.hpp 印同一组解 (2,3,1),以及一个秩为 2 的相关矩阵 B

两条直线的三种结局

编译:

bash
cd docs/math/systems/code
python demo.py
g++ -std=c++17 demo.cpp -o systems_demo

Windows 直接跑 systems_demo.exe。不要链 Eigen。


五、小结

概念一句话
Ax=bb 是否在列空间里
独立列(或行)的个数
高斯消元用主元清列,读出解或秩
增广矩阵多看 b 这一列,判断有没有打架
正规方程AAx^=Ab:把 b 投影到列空间
下游最小二乘、可观测性、特征值

下一章 特征值与二次型:不解 Ax=b,改为找「只被拉伸的方向」。

📥 Code

FileViewDownload
demo.pyOpenDownload
gauss.hppDownload
demo.cppDownload
exercise.pyOpenDownload

参考

  1. Strang, G. Introduction to Linear Algebra(列空间与消元)
  2. Trefethen & Bau, Numerical Linear Algebra(主元与条件数)