视频加载失败

18.06 第 9 讲:线性无关、基与维数

4805 字
24 分钟
18.06 第 9 讲:线性无关、基与维数
  1. 118.06 第 1 讲:方程组的行图与列图
  2. 218.06 第 2 讲:用矩阵做消元
  3. 318.06 第 3 讲:矩阵乘法的四种看法与逆矩阵
  4. 418.06 第 4 讲:分解成 A = LU
  5. 518.06 第 5 讲:转置、置换与向量空间
  6. 618.06 第 6 讲:列空间与零空间
  7. 718.06 第 7 讲:解 Ax = 0,主变量与特解
  8. 818.06 第 8 讲:解 Ax = b,行最简形 R
  9. 918.06 第 9 讲:线性无关、基与维数本文
  10. 1018.06 第 10 讲:四个基本子空间
  11. 1118.06 第 11 讲:矩阵空间、秩 1 矩阵与小世界图
  12. 1218.06 第 12 讲:图、网络与关联矩阵
  13. 1318.06 第 13 讲:第一次测验复习
  14. 1418.06 第 14 讲:正交向量与正交子空间
  15. 1518.06 第 15 讲:投影到子空间
  16. 1618.06 第 16 讲:投影矩阵与最小二乘
  17. 1718.06 第 17 讲:正交矩阵与 Gram-Schmidt
  18. 1818.06 第 18 讲:行列式的性质
  19. 1918.06 第 19 讲:行列式公式与代数余子式
  20. 2018.06 第 20 讲:Cramer 法则、逆矩阵与体积
  21. 2118.06 第 21 讲:特征值与特征向量
  22. 2218.06 第 22 讲:对角化与矩阵的幂
  23. 2318.06 第 23 讲:微分方程与 exp(At)
  24. 2418.06 第 24 讲:Markov 矩阵与 Fourier 级数
  25. 2518.06 第 24b 讲:第二次测验复习
  26. 2618.06 第 25 讲:对称矩阵与正定性
  27. 2718.06 第 26 讲:复矩阵与快速 Fourier 变换
  28. 2818.06 第 27 讲:正定矩阵与极小值
  29. 2918.06 第 28 讲:相似矩阵与 Jordan 标准形
  30. 3018.06 第 29 讲:奇异值分解
  31. 3118.06 第 30 讲:线性变换及其矩阵
  32. 3218.06 第 31 讲:基变换与图像压缩
  33. 3318.06 第 32 讲:第三次测验复习
  34. 3418.06 第 33 讲:左逆、右逆与伪逆
  35. 3518.06 第 34 讲:期末复习

这一讲 Strang 给四个词下了定义:线性无关、张成、基、维数。我把四个词都翻译成了同一个操作:把向量放进矩阵的列,算秩,找零空间。固定种子取 1000 个随机的 100 × 100 矩阵,1000 个全是满秩,也就是“随机向量几乎总是无关”;而在另一头,我人为造了一组只差 10−1210^{-12} 的相关向量,matrix_rank 判它们是秩 3,也就是“无关”。这两个数字合起来,就是这一讲的数学定义和浮点数之间的距离。

本讲速览

视频:Lecture 9: Independence, basis, and dimension(OCW 页面与字幕) 教材:《Introduction to Linear Algebra》第 6 版 §3.4 Independence, Basis, and Dimension 前置:第 8 讲:解 Ax = b,行最简形 R 一句话:把向量放进矩阵的列,它们无关当且仅当零空间只有零向量;列空间的维数是秩 rr,零空间的维数是 n−rn - r。

配合视频
  • 开头他先回顾“未知数比方程多,零空间里一定有非零向量”,这一段是整讲的伏笔,值得认真听。
  • 讲无关的那一段(v\mathbf{v} 和 2v2\mathbf{v}、含零向量、平面里的三个向量)很短,本篇第一节已经用代码算过,可以倍速。
  • 他在黑板上反复追问“给我另一组基”,那一段看一遍就行,本篇第二、三节有对应的代码。
  • 最后三分钟是零空间的维数,两个特解就是零空间的基,这是下一讲的预告,别漏。

线性无关:看零空间#

