算法知识图谱总览 / 线性代数族 / 特征多项式

特征多项式

P2advancedstandardG-C-14

What · 是什么

det(λI-A),特征值与Cayley-Hamilton定理,线性递推加速基础

特征多项式定义为p_A(λ)=det(λI-A),是关于λ的n次首一多项式。其根为矩阵A的特征值。特征值之和=迹(A),乘积=det(A)(韦达定理)。Cayley-Hamilton定理:矩阵满足自身的特征方程,即p_A(A)=0。此定理可用于加速线性递推:将A^n表示为A^0..A^(n-1)的线性组合(系数来自特征多项式),配合多项式取模可将O(n)降为O(n^2)或O(n log n)。

Why · 为什么

直觉 · Intuition

特征值是线性变换中'方向不变'的伸缩倍数。特征多项式的根(特征值)描述了变换的'本质频率'。Cayley-Hamilton定理说明矩阵'满足自身的方程'。

原理 · Principle

Faddeev-LeVerrier算法递推计算特征多项式系数:M_0=I, M_k=A*M_{k-1}+c_{k-1}*I, c_k=-trace(M_k)/k。Cayley-Hamilton保证A^n可由低次幂线性表出。

历史 · History

特征多项式概念源于特征值问题。Cayley-Hamilton定理由Cayley(1858)和Hamilton证明。Faddeev-LeVerrier算法是O(n^3)求系数的方法。

How · 实现

伪代码

Faddeev-LeVerrier:
  M = I, c[0] = 1
  for k in 1..n:
    M = A * M
    c[k] = -trace(M) / k
    M = M + c[k] * I

Python 实现

def mat_mul_simple(A, B, mod=None):
    n, m = len(A), len(A[0])
    k = len(B[0])
    C = [[0] * k for _ in range(n)]
    for i in range(n):
        for j in range(k):
            s = 0
            for t in range(m):
                s += A[i][t] * B[t][j]
            if mod:
                s %= mod
            C[i][j] = s
    return C

def char_polynomial_coefficients(A, mod=None):
    """Compute coefficients of characteristic polynomial det(xI - A)
    using Faddeev-LeVerrier algorithm.
    Returns [c_0, c_1, ..., c_n] where char poly = c_0*x^n + c_1*x^(n-1) + ... + c_n.
    Actually returns [1, c1, c2, ...] where poly = x^n + c1*x^(n-1) + ... + cn.
    """
    n = len(A)
    I = [[1 if i == j else 0 for j in range(n)] for i in range(n)]
    M = [row[:] for row in I]
    coeffs = [0] * (n + 1)
    coeffs[0] = 1
    for k in range(1, n + 1):
        MK = mat_mul_simple(A, M, mod)
        trace = sum(MK[i][i] for i in range(n))
        if mod:
            ck = (-trace * pow(k, mod - 2, mod)) % mod
        else:
            ck = -trace / k
        coeffs[k] = ck
        for i in range(n):
            MK[i][i] += ck
        M = MK
    return coeffs

def cayley_hamilton_check(A):
    """Verify Cayley-Hamilton: p(A) = 0 where p is char poly."""
    n = len(A)
    coeffs = char_polynomial_coefficients(A)
    # Compute p(A) = sum(coeffs[k] * A^(n-k)) for k=0..n
    # A^0 = I
    I = [[1 if i == j else 0 for j in range(n)] for i in range(n)]
    result = [[0] * n for _ in range(n)]
    Ak = [row[:] for row in I]  # A^0
    for k in range(n + 1):
        # Add coeffs[k] * A^(n-k)
        power = n - k
        Ap = [row[:] for row in I]
        for _ in range(power):
            Ap = mat_mul_simple(Ap, A)
        for i in range(n):
            for j in range(n):
                result[i][j] += coeffs[k] * Ap[i][j]
    # Check if result is zero
    for i in range(n):
        for j in range(n):
            if abs(result[i][j]) > 1e-6:
                return False
    return True

if __name__ == "__main__":
    # 2x2: char poly of [[1,2],[3,4]] is x^2 - 5x - 2
    coeffs = char_polynomial_coefficients([[1, 2], [3, 4]])
    assert abs(coeffs[0] - 1) < 1e-6
    assert abs(coeffs[1] - (-5)) < 1e-6
    assert abs(coeffs[2] - (-2)) < 1e-6
    # Identity matrix: char poly = (x-1)^n
    coeffs2 = char_polynomial_coefficients([[1, 0], [0, 1]])
    assert abs(coeffs2[0] - 1) < 1e-6
    assert abs(coeffs2[1] - (-2)) < 1e-6
    assert abs(coeffs2[2] - 1) < 1e-6
    # 3x3
    coeffs3 = char_polynomial_coefficients([[2, 0, 0], [0, 3, 0], [0, 0, 4]])
    assert abs(coeffs3[0] - 1) < 1e-6
    assert abs(coeffs3[1] - (-9)) < 1e-6
    assert abs(coeffs3[2] - 26) < 1e-6
    assert abs(coeffs3[3] - (-24)) < 1e-6
    # Cayley-Hamilton check
    assert cayley_hamilton_check([[1, 2], [3, 4]])
    assert cayley_hamilton_check([[2, 0], [0, 3]])
    print("char-polynomial: ALL TESTS PASSED")
PyPy 提示Faddeev-LeVerrier涉及矩阵乘法O(n^3)*n步=O(n^4)。竞赛中更多用于理论分析(Cayley-Hamilton加速递推)而非直接计算。
时间复杂度O(n^4)(Faddeev-LeVerrier)
空间复杂度O(n^2)
注意 · 局限直接计算特征多项式系数O(n^4)较慢。特征值可能为复数。大矩阵计算精度问题。

易错点

例题

OJ题号难度考点链接
LuoguP39396线性递推加速(特征多项式应用)https://www.luogu.com.cn/problem/P3939
上游 · 本知识点依赖(前置/变体/组合/共现)

信源

✓ = 已核验 · △ = 未核验