笔记8-《程序员的数学3:线性代数》可对角化与特征值  

目录
  1. 可对角化与特征值
  2. 特征值的两种理解
  3. 为什么特征值是「固有的」
  4. 用 Ruby 验证
  5. 从特征值到 Jordan 标准型

可对角化与特征值

  • 4.4 可对角化的情况

    • 三种表达方式

      • 变量替换:把「原来的变量」换成「好的变量」,逐个击破
      • 坐标变换:y(t)=Cr(t)\mathbf{y}(t) = C\mathbf{r}(t),其中 CC 是变换矩阵
      • 乘方计算:At=PDtP−1A^t = PD^tP^{-1}
    • 用矩阵语言表达坐标变换

      • 原问题 r(t)=Ar(t−1)\mathbf{r}(t) = A\mathbf{r}(t-1)
      • 令 y(t)=Cr(t)\mathbf{y}(t) = C\mathbf{r}(t),则变成 y(t)=CAC−1y(t−1)\mathbf{y}(t) = C A C^{-1}\mathbf{y}(t-1)
      • 如果 CAC−1=DC A C^{-1} = D 是对角矩阵,问题就归结为 4.3 的标量情形
      • 还原时用 r(t)=C−1y(t)\mathbf{r}(t) = C^{-1}\mathbf{y}(t)
    • 为什么不能用初等变换

      • 通过初等行/列变换确实能把 AA 变成 diag\mathrm{diag} 形式
      • 但初等变换是在 AA 的左右两边分别乘以可逆矩阵 CC 和 PP,得到 CAP=DCAP = D
      • 而这里的变量替换要求:左边的 r(t)\mathbf{r}(t) 和右边的 r(t−1)\mathbf{r}(t-1) 必须经过同一个 PP 变换
        • 即 r(t)=Py(t)\mathbf{r}(t) = P\mathbf{y}(t) 在递推式两边同时生效
      • 所以初等变换在这里不适用 —— 这是第 2 章里「无所不能」的初等变换在本章失效的原因
    • 4.5 特征值、特征向量

      • 几何意义

        • 乘以 A=(1.3000.3)A = \begin{pmatrix} 1.3 & 0 \\ 0 & 0.3 \end{pmatrix} 之后,只有长度的伸缩变化而方向保持不变的向量就是 AA 的特征向量
        • 伸缩倍率就是特征值(伸长时为 1.3,缩短时为 0.3)
      • 定义:满足 Ap=λpA\mathbf{p} = \lambda \mathbf{p} 的非零向量 p\mathbf{p} 是特征向量,λ\lambda 是对应的特征值

      • 旋转矩阵没有实特征向量

        • A=(0−110)A = \begin{pmatrix} 0 & -1 \\ 1 & 0 \end{pmatrix} 把 (1,0)T(1,0)^T 转到 (0,1)T(0,1)^T,把 (0,1)T(0,1)^T 转到 (−1,0)T(-1,0)^T
        • 对应「以原点为中心逆时针旋转 90 度」的变换
        • 所有向量都转了 90 度,方向不变的向量找不到 → 实数范围内没有特征向量
        • 引入复数后就有了:特征值 +i+i 的特征向量 p+=(1,i)T\mathbf{p}_+ = (1, i)^T,特征值 −i-i 的是 p−=(1,−1)T\mathbf{p}_- = (1, -1)^T
        • 所以即便是实矩阵,特征值和特征向量也可能是复数
      • 复特征值的情况

        • 一般的实方阵 AA(若可对角化)用实矩阵 PP 变换后得到分块对角的实矩阵 DD
        • 每个 2×22 \times 2 区块对应一对共轭复特征值
        • 求分块对角矩阵的幂,只需对各区块分别求幂

特征值的两种理解

第一种:伸缩倍率。

Ap=λpA\mathbf{p} = \lambda\mathbf{p} 意味着沿 p\mathbf{p} 这个方向,映射只做伸缩。λ>1\lambda > 1 伸长,∣λ∣<1|\lambda| < 1 缩短,λ<0\lambda < 0 伸缩加翻转。