他先说了一条上一讲留下的事实:AA 是 m×nm \times n 的矩阵,如果 n>mn > m(未知数比方程多),那么 Ax=0A\mathbf{x} = \mathbf{0} 一定有非零解。理由是消元之后主元最多 mm 个,至少剩下 n−mn - m 个自由变量,自由变量可以随便取 1,再回代解出主变量。

线性无关是什么? 一堆向量 x1,…,xn\mathbf{x}_1, \dots, \mathbf{x}_n,如果

c1x1+c2x2+⋯+cnxn=0c_1 \mathbf{x}_1 + c_2 \mathbf{x}_2 + \cdots + c_n \mathbf{x}_n = \mathbf{0}

除了所有 cic_i 都是 0 之外别无解,它们就线性无关;若还有别的 cc 能凑出零向量,它们就线性相关。他特地强调:说的是“一堆向量”无关,不说“一个矩阵”无关。

接着他举了三个例子:v\mathbf{v} 和 2v2\mathbf{v}(两份第一个减去第二个就是零,相关)、v\mathbf{v} 和零向量(零向量那一份随便取几都行,“只要里面有零向量,无关就死了”)、平面里的三个向量(必然相关)。第三个例子里他是这样看的:把三个向量放进 AA 的三列,AA 是 2×32 \times 3,列比行多,零空间里一定有非零的 c\mathbf{c},这个 c\mathbf{c} 就是“往 v1\mathbf{v}_1 走几步,往 v2\mathbf{v}_2 走几步,再往 v3\mathbf{v}_3 退几步,回到原点”。

这一下就把定义翻译成了矩阵语言:

  • 列无关   ⟺  \iff N(A)={0}N(A) = \{\mathbf{0}\}   ⟺  \iff 没有自由变量   ⟺  \iff 秩 r=nr = n。
  • 列相关   ⟺  \iff 零空间里有非零向量   ⟺  \iff 有自由变量   ⟺  \iff r<nr < n。

我按字幕里他随手画的数取 v1=(2,1)\mathbf{v}_1 = (2, 1)、v2=(1,2)\mathbf{v}_2 = (1, 2)、v3=(2.5,−1)\mathbf{v}_3 = (2.5, -1)(字幕是语音转写,“two and a half, minus one”我就照字面取了,他自己也说没画准)。下面的脚本做三件事:判三个向量是否无关,找出那个凑出零的 c\mathbf{c},再把三种“一眼就相关”的情形跑一遍。零空间向量我用 SVD 的最后一个右奇异向量得到,这个办法后面几讲会解释,现在只当它是“零空间里的一个单位向量”:

import numpy as np
def null_vector(A: np.ndarray) -> np.ndarray:
"""返回 A 的零空间里的一个单位向量(A 的列相关时才有意义)。"""
_, _, Vt = np.linalg.svd(A)
return Vt[-1]
def main() -> None:
np.set_printoptions(precision=4, suppress=True)
# 平面里的三个向量:把它们放进 A 的三列,A 是 2 x 3
v1 = np.array([2.0, 1.0])
v2 = np.array([1.0, 2.0])
v3 = np.array([2.5, -1.0])
A = np.column_stack([v1, v2, v3])
print("A 的形状:", A.shape, ",秩 =", np.linalg.matrix_rank(A))
print("独立的条件是秩 = 列数 3:", np.linalg.matrix_rank(A) == 3)
# 列比行多,零空间里一定有非零向量 c
c = null_vector(A)
print("零空间里的 c =", c)
print("c1 v1 + c2 v2 + c3 v3 =", A @ c)
# 只取前两个向量,秩 = 2 = 列数,独立
print("v1, v2 的秩:", np.linalg.matrix_rank(A[:, :2]))
# 三种一眼就相关的情形:v 与 2v,含零向量
v = np.array([2.0, 1.0])
pairs = {
"v 与 2v": np.column_stack([v, 2 * v]),
"v 与零向量": np.column_stack([v, np.zeros(2)]),
"v1 与 v2": np.column_stack([v1, v2]),
}
for name, M in pairs.items():
r = np.linalg.matrix_rank(M)
print(f"{name}:秩 = {r},列数 = {M.shape[1]},独立:{r == 2}")
if __name__ == "__main__":
main()
A 的形状: (2, 3) ,秩 = 2
独立的条件是秩 = 列数 3: False
零空间里的 c = [-0.7428 0.5571 0.3714]
c1 v1 + c2 v2 + c3 v3 = [ 0. -0.]
v1, v2 的秩: 2
v 与 2v:秩 = 1,列数 = 2,独立:False
v 与零向量:秩 = 1,列数 = 2,独立:False
v1 与 v2:秩 = 2,列数 = 2,独立:True

