Power Method for Eigenvalues

幂法:矩阵本征值迭代求解的基本方法

基本的幂法:求矩阵的最大本征值

$$ Ax^{(k)} = x^{(k+1)} $$

只要把任何一个初始随机向量反复地被一个矩阵作用,同时除以一个足够大的数保证不超过数值精度,那么最终的收敛结果就是矩阵的最大本征矢。

这种方法可行的原因是,矩阵可以看做是一个线性变换,对任何一个向量连续地作用同一个变换的结果,总是会让这个向量趋近于变换的主向量,也就是矩阵的最大本征值对应的本征矢。

In [1]:
import numpy as np
In [2]:
def power_iteration(A, num_simulations: int, v0=None):
    if v0 is None:
        v = np.random.rand(A.shape[1])
    else: 
        v = v0
        
    for _ in range(num_simulations):     
        v = A @ v / np.max(v)
    return v
In [3]:
a = np.random.rand(4,4)
e2,v2=np.linalg.eig(a)
ei2 = e2.argmax()
e2[ei2], v2[:,ei2] / np.linalg.norm(v2[:,ei2])
Out[3]:
((2.1973691032607885+0j),
 array([0.54317076+0.j, 0.56821252+0.j, 0.28769568+0.j, 0.54711174+0.j]))
In [4]:
v1 = power_iteration(a, 1000)
(a @ v1 / v1)[0], v1/ np.linalg.norm(v1)
Out[4]:
(2.197369103260788, array([0.54317076, 0.56821252, 0.28769568, 0.54711174]))

反幂法:求矩阵的最小本征矢

与幂法完全相同,只不过迭代的是矩阵的逆,显然矩阵的逆的最大本征值就是原矩阵的模最小的本征值。 $$ A^{-1}x^{(k)} = x^{(k+1)} $$ 不过由于矩阵求逆计算复杂度很大,可以把它转化成求线性方程组: $$ A x^{(k+1)} = x^{(k)} $$

In [5]:
def inverse_power_iteration(A, num_simulations: int, v0=None):
    if v0 is None:
        v = np.random.rand(A.shape[1])
    else: 
        v = v0
        
    for _ in range(num_simulations):  
        v = np.linalg.solve(A, v) 
        # v = np.linalg.inv(A) @ v
        v = v / np.max(v)
    return v
    
In [6]:
a = np.random.rand(4,4)
e2,v2=np.linalg.eig(a)
ei2 = np.abs(e2).argmin()
e2[ei2], v2[:,ei2] / np.linalg.norm(v2[:,ei2])
Out[6]:
(0.0934634074161824,
 array([ 0.06236468, -0.34577788,  0.87179586, -0.34135067]))
In [7]:
v1 = inverse_power_iteration(a, 1000)
1/ (np.linalg.inv(a) @ v1 / v1)[0], v1/ np.linalg.norm(v1)
Out[7]:
(0.09346340741618211,
 array([ 0.06236468, -0.34577788,  0.87179586, -0.34135067]))
In [ ]:
 

评论

Comments powered by Disqus