第二种:系统失控的判据。

第 4 章的真正目标是判断 r(t)=Ar(t−1)\mathbf{r}(t) = A\mathbf{r}(t-1) 会不会失控。如果 AA 可对角化成 A=PDP−1A = PDP^{-1},那么

At=PDtP−1A^t = P D^t P^{-1}

失控与否完全由 DD 的对角元素决定,也就是由 AA 的特征值决定:

  • 存在 ∣λ∣>1|\lambda| > 1 → 失控

  • 所有 ∣λ∣<1|\lambda| < 1 → 不失控

  • 所有 ∣λ∣≤1|\lambda| \le 1 但有 ∣λ∣=1|\lambda| = 1 → 仅凭特征值无法判断

这个判据是全书最有实用价值的结论之一:不用算完整的 AtA^t,只要算出特征值。

为什么特征值是「固有的」

书中明确指出:DD 的对角元素本质是特征方程的解,是矩阵本身的固有性质,没有任何人为操作的余地。

这解释了为什么变量替换得到的 DD 的对角元素是确定的 —— 你换基底、换变量方式都不会改变它们。换句话说,特征值是矩阵的不变量。

用 Ruby 验证

def mat_mul_v(a, v)
a.each_index.map { |i| a[i].each_index.sum { |j| a[i][j] * v[j] } }
end

# A = [[2,1],[1,2]] 的特征值是 3 和 1
a = [[2.0, 1.0], [1.0, 2.0]]

# 特征向量满足 A*v = lambda*v
[3.0, 1.0].each do |lam|
# 解 (A - lambda I) v = 0,取 v = (1, -(2-lambda))
v = [1.0, -(2.0 - lam)]
r = mat_mul_v(a, v)
ratio = r.map { |x| x / v[0] }
puts "lambda=#{lam} v=#{v} A*v=#{r.map { |x| x.round(6) }} 比值=#{ratio.map { |x| x.round(6) }}"
end

输出:

lambda=3.0  v=[1.0, 1.0]  A*v=[3.0, 3.0]  比值=[3.0, 3.0]
lambda=1.0 v=[1.0, -1.0] A*v=[1.0, -1.0] 比值=[1.0, -1.0]

「比值」那两列就是验证:ApA\mathbf{p} 的每个分量除以 p\mathbf{p} 的对应分量,两个都等于 λ\lambda,说明 p\mathbf{p} 确实是特征向量,λ\lambda 确实是伸缩倍率。

顺带验证幂矩阵:

def mat_mul(a, b)
n = a.size
m = b[0].size
k = b.size
n.times.map { |i| m.times.map { |j| k.times.sum { |t| a[i][t] * b[t][j] } } }
end

def mat_pow(a, e)
r = a.size
res = Array.new(r) { |i| Array.new(r) { |j| i == j ? 1.0 : 0.0 } }
base = a
while e > 0
res = mat_mul(res, base) if e & 1 == 1
base = mat_mul(base, base)
e >>= 1
end
res
end

a = [[2.0, 1.0], [1.0, 2.0]]
p3 = mat_pow(a, 3)
puts "A^3 = #{p3.each_index.map { |i| p3[i].map { |v| v.round(6) } }}" # A^3 = [[14.0, 13.0], [13.0, 14.0]]

A3=PD3P−1A^3 = P D^3 P^{-1} 这个公式可以用来交叉验证求出的 PP 和 DD 是否正确。

从特征值到 Jordan 标准型

特征值判据有个漏洞:∣λ∣=1|\lambda| = 1 的情况,仅凭特征值无法判断。

原因是当 AA 不可对角化时,AtA^t 里有 tt 这个因子出现。一个 λ=1\lambda = 1 的 Jordan 块,其 tt 次方带上 tt 的增长,tt 无限增大时还是会发散。

这就是下一节(4.7 不可对角化的情况)要解决的问题:用 Jordan 标准型补上这个缺口。

123.8k