2×32 \times 3 的矩阵秩最多是 2,所以三列不可能无关,这是“列比行多”的直接后果。c 的三个分量满足 −0.7428 v1+0.5571 v2+0.3714 v3=0-0.7428\,\mathbf{v}_1 + 0.5571\,\mathbf{v}_2 + 0.3714\,\mathbf{v}_3 = \mathbf{0},右边打印出来的 [ 0. -0.] 就是验证(-0. 是浮点数的负零,不是错误)。把 c\mathbf{c} 同时除以 0.3714,得到 (−2,1.5,1)(-2, 1.5, 1),你可以手算验一遍:第一个分量 −4+1.5+2.5=0-4 + 1.5 + 2.5 = 0,第二个 −2+3−1=0-2 + 3 - 1 = 0。

张成与基:不多不少#

张成是什么? 一堆向量张成一个空间,意思是这个空间就是它们所有线性组合的集合。他说这个词其实早就用过了:矩阵的列张成列空间。他补了一句:这堆向量张成的空间是包含它们的最小空间,因为任何含有这些向量的空间都必须含有它们的所有组合。

单看张成不够,列可能有冗余;单看无关也不够,向量可能太少。基是什么? 同时满足两条:无关,并且张成这个空间。他的说法是“刚刚好”:少一个张不满,多一个就相关。这有点像点菜,少一道吃不饱,多一道吃不完,只有刚好的那一桌才既不饿也不浪费。往后每次问到子空间,他都会问“给我一组基”,因为基就是对这个子空间的完整描述。

他的第一个例子是 R3\mathbb{R}^3。最先想到的基是 xx、yy、zz 轴方向的三个单位向量,也就是单位矩阵的三列,零空间只有零向量,所以无关。第二个例子,他从 (1,1,2)(1, 1, 2) 和 (2,2,5)(2, 2, 5) 开始:两个向量无关,但张不满 R3\mathbb{R}^3。要补第三个。补 (3,3,7)(3, 3, 7) 是个“失误”,因为它恰好是前两个之和,躺在同一个平面里。补 (3,3,8)(3, 3, 8) 呢?他说“希望这个行”,然后问:如果我挑的是别的数,比如 (5,7,−14)(5, 7, -14),我怎么知道?答案是放进矩阵的列,做消元,看有没有自由变量;对方阵来说,等价于矩阵可逆。

我把这三个候选逐个交给 NumPy,结果和字幕里的猜测不太一样:

import numpy as np
def main() -> None:
np.set_printoptions(precision=4, suppress=True)
# R^3 的第一组基:单位矩阵的三列
print("单位矩阵的秩:", np.linalg.matrix_rank(np.eye(3)))
# 只有两个向量:独立,但张不满 R^3
B2 = np.array([[1.0, 2.0], [1.0, 2.0], [2.0, 5.0]])
print("(1,1,2) 与 (2,2,5) 的秩:", np.linalg.matrix_rank(B2))
# 第三个向量逐个试:秩 = 3 才是基(方阵时等价于 det 非零)
for third in ([3.0, 3.0, 7.0], [3.0, 3.0, 8.0], [5.0, 7.0, -14.0]):
M = np.column_stack([B2, third])
r = np.linalg.matrix_rank(M)
print(f"补 {third}:秩 = {r},det = {np.linalg.det(M):.4f}")
# 前两个向量的第一、二个分量总相等,它们张成的平面是 x = y
# (3, 3, 8) 也满足 x = y,所以它还在这个平面里
print("B2 的两列满足 x = y:", np.allclose(B2[0], B2[1]))
# 补 (5, 7, -14) 得到一组基:任意向量都有唯一的坐标
good = np.column_stack([B2, [5.0, 7.0, -14.0]])
x = np.array([1.0, -2.0, 3.0])
coeff = np.linalg.solve(good, x)
print("x 在这组基下的坐标:", coeff)
print("坐标重新组合回 x:", np.allclose(good @ coeff, x))
if __name__ == "__main__":
main()
单位矩阵的秩: 3
(1,1,2) 与 (2,2,5) 的秩: 2
补 [3.0, 3.0, 7.0]:秩 = 2,det = 0.0000
补 [3.0, 3.0, 8.0]:秩 = 2,det = 0.0000
补 [5.0, 7.0, -14.0]:秩 = 3,det = -2.0000
B2 的两列满足 x = y: True
x 在这组基下的坐标: [ 78.5 -35. -1.5]
坐标重新组合回 x: True

