一、幂法和反幂法
1、幂法
由于求解特征方程
入手。设
且与
产生向量序列
证明当
充分大时,上述结论成立: 设
,且 线性无关,故必存在 个不全为零的数 ,使得: 得:
即:
设
, 由 得: 于是:
故只要
充分大, 就有: 因此, 可把
作为与 相应的特征向量的近似。由公式: 即可得到:
利用上述结论,可以不断迭代,得到:
注意到其中
- 如果
的范数大于 ,则会导致计算过程中溢出。 - 如果
的范数小于 ,则会导致在计算过程中变成 。
根据上面的推导过程,以及矩阵2-范数的定义,为了避免这种情形,实际计算时每次迭代所求得的向量都要归一化,因此实际计算使用公式为:
当我们计算
这样所得的结果更加稳定。
2、反幂法
在实际应用是,我们需要寻找一个最接近于数
设
因此,若对矩阵
由于
代替,同时在每次迭代的过程中做归一化处理。
3、代码
下面是使用反幂法求解特定特征值(距离给出 lambda0 最近的特征值)的MATLAB代码:
function [lambda, v] = solveEigenpair(A, lambda0) n = size(A, 1); B = A - lambda0 * eye(n); [L, U, P] = lu(B); v = rand(n, 1); v = v / norm(v); tol = 1e-12; while true v_new = U \ (L \ (P * v)); v_new = v_new / norm(v_new); lambda = v_new' * A * v_new; if norm(A * v_new - lambda * v_new) < tol break; end v = v_new; endend二、雅可比(Jacobi)方法
Jacobi 方法是求实对称矩阵的全部特征值及相应特征向量的一种方法 。它基于以下两个数学结论:
- 正交相似变换:任意实对称矩阵
均存在正交矩阵 ,使得 ,其中 为特征值, 的列向量为特征向量。 - Frobenius 范数不变性:在正交变换下,矩阵元素的平方和保持不变 。设
,则 。
该方法的核心思想是通过一系列正交变换(旋转变换),不断减小非对角元素的平方和,使矩阵趋向于对角阵。下面介绍旋转变换矩阵
选取旋转角
雅各比方法运算量大,且不能保持矩阵的特殊形状,所以该方法只适合求解中小型稠密矩阵。
三、QR 方法
1、基本 QR 算法
QR 算法是计算中小型矩阵全部特征值最有效的方法之一 。其基本思想是利用矩阵的 QR 分解进行相似变换迭代,可以证明,任意非奇异实矩阵都可以分解成一个正交矩阵
其中
使用施密特(Schmidt)正交化方法对
设
其中
对于后续列向量
得到长度为 1 的正交向量
将上述迭代公式改写为
根据该线性组合关系,矩阵
2、Householder 变换
为了减少运算量,通常先通过 Householder 变换将一般矩阵化为拟上三角形(Hessenberg 矩阵)。设
该矩阵存在一个重要性质:设
该定理表明,对于任一非零向量
为了避免在
3、化一般矩阵为拟上三角矩阵
拟上三角形矩阵(上海森堡阵)指主对角线下方的元素从第二行开始全为零的矩阵 。其形式如下:
首先构造第一个 Householder 矩阵
计算
其中
4、拟上三角矩阵的QR分解
由于拟上三角形矩阵
取旋转矩阵
计算参数:
循环操作,假设前
由于旋转矩阵均为正交矩阵,根据正交阵的性质:
其中,
5、代码
下面为使用 Householder 矩阵优化后的QR分解的MATLAB代码:
function [Q, H] = hessenberg(A) n = size(A, 1); Q = eye(n); H = A; for i = 1:n-2 x = H(i+1:n, i); e = zeros(n-i, 1); e(1) = 1; s = sign(x(1)); if s == 0 s = 1; end w = (x + norm(x, 2) * e * s) / norm(x + norm(x, 2) * e * s, 2); H0 = eye(n-i) - 2 * (w * w'); H1 = eye(n); H1(i+1:n, i+1:n) = H0; Q = Q * H1; H = H1 * H * H1; endend
function [Q, R] = getQR(H) n = size(H, 1); Q = eye(n); R = H; for i = 1:n-1 a = R(i, i); b = R(i+1, i); if b == 0 c = 1; s = 0; else r = hypot(a, b); c = a / r; s = b / r; end ri = R(i, i:n); rj = R(i+1, i:n); R(i, i:n) = c * ri + s * rj; R(i+1, i:n) = -s * ri + c * rj; qi = Q(:, i); qj = Q(:, i+1); Q(:, i) = c * qi + s * qj; Q(:, i+1) = -s * qi + c * qj; endend
function values = eigen(A) n = size(A, 1); [~, H] = hessenberg(A); tol = 1e-5; while norm(H - diag(diag(H)), 'fro') >= tol mu = H(n, n); B = H(1:n, 1:n) - mu * eye(n); [Q, R] = getQR(B); H = R * Q + mu * eye(n); end values = real(diag(H));end