18.06 第 28 讲:相似矩阵与 Jordan 标准形
- 118.06 第 1 讲:方程组的行图与列图
- 218.06 第 2 讲:用矩阵做消元
- 318.06 第 3 讲:矩阵乘法的四种看法与逆矩阵
- 418.06 第 4 讲:分解成 A = LU
- 518.06 第 5 讲:转置、置换与向量空间
- 618.06 第 6 讲:列空间与零空间
- 718.06 第 7 讲:解 Ax = 0,主变量与特解
- 818.06 第 8 讲:解 Ax = b,行最简形 R
- 918.06 第 9 讲:线性无关、基与维数
- 1018.06 第 10 讲:四个基本子空间
- 1118.06 第 11 讲:矩阵空间、秩 1 矩阵与小世界图
- 1218.06 第 12 讲:图、网络与关联矩阵
- 1318.06 第 13 讲:第一次测验复习
- 1418.06 第 14 讲:正交向量与正交子空间
- 1518.06 第 15 讲:投影到子空间
- 1618.06 第 16 讲:投影矩阵与最小二乘
- 1718.06 第 17 讲:正交矩阵与 Gram-Schmidt
- 1818.06 第 18 讲:行列式的性质
- 1918.06 第 19 讲:行列式公式与代数余子式
- 2018.06 第 20 讲:Cramer 法则、逆矩阵与体积
- 2118.06 第 21 讲:特征值与特征向量
- 2218.06 第 22 讲:对角化与矩阵的幂
- 2318.06 第 23 讲:微分方程与 exp(At)
- 2418.06 第 24 讲:Markov 矩阵与 Fourier 级数
- 2518.06 第 24b 讲:第二次测验复习
- 2618.06 第 25 讲:对称矩阵与正定性
- 2718.06 第 26 讲:复矩阵与快速 Fourier 变换
- 2818.06 第 27 讲:正定矩阵与极小值
- 2918.06 第 28 讲:相似矩阵与 Jordan 标准形本文
- 3018.06 第 29 讲:奇异值分解
- 3118.06 第 30 讲:线性变换及其矩阵
- 3218.06 第 31 讲:基变换与图像压缩
- 3318.06 第 32 讲:第三次测验复习
- 3418.06 第 33 讲:左逆、右逆与伪逆
- 3518.06 第 34 讲:期末复习
这一讲的主角是 :同一个线性变换换一套基写下来,矩阵就变成了 ,但特征值一个都没变。Strang 把所有这样连起来的矩阵叫作一个“家族”,每个家族里挑一个最规整的代表,这个代表就是 Jordan 标准形。可是我把一个 4 阶 Jordan 块的左下角改了 ,特征值立刻从 0 跑到了模长 ,放大了 3000 多万倍。他在课上说 Jordan 形在数值上不是好东西,我一开始以为是客气话。
视频:Lecture 28: Similar matrices and Jordan form(OCW 页面与字幕) 教材:《Introduction to Linear Algebra》第 6 版 §6.2 Diagonalizing a Matrix;Appendix 5 The Jordan Form of a Square Matrix 前置:第 27 讲:正定矩阵与极小值 一句话:相似矩阵有相同的特征值;每个方阵都相似于一个 Jordan 矩阵,对角化只是它不缺特征向量时的特例。
- 前十分钟还在讲正定矩阵:逆矩阵、、 是不是正定。这段很短,我在第一节用代码过了一遍,可以倍速。
- 他证明“相似矩阵特征值相同”的那几行(在 中间塞一个 )值得认真看,整讲只有这一处是证明。
- 他当场“编”一个 去算 ,一路算一路惊呼怎么会是 ,随后用迹和行列式验算。这一段有人味,不必倍速。
- 后半段讲 的 Jordan 块那几分钟信息密度最高:两个矩阵特征值相同、特征向量个数也相同,却不相似。暂停看一遍黑板上的两个矩阵。
开头十分钟:正定矩阵从哪里来
这是上一讲的尾巴。他想补一句:正定矩阵不是凭空冒出来的,最常见的出处是最小二乘里那个 。他顺手问了三个问题,我用 NumPy 各验证一次。
对称正定矩阵的逆还正定吗? 还正定,因为逆矩阵的特征值是原来的倒数,正数的倒数还是正数。(他的原话大意是:逆矩阵的主元我们知道得不多,特征值我们什么都知道。)
两个正定矩阵相加呢? 主元和特征值都帮不上忙,但二次型可以:,两项都大于 0,和当然大于 0。
长方形的 呢? 本身不对称,甚至不是方阵,无从谈起正定。但 。想让它严格大于 0,只需要 除了 之外都不为 0,也就是 的零空间里只有零向量,也就是 的列线性无关。他的例子是 11 × 5 的矩阵,秩要等于 5。
下面的脚本里, 是随机的 11 × 5 矩阵, 是把第五列抄成第四列的版本:
import numpy as np
def is_pd(M: np.ndarray) -> bool: return bool(np.all(np.linalg.eigvalsh(M) > 1e-12))
def main() -> None: np.set_printoptions(precision=4, suppress=True) rng = np.random.default_rng(1806)
# 对称正定矩阵的逆:特征值取倒数 A = np.array([[2.0, 1.0], [1.0, 2.0]]) print("A 的特征值:", np.linalg.eigvalsh(A)) print("A^-1 的特征值:", np.linalg.eigvalsh(np.linalg.inv(A)))
# 两个正定矩阵之和:x^T (A + B) x = x^T A x + x^T B x B = np.array([[3.0, -2.0], [-2.0, 3.0]]) print("A、B、A + B 都正定:", is_pd(A), is_pd(B), is_pd(A + B)) x = rng.standard_normal(2) print( "二次型可加:", np.isclose(x @ (A + B) @ x, x @ A @ x + x @ B @ x), )
# 11 x 5 的长方形矩阵:G^T G 是方阵、对称,而且正定 G = rng.standard_normal((11, 5)) K = G.T @ G x = rng.standard_normal(5) print( f"x^T K x = {x @ K @ x:.6f},|Gx|^2 = {np.linalg.norm(G @ x) ** 2:.6f}" ) print(f"K 的最小特征值:{np.linalg.eigvalsh(K).min():.4f}")
# 第五列抄第四列:零空间不再只有零向量,只剩半正定 H = G.copy() H[:, 4] = H[:, 3] K2 = H.T @ H n = np.array([0.0, 0.0, 0.0, 1.0, -1.0]) print("H 的秩:", np.linalg.matrix_rank(H)) print(f"n^T K2 n = {n @ K2 @ n:.1e}") print(f"K2 的最小特征值:{np.linalg.eigvalsh(K2).min():.1e}")
if __name__ == "__main__": main()A 的特征值: [1. 3.]A^-1 的特征值: [0.3333 1. ]A、B、A + B 都正定: True True True二次型可加: Truex^T K x = 16.278015,|Gx|^2 = 16.278015K 的最小特征值:2.7552H 的秩: 4n^T K2 n = 0.0e+00K2 的最小特征值:4.4e-16 的三个“正定”都是 True。 的 最小特征值是 2.7552,完全正定; 和 在六位小数内相同,因为它们本来就是同一个数。 的秩掉到 4,零空间里多了 :沿着这个方向二次型是 0,最小特征值只剩 ,也就是舍入误差,正定退化成半正定。
相似矩阵:同一个家族,同一组特征值
“相似”是什么意思? 两个 矩阵 和 相似,指的是存在可逆矩阵 ,使得
上一章的对角化是它的特例: 有一整套特征向量时,取 (特征向量矩阵),。所以 相似于 。换一个别的 ,得到的 不是对角的,但仍然和 相似。Strang 把相似的矩阵看成一个“家族”,对角的 是家族里最体面的成员。
他在黑板上的例子是 ,特征值 3 和 1。他随手编了 (上三角,逆矩阵好写),算出
这个矩阵看上去什么特点也没有,但迹是 ,行列式是 ,和 的迹 4、行列式 3 一样,所以特征值也是 3 和 1。(他自己心算 的时候也算得磕磕绊绊,我这里让 NumPy 来。)
为什么特征值不变? 从 出发,在 和 之间塞一个 ,两边左乘 :
也是 的特征值,对应的特征向量是 。特征值留下了,特征向量被 挪了个位置。(要是连特征向量也不动, 大概就等于 了。)我把这几句都跑了一遍,同时在家族里另找两个三角矩阵:
import numpy as np
def main() -> None: np.set_printoptions(precision=4, suppress=True)
A = np.array([[2.0, 1.0], [1.0, 2.0]]) M = np.array([[1.0, 4.0], [0.0, 1.0]]) B = np.linalg.inv(M) @ A @ M print("B = M^-1 A M =") print(B) print("A 的特征值:", np.sort(np.linalg.eigvals(A))) print("B 的特征值:", np.sort(np.linalg.eigvals(B))) print("迹:", np.trace(A), np.trace(B)) print(f"行列式:{np.linalg.det(A):.4f} {np.linalg.det(B):.4f}")
# 特征向量被 M^-1 挪了个位置 lam, V = np.linalg.eig(A) W = np.linalg.inv(M) @ V print("M^-1 x 是 B 的特征向量:", np.allclose(B @ W, W * lam))
# 对角化是最特殊的一次相似:M 取特征向量矩阵 S S = V print("S^-1 A S =") print(np.linalg.inv(S) @ A @ S)
# 家族里再取几个成员:迹是 4,行列式是 3 C = np.array([[1.0, 5.0], [0.0, 3.0]]) D = np.array([[3.0, 1.0], [0.0, 1.0]]) for name, X in [("三角 C", C), ("三角 D", D)]: print(name, "的特征值:", np.sort(np.linalg.eigvals(X))) print("A 和 B 的特征向量相同吗:", np.allclose(np.abs(V), np.abs(W)))
if __name__ == "__main__": main()B = M^-1 A M =[[ -2. -15.] [ 1. 6.]]A 的特征值: [1. 3.]B 的特征值: [1. 3.]迹: 4.0 4.0行列式:3.0000 3.0000M^-1 x 是 B 的特征向量: TrueS^-1 A S =[[ 3. 0.] [-0. 1.]]三角 C 的特征值: [1. 3.]三角 D 的特征值: [1. 3.]A 和 B 的特征向量相同吗: FalseB 和 A 的特征值都是 ,迹都是 4,行列式都是 3.0000。M^-1 x 是 B 的特征向量 为 True,而 A 和 B 的特征向量相同吗 为 False,对应他说的“特征向量被挪了位置”。最后两个三角矩阵 和 的特征值也是 1 和 3:迹为 4、行列式为 3 的 2 × 2 矩阵,特征多项式都是 ,特征值都是 3 和 1,互不相同,所以它们都和 相似,也就彼此相似。
如果硬要找个类比,我觉得它像同一座城市用不同的坐标系画地图:街道的连通方式(特征值)是地图的内在性质,地图怎么摆(特征向量)取决于你选哪个原点和朝向。这个类比到这里就收。
孤家寡人 4I 和只有一个特征向量的 Jordan 块
特征值重复了会怎样? 刚才的家族之所以好,是因为两个特征值 3 和 1 不同。如果两个特征值相等,就可能缺特征向量,对角化不再保证。Strang 取了特征值 4 和 4:
- 自己一个家族。(他说到这里承认,学到 18.06 的这个阶段,他已经把矩阵当人看了。)
- 任何 都有 ,挪不出第二个成员。
- 其余所有迹为 8、行列式为 16 的矩阵(他举了 和 )都在另一个家族里。这个家族里不可能有对角矩阵,因为对角的只能是 ,而 不相似于其中任何一个。
这个大家族里最规整的是 Jordan 块 。他说他把 1 改成 10 或者 100 万,也能找到 连回来,所以都是亲戚,Jordan 挑的是最简洁的那个,对角线上方保留一个 1。
下面用特征向量个数()当“指纹”:
import numpy as np
def main() -> None: np.set_printoptions(precision=4, suppress=True) rng = np.random.default_rng(1806)
# 4I 是孤家寡人:任何 M 都挪不动它 four = 4.0 * np.eye(2) M = rng.standard_normal((2, 2)) moved = np.linalg.inv(M) @ four @ M print("M^-1 (4I) M = 4I:", np.allclose(moved, four))
# 特征值 4、4 的另一族:迹 8、行列式 16,只有一个特征向量 J = np.array([[4.0, 1.0], [0.0, 4.0]]) family = { "J": J, "[[5, 1], [-1, 3]]": np.array([[5.0, 1.0], [-1.0, 3.0]]), "[[4, 17], [0, 4]]": np.array([[4.0, 17.0], [0.0, 4.0]]), "M^-1 J M": np.linalg.inv(M) @ J @ M, } for name, X in family.items(): rank = np.linalg.matrix_rank(X - 4.0 * np.eye(2), tol=1e-8) print( f"{name:>18}:迹 {np.trace(X):.1f},det {np.linalg.det(X):.1f}," f"特征向量个数 {2 - rank}" )
# 4I 有两个特征向量,J 只有一个:所以不可能相似 rank = np.linalg.matrix_rank(four - 4.0 * np.eye(2)) print("4I 的特征向量个数:", 2 - rank)
# 对 J 求特征向量矩阵:两列平行,S 奇异(容差内),凑不出对角化 _, S = np.linalg.eig(J) print("eig(J) 的特征向量矩阵:") print(S) print("S 的秩(容差 1e-8):", np.linalg.matrix_rank(S, tol=1e-8))
if __name__ == "__main__": main()M^-1 (4I) M = 4I: True J:迹 8.0,det 16.0,特征向量个数 1 [[5, 1], [-1, 3]]:迹 8.0,det 16.0,特征向量个数 1 [[4, 17], [0, 4]]:迹 8.0,det 16.0,特征向量个数 1 M^-1 J M:迹 8.0,det 16.0,特征向量个数 14I 的特征向量个数: 2eig(J) 的特征向量矩阵:[[ 1. -1.] [ 0. 0.]]S 的秩(容差 1e-8): 1四个成员的特征向量个数都是 1,而 是 2,所以 不可能和它们相似,和 Strang 说的一致。np.linalg.eig(J) 给出的特征向量矩阵是 ,两列平行,秩(容差 )是 1,没法当 用:Jordan 块只有一个特征向量,就是对角化失败的原因。(M^-1 J M 那一行我最初没加 tol,默认容差把噪声当成了秩,算出 0 个特征向量,我才发现应该显式给容差。)
光数特征向量还不够
特征值相同、特征向量个数也相同,就相似了吗? 他接着给了一对 4 × 4 矩阵,让人做噩梦:特征值都是 4 个 0。
- 第一个: 的 和 位置是 1,其余是 0。它是两个 2 × 2 的 Jordan 块。
- 第二个: 和 位置是 1,其余是 0。它是一个 3 × 3 块加一个 1 × 1 块。
两个矩阵的秩都是 2,所以零空间维数都是 ,各有两个特征向量,缺两个。他说光数特征向量,它们看上去像是相似的,其实不相似。区别在块的大小:每个 Jordan 块贡献一个特征向量,块数就是特征向量个数,但块大小不同,家族就不同。这里的判别方法他没讲,我用的是 的秩:
import numpy as np
def nilpotent(blocks: list[int]) -> np.ndarray: """按块大小构造特征值全为 0 的 Jordan 矩阵。""" n = sum(blocks) N = np.zeros((n, n)) start = 0 for size in blocks: for i in range(start, start + size - 1): N[i, i + 1] = 1.0 start += size return N
def main() -> None: np.set_printoptions(precision=4, suppress=True) rank = np.linalg.matrix_rank
two_two = nilpotent([2, 2]) three_one = nilpotent([3, 1]) print("2 + 2 块:") print(two_two) print("3 + 1 块:") print(three_one) for name, N in [("2 + 2", two_two), ("3 + 1", three_one)]: ranks = [int(rank(np.linalg.matrix_power(N, k))) for k in range(4)] print(f"{name}:特征值 {np.linalg.eigvals(N)},N^k 的秩 {ranks}")
# 把 2 + 2 里的一个 0 换成 7:Strang 没说是哪个 0,两种选法差别很大 for pos in [(0, 3), (1, 2)]: X = two_two.copy() X[pos] = 7.0 ranks = [int(rank(np.linalg.matrix_power(X, k))) for k in range(4)] print(f"位置 {pos} 换成 7:N^k 的秩 {ranks}")
# 用 M^-1 X M 随便挪一下,N^k 的秩序列不变 rng = np.random.default_rng(1806) M = rng.standard_normal((4, 4)) Y = np.linalg.inv(M) @ two_two @ M ranks = [ int(rank(np.linalg.matrix_power(Y, k), tol=1e-8)) for k in range(4) ] print("相似挪动后的 2 + 2:N^k 的秩", ranks)
if __name__ == "__main__": main()2 + 2 块:[[0. 1. 0. 0.] [0. 0. 0. 0.] [0. 0. 0. 1.] [0. 0. 0. 0.]]3 + 1 块:[[0. 1. 0. 0.] [0. 0. 1. 0.] [0. 0. 0. 0.] [0. 0. 0. 0.]]2 + 2:特征值 [0. 0. 0. 0.],N^k 的秩 [4, 2, 0, 0]3 + 1:特征值 [0. 0. 0. 0.],N^k 的秩 [4, 2, 1, 0]位置 (0, 3) 换成 7:N^k 的秩 [4, 2, 0, 0]位置 (1, 2) 换成 7:N^k 的秩 [4, 3, 2, 1]相似挪动后的 2 + 2:N^k 的秩 [4, 2, 0, 0]的秩两个矩阵都是 2, 的秩才分出高下:2 + 2 是 0,3 + 1 是 1。这是 Jordan 结构的指纹,经过相似变换不变(最后一行,用随机的 挪过以后还是 )。
他还说,把 2 + 2 里的“一个 0”改成 7,秩仍然是 2,还是同一个家族,只是不如原来那个好看。转写里没说清是哪个 0,所以我两种都试了:改 位置,秩序列还是 ,确实同族;改 位置(两个块之间那一格),秩变成 ,已经变成一个 4 阶块了。我猜他指的是前者,毕竟他是在强调“秩没变”。
于是 Jordan 定理的完整表述就清楚了:每个方阵相似于一个 Jordan 矩阵 ,由若干 Jordan 块拼成,对角线上是特征值,块内对角线上方是 1。块数等于特征向量个数。特征值互不相同时,每块是 1 × 1,,这是“好情形”,整门课主要讲这个。
Jordan 形为什么在数值上不好用
他自己对 Jordan 形是什么态度? 他说得很直白:二十年前上 18.06,这是课程的高潮;现在不是了,因为它“依赖特征值恰好相同”,你得精确知道特征值,还得精确知道秩,数字稍微变一点,特征值变了、秩变了,整个结构就变了。他最后说,期末考试大概不会让你算一个四重特征值的 Jordan 形,他自己不太喜欢 Jordan 形,对正定矩阵和下一讲的 SVD 倒是很积极。
我想把他这个说法量化。取扰动 :
import numpy as np
def main() -> None: np.set_printoptions(precision=6, suppress=False) eps = 1e-10
# 2 x 2:4I 加扰动,对比 Jordan 块加扰动 diag = 4.0 * np.eye(2) J = np.array([[4.0, 1.0], [0.0, 4.0]]) bump = eps * np.array([[0.0, 1.0], [1.0, 0.0]]) for name, X in [("4I", diag), ("J", J)]: lam = np.linalg.eigvals(X + bump) print(f"{name} + 1e-10:特征值 {lam},偏离 {abs(lam - 4).max():.2e}")
# 4 x 4:一个 4 阶 Jordan 块,扰动落在左下角 N = np.diag(np.ones(3), k=1) N[3, 0] = eps lam = np.linalg.eigvals(N) print(f"4 阶块 + 1e-10:|lambda| = {abs(lam).max():.2e}") print(f"理论值 eps^(1/4) = {eps**0.25:.2e}")
# 秩:Jordan 结构靠“恰好为零”,扰动之后秩立刻变了 two_two = np.diag([1.0, 0.0, 1.0], k=1) noisy = two_two + eps * np.diag(np.ones(3), k=-1) print("N^2 的秩(精确):", np.linalg.matrix_rank(two_two @ two_two)) print( "N^2 的秩(加 1e-10 后,默认容差):", np.linalg.matrix_rank(noisy @ noisy), )
# 对 J 加 1e-10 的扰动,特征向量矩阵有多病态 _, S = np.linalg.eig(J + bump) print("特征向量矩阵的条件数:", f"{np.linalg.cond(S):.2e}")
if __name__ == "__main__": main()4I + 1e-10:特征值 [4. 4.],偏离 1.00e-10J + 1e-10:特征值 [4.00001 3.99999],偏离 1.00e-054 阶块 + 1e-10:|lambda| = 3.16e-03理论值 eps^(1/4) = 3.16e-03N^2 的秩(精确): 0N^2 的秩(加 1e-10 后,默认容差): 4特征向量矩阵的条件数: 1.00e+05四个数字:
- 对角化的 加一个 的对称扰动,特征值偏离 ,和扰动同量级。
- 2 × 2 的 Jordan 块加同样的扰动,偏离 ,放大 倍。理由是特征多项式变成 ,特征值跑去 。
- 4 阶 Jordan 块的左下角放 ,特征值模长是 ,正好是 :放大 3000 多万倍。
- 2 + 2 那个矩阵的次对角线加上 以后, 的秩从精确的 0 变成 4(默认容差)。而他强调的正是“靠秩来区分 Jordan 结构”。
另外加了扰动的 其实有两个不同的特征值,可以对角化,但特征向量矩阵的条件数是 :用它去做相似变换会放大误差,没什么好处。据我所知,实际的数值软件不去算 Jordan 形,而是用 Schur 分解这类稳定的三角化,不过这一点我没有在本讲里验证。
在控制里
重极点正是 Jordan 块的用武之地。状态矩阵 有一个二重极点 又缺一个特征向量时, 的解里不只有 ,还有 :对 ,有 。我用 Taylor 级数验证了 的情形: 时右上角是 0.3679(即 ,也是 的峰值), 时降到 。这个响应先升后降,稳定,但不是单纯的指数衰减。据我所知,临界阻尼系统的响应里就有这样的 项。
模态坐标是一个相似变换:取 ,,每个模态各走各的,。脚本里 的两个极点是 和 ,模态初值是 ,用模态坐标算出的 与直接用级数算出的一致。但是 Jordan 块的 eig 给出的特征向量矩阵秩为 1,没有 ,模态坐标这条路走不通,只能退到 Jordan 形,保留那个 1 带来的 项。
import numpy as np
def taylor_exp(A: np.ndarray, terms: int = 60) -> np.ndarray: """用 Taylor 级数求 exp(A)。""" result = np.eye(A.shape[0]) term = np.eye(A.shape[0]) for k in range(1, terms): term = term @ A / k result = result + term return result
def main() -> None: np.set_printoptions(precision=4, suppress=True)
# 重极点 -1:x' = J x,J 是 2 x 2 的 Jordan 块 lam = -1.0 J = np.array([[lam, 1.0], [0.0, lam]]) for t in [1.0, 5.0, 10.0]: E = taylor_exp(J * t) closed = np.exp(lam * t) * np.array([[1.0, t], [0.0, 1.0]]) print( f"t = {t:>4}:Taylor 与闭式一致 {np.allclose(E, closed)}," f"x2 的响应 t e^(lt) = {E[0, 1]:.4e}" )
# 模态坐标:对角化后 z' = Lambda z,每个模态各走各的 A = np.array([[-1.0, 2.0], [0.0, -3.0]]) eigvals, S = np.linalg.eig(A) x0 = np.array([1.0, 1.0]) z0 = np.linalg.solve(S, x0) t = 2.0 x_direct = taylor_exp(A * t) @ x0 x_modal = S @ (np.exp(eigvals * t) * z0) print("极点:", eigvals, ",模态初值 z0 =", z0) print("直接算与模态坐标一致:", np.allclose(x_direct, x_modal))
# Jordan 块没有足够的特征向量:S 不可逆,模态坐标这条路走不通 _, SJ = np.linalg.eig(J) print("Jordan 块的特征向量矩阵秩:", np.linalg.matrix_rank(SJ))
if __name__ == "__main__": main()t = 1.0:Taylor 与闭式一致 True,x2 的响应 t e^(lt) = 3.6788e-01t = 5.0:Taylor 与闭式一致 True,x2 的响应 t e^(lt) = 3.3690e-02t = 10.0:Taylor 与闭式一致 True,x2 的响应 t e^(lt) = 4.5400e-04极点: [-1. -3.] ,模态初值 z0 = [2. 1.4142]直接算与模态坐标一致: TrueJordan 块的特征向量矩阵秩: 1上一节的结论在这里换个说法:真实系统的极点不会恰好重合,参数一变,二重极点就裂成两个靠得很近的单极点,Jordan 块变成一个病态的对角化。工程上除非有意要临界阻尼,多半会避免把极点放到完全相同的位置(我猜的,这不是本讲的内容)。
下一讲是奇异值分解,Strang 说它十年前还不在课里,现在不讲不行了:任何矩阵(不必是方阵)都能写成 ,而且数值上很稳。接着看 18.06 第 29 讲:奇异值分解。
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!