(3,3,8)(3, 3, 8) 也是相关的:前两个向量的第一、第二个分量都相等,它们张成的平面就是 x=yx = y,而 (3,3,8)(3, 3, 8) 的前两个分量也相等,所以它同样躺在这个平面里。这是 Strang 自己挑错了数字:他说“希望 3 3 8 可以”,课后有同学指出来,他在 第 10 讲 开头更正了。这个“挑数字挑错了”的插曲反而把他想说的事演示了:肉眼挑,十有八九会翻车,要用矩阵检验。(我这里再试一次运气,(5,7,−14)(5, 7, -14) 通过,行列式是 −2-2。)

补上 (5,7,−14)(5, 7, -14) 之后,方阵 good 可逆,任意 x\mathbf{x} 都能唯一地写成三列的组合。随手取的 x=(1,−2,3)\mathbf{x} = (1, -2, 3) 在这组基下的坐标是 (78.5,−35,−1.5)(78.5, -35, -1.5),系数不小,我猜是因为这三个向量彼此并不“垂直”,拼一个普通的向量得靠大系数互相抵消(我没有算条件数去证实,这只是猜测)。基有好坏之分,后面讲正交基的时候会回来。

还有一个他强调了两次的事实:基不唯一。任何可逆的 3×33 \times 3 矩阵的列都是 R3\mathbb{R}^3 的一组基,有无穷多组。但所有的基有一个共同点:向量个数相同。

维数:基里有几个向量#

维数是什么? 对一个空间,所有基含有的向量个数相同,这个数就是它的维数。R3\mathbb{R}^3 的每组基都有 3 个向量;某个子空间的一组基有 6 个向量,那它的所有基都是 6 个。他说这是“定义性”的:维数就是基的向量个数,它回答的是“这个空间有多大”。

这里有一个用词上的提醒,我觉得值得抄下来:

  • 矩阵有秩,没有“维数”。
  • 子空间有维数,没有“秩”。
  • 秩是列空间的维数,所以说“列空间的维数”,不说“AA 的维数”。

他说,用词对了,就说明概念对了。

他用的矩阵是一个 3×43 \times 4 的例子:四列依次是 (1,1,1)(1, 1, 1)、(2,1,2)(2, 1, 2)、(3,2,3)(3, 2, 3)、(1,1,1)(1, 1, 1)。第三列是前两列之和,第四列重复第一列。问题是:四列张成列空间,但是否是基?不是,因为 −1-1 份第一列、−1-1 份第二列、11 份第三列、00 份第四列加起来是零向量,零空间里有非零向量。

他的回答是:自然的基是主列,也就是第一、第二列。从左往右扫,第一列可以放进基,第二列也可以,第三列不能(它是前两列的组合),第四列也不能。所以秩是 2,主列有 2 个,列空间的维数也是 2:秩、主列个数、列空间维数是同一个数。然后他让大家说“另一组基”:第一、三列,第二、三列,第二、四列都行,甚至不是 AA 的列的也行,比如 (2,2,2)(2, 2, 2) 和 (7,5,7)(7, 5, 7)(后者是四列之和)。

最后是一个我觉得很实用的小定理:如果你已经知道空间的维数是 dd,并且手里有 dd 个无关的向量,它们自动就是基,张成是白送的。因为如果张不满,就还缺一个向量来补,那时候就会有 d+1d + 1 个无关向量,超过了维数。

这一节所有的断言,我用一个脚本一并验证。其中的“主列”和“特解”都是手写的(主列:从左到右,加入这一列使秩增加,它就是主列;特解:自由变量取 1,其余自由变量取 0,再解主变量),用 np.linalg.matrix_rank 对照:

import numpy as np
def pivot_columns(A: np.ndarray) -> list[int]:
"""从左到右:这一列让秩增加,就是主列。"""
pivots: list[int] = []
for j in range(A.shape[1]):
if np.linalg.matrix_rank(A[:, pivots + [j]]) > len(pivots):
pivots.append(j)
return pivots
def special_solutions(A: np.ndarray, pivots: list[int]) -> np.ndarray:
"""每个自由列取 1、其余自由列取 0,再解出主变量。"""
n = A.shape[1]
free = [j for j in range(n) if j not in pivots]
N = np.zeros((n, len(free)))
for k, j in enumerate(free):
N[j, k] = 1.0
N[pivots, k], *_ = np.linalg.lstsq(A[:, pivots], -A[:, j], rcond=None)
return N
def main() -> None:
np.set_printoptions(precision=4, suppress=True)
# Strang 的矩阵:四列依次是 (1,1,1)、(2,1,2)、(3,2,3)、(1,1,1)
A = np.array(
[
[1.0, 2.0, 3.0, 1.0],
[1.0, 1.0, 2.0, 1.0],
[1.0, 2.0, 3.0, 1.0],
]
)
m, n = A.shape
r = np.linalg.matrix_rank(A)
print("A =")
print(A)
print(f"m = {m}, n = {n}, 秩 r = {r}")
# 列空间:主列就是一组基,维数 = 秩
pivots = pivot_columns(A)
print("主列(从 0 数起):", pivots, ",列空间的维数 =", len(pivots))
# 零空间:特解就是一组基,维数 = n - r
N = special_solutions(A, pivots)
print("特解矩阵 N(每列一个特解):")
print(N)
print("A @ N = 0:", np.allclose(A @ N, 0))
print(
"零空间的维数 n - r =", n - r, ",N 的秩 =", np.linalg.matrix_rank(N)
)
# 他说的第一个组合:-1 份第一列,-1 份第二列,1 份第三列,0 份第四列
c = np.array([-1.0, -1.0, 1.0, 0.0])
print("A @ (-1, -1, 1, 0) =", A @ c)
# 另一组基:不是 A 的列,但在列空间里。7 5 7 是四列之和
B = np.column_stack([[2, 2, 2], [7, 5, 7]]).astype(float)
print("B 的秩:", np.linalg.matrix_rank(B))
print(
"B 的列都在列空间里:", np.linalg.matrix_rank(np.hstack([A, B])) == r
)
print("四列之和 =", A @ np.ones(4))
if __name__ == "__main__":
main()
A =
[[1. 2. 3. 1.]
[1. 1. 2. 1.]
[1. 2. 3. 1.]]
m = 3, n = 4, 秩 r = 2
主列(从 0 数起): [0, 1] ,列空间的维数 = 2
特解矩阵 N(每列一个特解):
[[-1. -1.]
[-1. 0.]
[ 1. 0.]
[ 0. 1.]]
A @ N = 0: True
零空间的维数 n - r = 2 ,N 的秩 = 2
A @ (-1, -1, 1, 0) = [0. 0. 0.]
B 的秩: 2
B 的列都在列空间里: True
四列之和 = [7. 5. 7.]

零空间的维数是 n - r#

最后几分钟他转向零空间。刚才那个非零向量 (−1,−1,1,0)(-1, -1, 1, 0) 只是零空间里的一个向量,零空间里还有别的。自然的选择是:第四列是自由列,令这个自由变量为 1、另一个自由变量(第三列)为 0,问第四列是不是主列的组合。是的,它就是第一列,所以 (−1,0,0,1)(-1, 0, 0, 1) 在零空间里。这两个向量正是上一讲的特解:每个自由变量轮流取 1,其他自由变量取 0。

它们无关,而且张成整个零空间,所以是零空间的一组基,零空间的维数是 2。更一般地:nn 列里有 rr 个主列,剩下 n−rn - r 个自由列,每个自由列给一个特解,因此

dim⁡C(A)=r,dim⁡N(A)=n−r.\dim C(A) = r, \qquad \dim N(A) = n - r.

上面代码块的输出正对着这两个公式:m=3m = 3、n=4n = 4、r=2r = 2,主列是第 0、1 列(从 0 数起),特解矩阵 N 的两列正是 (−1,−1,1,0)(-1, -1, 1, 0) 和 (−1,0,0,1)(-1, 0, 0, 1),A @ N 全零,NN 的秩是 2。零空间里的向量就是“这些列相关的方式”:每一个特解告诉你,哪几列怎么组合能得零。

浮点数里的“几乎无关”#

定义是干净的:要么无关,要么相关。但 np.linalg.matrix_rank 判的是数值秩,它拿奇异值和一个阈值比(默认阈值约为 σmax⁡⋅max⁡(m,n)⋅ε\sigma_{\max} \cdot \max(m, n) \cdot \varepsilon,ε≈2.2×10−16\varepsilon \approx 2.2 \times 10^{-16}),低于阈值的奇异值当成 0。所以“相关”在浮点数里是有一个模糊带的。下面的脚本做两个实验。第一个:固定种子取随机向量,看它们是不是几乎总是无关(他在第 1 讲说过“MATLAB 的随机矩阵几乎一定可逆”);并且验证 n+1n + 1 个 nn 维向量必相关。第二个:第三列取前两列之和,再加上噪声,看噪声多小时 matrix_rank 会被“骗过去”:

import numpy as np
def main() -> None:
np.set_printoptions(precision=4, suppress=True)
rng = np.random.default_rng(1806)
# 随机取 n 个 n 维向量:几乎总是独立(秩 = n)
for n in (3, 10, 100):
trials = 1000
full = sum(
np.linalg.matrix_rank(rng.standard_normal((n, n))) == n
for _ in range(trials)
)
print(f"n = {n:3d}:{trials} 次里有 {full} 次秩为 n")
# 取 n + 1 个 n 维向量:必相关,零空间至少一维
n = 5
M = rng.standard_normal((n, n + 1))
print("5 维里取 6 个向量,秩 =", np.linalg.matrix_rank(M))
_, s, Vt = np.linalg.svd(M)
c = Vt[-1]
print("‖M c‖ =", f"{np.linalg.norm(M @ c):.2e}")
# 浮点数里的“相关”:第三列 = 前两列之和,再加一点点噪声
base = rng.standard_normal((4, 2))
third = base[:, 0] + base[:, 1]
for eps in (0.0, 1e-16, 1e-12, 1e-8, 1e-4):
noise = eps * rng.standard_normal(4)
M = np.column_stack([base, third + noise])
s = np.linalg.svd(M, compute_uv=False)
print(
f"噪声 {eps:7.0e}:最小奇异值 = {s[-1]:.2e},"
f"秩 = {np.linalg.matrix_rank(M)}"
)
if __name__ == "__main__":
main()
n = 3:1000 次里有 1000 次秩为 n
n = 10:1000 次里有 1000 次秩为 n
n = 100:1000 次里有 1000 次秩为 n
5 维里取 6 个向量,秩 = 5
‖M c‖ = 4.79e-16
噪声 0e+00:最小奇异值 = 9.16e-17,秩 = 2
噪声 1e-16:最小奇异值 = 2.18e-16,秩 = 2
噪声 1e-12:最小奇异值 = 9.42e-13,秩 = 3
噪声 1e-08:最小奇异值 = 9.92e-09,秩 = 3
噪声 1e-04:最小奇异值 = 5.54e-05,秩 = 3

前三行:随机取向量,在 n=3,10,100n = 3, 10, 100 三种规模下各试 1000 次,每一次都是满秩,随机向量“几乎总是无关”不是夸张。第四、五行:5 维空间里的 6 个向量,秩最多 5,所以必相关,找到的 c\mathbf{c} 让 ∥Mc∥=4.79×10−16\|M\mathbf{c}\| = 4.79 \times 10^{-16},也就是舍入误差的水平。

最后五行是我觉得最有意思的。第三列是前两列的精确之和时(噪声 0),最小奇异值是 9.16×10−179.16 \times 10^{-17},判相关,对的。噪声只有 10−1610^{-16} 时最小奇异值是 2.18×10−162.18 \times 10^{-16},还在阈值之下,判相关。可是噪声涨到 10−1210^{-12},最小奇异值 9.42×10−139.42 \times 10^{-13} 已经高于阈值,matrix_rank 就判秩 3,也就是“无关”了。严格地说,这三列在数学上是无关的(噪声不为零),所以 NumPy 没有错。但如果这个噪声只是测量误差,那么它判的“无关”就没有意义。

我的结论是:数学里的无关是一个二选一,数值里的“秩”是一个带阈值的判断,阈值怎么取要看这个噪声是不是你关心的东西。后面讲 SVD 时,我会换一个角度处理这件事:奇异值是多少,比“秩是几”携带的信息多得多。(所以我在日常里更愿意看最小奇异值,而不是只看 matrix_rank 的那个整数。)

这一讲算是把前八讲反复出现的词都落了地:消元找主元,主元是几个,秩就是几;自由变量是几个,零空间就是几维。下一讲要把列空间、零空间再配上它们的两个“转置版本”,凑齐四个基本子空间,并把它们的维数 rr、n−rn - r、rr、m−rm - r 一次说完,见 18.06 第 10 讲:四个基本子空间。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
18.06 第 9 讲:线性无关、基与维数
https://bfmhno3.github.io/posts/linear-algebra-09-independence-basis-dimension/
作者
bfmhno3
发布于
2026-10-18
许可协议
CC BY-NC-SA 4.0
相关文章智能推荐
1
18.06 第 31 讲:基变换与图像压缩
NoteMIT 18.06 第 31 讲的配套笔记:我用 Python 3.13 和 NumPy 2.4 在 Haar 小波基下压缩一张合成的 64 × 64 灰度图,只存 516 个数,相对误差 0.0142,同样存储量的 SVD 低秩近似是 0.0795。
2
18.06 第 24 讲:Markov 矩阵与 Fourier 级数
NoteMIT 18.06 第 24 讲的配套笔记:我用 Python 3.13 和 NumPy 2.4 把加州与麻州的人口迁移连乘了 20 年,离稳态 (666.67, 333.33) 只差 0.7523 人,再用 np.trapezoid 把方波和三角波展开成 Fourier 级数,取到 19 次谐波时三角波的误差约为方波的 1/35。
3
18.06 第 30 讲:线性变换及其矩阵
NoteMIT 18.06 第 30 讲的配套笔记:我用 Python 3.13 和 NumPy 2.4 把一座房子的六个顶点交给翻转、旋转和投影三个矩阵,又把多项式求导写成 2 × 3 矩阵,平移的线性性误差是 3.1623,而投影把房子的面积压成了 0 倍。
4
18.06 第 23 讲:微分方程与 exp(At)
NoteMIT 18.06 第 23 讲的配套笔记:我用 Python 3.13 和 NumPy 2.4 把 du/dt = Au 的解 exp(At)u(0) 用特征分解、Taylor 级数和缩放平方各算了一遍,t = 20 时 60 项 Taylor 的误差是 3.11e+24,缩放平方是 1.05e-15。
5
18.06 第 21 讲:特征值与特征向量
NoteMIT 18.06 第 21 讲的配套笔记:我用 Python 3.13 和 NumPy 2.4 算了投影、置换、旋转和三角矩阵的特征值,90 度旋转矩阵的特征值是 ±i,而 [[3, 1], [0, 3]] 的特征向量矩阵条件数高达 3.00e+15。
随机文章随机推荐

评论区

Profile Image of the Author
bfmhno3
Hello, I'm bfmhno3.
公告
本站曾使用 Jekyll + Minimal Mistakes 主题,现已迁移至 Astro + Firefly。博客内容未变,但文章链接有所调整,请自行查找需要的文章。
分类
标签
最新动态
站点统计
文章
123
分类
2
标签
239
总字数
753,253
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
GitHub Actions
博客版本
Firefly v6.16.8
文章许可
CC BY-NC-SA 4.0
文章目录