矩阵特征值计算的python实现(1)——幂法与反幂法

\qquad 已知 n × n n\times n n×n 矩阵 A = [ a i j ] A=[a_{ij}] A=[aij],矩阵 A A A特征多项式定义为:

φ ( λ ) = det ⁡ ( λ I − A ) = ∣ λ − a 11 − a 12 ⋯ − a 1 n − a 21 λ − a 22 ⋯ − a 2 n ⋮ ⋮ ⋱ ⋮ − a n 1 − a n 2 ⋯ λ − a n n ∣ \qquad\qquad\varphi(\lambda)=\det(\lambda\bold I-A)=\left|\begin{array}{cccc}\lambda-a_{11}&-a_{12}&\cdots&-a_{1n}\\-a_{21}&\lambda-a_{22}&\cdots&-a_{2n}\\ \vdots&\vdots&\ddots&\vdots \\-a_{n1}&-a_{n2}&\cdots&\lambda-a_{nn}\end{array}\right| φ(λ)=det(λIA)= λa11a21an1a12λa22an2a1na2nλann

\qquad 矩阵 A A A特征方程定义为:

φ ( λ ) = det ⁡ ( λ I − A ) = 0 \qquad\qquad\varphi(\lambda)=\det(\lambda\bold I-A)=0 φ(λ)=det(λIA)=0

( 1 ) \qquad(1) (1) 矩阵 A A A 的特征方程的解,即为特征值 (Eigenvalue) \text{(Eigenvalue)} (Eigenvalue)

\qquad   矩阵 A A A 的所有特征值的集合,记为 λ ( A ) \lambda(A) λ(A)

( 2 ) \qquad(2) (2) λ \lambda λ 为矩阵 A A A 的特征值,齐次方程 ( λ I − A ) x = 0 (\lambda\bold I-A)\boldsymbol x=0 (λIA)x=0 的非零解 x \boldsymbol x x 为矩阵 A A A 的对应于特征值 λ \lambda λ特征向量 (Eigenvector) \text{(Eigenvector)} (Eigenvector)
\qquad

1. 矩阵特征值界的估计

\qquad 考虑 n × n n\times n n×n 矩阵 A = [ a i j ] A=[a_{ij}] A=[aij],令:

{ r i = ∑ j = 1 j ≠ i n ∣ a i j ∣ , i = 1 , 2 , ⋯   , n D i = { z   ∣   ∣ z − a i j ∣ ≤ r i , z ∈ C } \qquad\qquad\begin{cases}r_i=\displaystyle\sum_{j=1 \atop j\neq i}^n\vert a_{ij}\vert ,\quad i=1,2,\cdots,n\\\\ D_i=\left\{z\ \Big|\ \vert z-a_{ij}\vert\le r_i,\quad z\in\mathbf C\right\} \end{cases} ri=j=ij=1naij,i=1,2,,nDi={z   zaijri,zC}

\qquad 称复平面上 a i i a_{ii} aii 为圆心、 r i r_i ri 为半径所有圆盘为矩阵 A A A Gerschgorin \text{Gerschgorin} Gerschgorin圆盘

\qquad
Gerschgorin圆盘定理 \textbf{Gerschgorin圆盘定理} Gerschgorin圆盘定理

( 1 ) \qquad(1) (1) 一个 n × n n\times n n×n 矩阵 A = [ a i j ] A=[a_{ij}] A=[aij] 的每一个特征值必定属于下述的某个圆盘中:

∣ λ − a i i ∣ ≤ r i = ∑ j = 1 j ≠ i n ∣ a i j ∣ , i = 1 , 2 , ⋯   , n \qquad\qquad\vert\lambda-a_{ii}\vert\le r_i=\displaystyle\sum_{j=1 \atop j\neq i}^n\vert a_{ij}\vert,\quad i=1,2,\cdots,n λaiiri=j=ij=1naij,i=1,2,,n

\qquad  或者说,矩阵 A A A 的特征值都在复平面上 n n n 个圆盘的并集中。

( 2 ) \qquad(2) (2) 如果矩阵 A A A m m m 个圆盘组成了一个连通的并集 S S S,且 S S S 与余下 n − m n-m nm 个圆盘是分离的,那么 S S S 内恰好包含矩阵 A A A m m m 个特征值。

\qquad  特别地,如果矩阵 A A A 的一个圆盘 D i D_i Di 与其它圆盘是分离的(孤立圆盘),那么圆盘 D i D_i Di 中精确地包含矩阵 A A A 的一个特征值。
\qquad
例 \textbf{例}
A = [ 4 1 0 1 0 − 1 1 1 − 4 ] ⟹ { D 1 = ∣ λ − 4 ∣ ≤ 1 D 2 = ∣ λ ∣ ≤ 2 D 3 = ∣ λ + 4 ∣ ≤ 2 \qquad A=\begin{bmatrix}4&1&0\\1&0&-1\\1&1&-4\end{bmatrix}\Longrightarrow\begin{cases}D_1=\vert \lambda-4\vert\le1\\D_2=\vert \lambda\vert\le2\\D_3=\vert \lambda+4\vert\le2 \end{cases} A= 411101014 D1=λ4∣1D2=λ2D3=λ+4∣2

\qquad 由于 D 1 D_1 D1 是孤立圆盘,可得到: 3 ≤ λ 1 ≤ 5 3\le\lambda_1\le5 3λ15
\qquad 矩阵 A A A 的三个特征值位于三个圆盘的并集中,即: λ i ∈ D 1 ∪ D 2 ∪ D 3 \lambda_i\in D_1\cup D_2\cup D_3 λiD1D2D3
\qquad

2. 幂法与反幂法

2.1 幂法

\qquad 假设 n × n n\times n n×n 矩阵 A = [ a i j ] A=[a_{ij}] A=[aij] 的特征值 λ i \lambda_i λi 所对应的特征向量为 x i \boldsymbol x_i xi,且特征值的排列满足:

∣ λ 1 ∣ > ∣ λ 2 ∣ ≥ ∣ λ 3 ∣ ≥ ⋯ ≥ ∣ λ n ∣ \qquad\qquad|\lambda_1|>|\lambda_2|\ge|\lambda_3|\ge\cdots\ge|\lambda_n| λ1>λ2λ3λn

\qquad 其中, λ 1 = max ⁡ i ∣ λ i ∣ \lambda_1=\displaystyle\max_i|\lambda_i| λ1=imaxλi主特征值,且为实数。

\qquad 幂法用来计算矩阵的主特征值 λ 1 \lambda_1 λ1 及对应特征向量 x 1 \boldsymbol x_1 x1,是一种迭代的方法。
\qquad

  • 幂法的基本思路

\qquad 任取一个非零的初始向量 v ( 0 ) \boldsymbol v^{(0)} v(0),构造出一个向量序列 { v ( k ) } \{\boldsymbol v^{(k)}\} {v(k)},也就是:

{ v ( 1 ) = A v ( 0 ) v ( 2 ) = A v ( 1 ) = A 2 v ( 0 ) ⋯ v ( k + 1 ) = A v ( k ) = A k + 1 v ( 0 ) ⋯ \qquad\qquad\begin{cases}\boldsymbol v^{(1)}=A\boldsymbol v^{(0)}\\ \boldsymbol v^{(2)}=A\boldsymbol v^{(1)}=A^2\boldsymbol v^{(0)} \\ \qquad\cdots \\ \boldsymbol v^{(k+1)}=A\boldsymbol v^{(k)}=A^{k+1}\boldsymbol v^{(0)} \\ \qquad\cdots \end{cases} v(1)=Av(0)v(2)=Av(1)=A2v(0)v(k+1)=Av(k)=Ak+1v(0)

\qquad 假设矩阵 A A A n n n 个特征向量 { x i } \{\boldsymbol x_i\} {xi} 线性无关,初始向量 v ( 0 ) \boldsymbol v^{(0)} v(0) 就可以表示为:

v ( 0 ) = α 1 x 1 + α 2 x 2 + ⋯ + α n x n \qquad\qquad\boldsymbol v^{(0)}=\alpha_1\boldsymbol x_1+\alpha_2\boldsymbol x_2+\cdots+\alpha_n\boldsymbol x_n v(0)=α1x1+α2x2++αnxn

\qquad 那么

v ( k ) = A k v ( 0 ) = α 1 A k x 1 + α 2 A k x 2 + ⋯ + α n A k x n = α 1 λ 1 k x 1 + α 2 λ 2 k x 2 + ⋯ + α n λ n k x n = λ 1 k [ α 1 x 1 + ∑ i = 2 n α i ( λ i λ 1 ) k x i ] \qquad\qquad\begin{aligned}\boldsymbol v^{(k)}&=A^k\boldsymbol v^{(0)}=\alpha_1A^k\boldsymbol x_1+\alpha_2A^k\boldsymbol x_2+\cdots+\alpha_nA^k\boldsymbol x_n\\ &=\alpha_1\lambda_1^k\boldsymbol x_1+\alpha_2\lambda_2^k\boldsymbol x_2+\cdots+\alpha_n\lambda_n^k\boldsymbol x_n\\ &=\lambda_1^k\left[\alpha_1\boldsymbol x_1+\displaystyle\sum_{i=2}^n\alpha_i\left(\dfrac{\lambda_i}{\lambda_1}\right)^k\boldsymbol x_i\right]\end{aligned} v(k)=Akv(0)=α1Akx1+α2Akx2++αnAkxn=α1λ1kx1+α2λ2kx2++αnλnkxn=λ1k[α1x1+i=2nαi(λ1λi)kxi]

( 1 ) \qquad(1) (1) 若记 ε k = ∑ i = 2 n α i ( λ i λ 1 ) k x i \boldsymbol\varepsilon_k=\displaystyle\sum_{i=2}^n\alpha_i\left(\dfrac{\lambda_i}{\lambda_1}\right)^k\boldsymbol x_i εk=i=2nαi(λ1λi)kxi,那么: v ( k ) = λ 1 k [ α 1 x 1 + ε k ] \textcolor{red}{\boldsymbol v^{(k)}=\lambda_1^k\left[\alpha_1\boldsymbol x_1+\boldsymbol\varepsilon_k\right]} v(k)=λ1k[α1x1+εk]

( 2 ) \qquad(2) (2) 由于 ∣ λ 1 ∣ > ∣ λ i ∣ ⟹ ∣ λ i λ 1 ∣ < 1 ( i = 2 , ⋯   , n ) |\lambda_1|>|\lambda_i|\quad\Longrightarrow\quad\left|\dfrac{\lambda_i}{\lambda_1}\right|<1\quad (i=2,\cdots,n) λ1>λi λ1λi <1(i=2,,n)
⟹ lim ⁡ k → ∞ ε k = 0 \qquad\qquad\qquad\qquad\qquad\quad\Longrightarrow\quad\displaystyle\lim_{\scriptscriptstyle k\to\infty}\boldsymbol\varepsilon_k=0 klimεk=0 (显然, ∣ λ 2 λ 1 ∣ \left|\frac{\lambda_2}{\lambda_1}\right| λ1λ2 越小,收敛越快)
⟹ lim ⁡ k → ∞ v ( k ) λ 1 k = α 1 x 1 \qquad\qquad\qquad\qquad\qquad\quad\Longrightarrow\quad\textcolor{red}{\displaystyle\lim_{\scriptscriptstyle k\to\infty}\dfrac{\boldsymbol v^{(k)}}{\lambda_1^k}=\alpha_1\boldsymbol x_1} klimλ1kv(k)=α1x1

\qquad\qquad 因此,迭代过程 v ( k + 1 ) = A v ( k ) \boldsymbol v^{(k+1)}=A\boldsymbol v^{(k)} v(k+1)=Av(k) 持续到 k k k 充分大时, v ( k ) ≈ α 1 λ 1 k x 1 \textcolor{royalblue}{\boldsymbol v^{(k)}\approx\alpha_1\lambda_1^k\boldsymbol x_1} v(k)α1λ1kx1
\qquad
( 3 ) \qquad(3) (3) v i k \boldsymbol v^k_i vik 表示 v ( k ) \boldsymbol v^{(k)} v(k) 的第 i i i 个分量,那么

v i k + 1 v i k = λ 1 α 1 x 1 i + ε k + 1 , i α 1 x 1 i + ε k , i ⟹ lim ⁡ k → ∞ v i k + 1 v i k = λ 1 \qquad\qquad\qquad\dfrac{\boldsymbol v^{k+1}_i}{\boldsymbol v^k_i}=\lambda_1\dfrac{\alpha_1\boldsymbol x_{1i}+\boldsymbol\varepsilon_{k+1,i}}{\alpha_1\boldsymbol x_{1i}+\boldsymbol\varepsilon_{k,i}}\quad\Longrightarrow\quad\textcolor{red}{\displaystyle\lim_{\scriptscriptstyle k\to\infty}\dfrac{\boldsymbol v^{k+1}_i}{\boldsymbol v^k_i}=\lambda_1} vikvik+1=λ1α1x1i+εk,iα1x1i+εk+1,iklimvikvik+1=λ1

\qquad\qquad\qquad 或者记为: v i k + 1 v i k → λ 1 \textcolor{royalblue}{\dfrac{\boldsymbol v^{k+1}_i}{\boldsymbol v^k_i}\rightarrow\lambda_1} vikvik+1λ1 (收敛速度由 ∣ λ 2 λ 1 ∣ \left|\frac{\lambda_2}{\lambda_1}\right| λ1λ2 确定)

\qquad\qquad 这就说明,相邻两个迭代向量的分量的比值收敛到主特征值。

\qquad

  • 主特征值的计算

\qquad 任取非零的初始向量 v ( 0 ) = u ( 0 ) ≠ 0 \boldsymbol v^{(0)}=\boldsymbol u^{(0)}\neq 0 v(0)=u(0)=0,构造向量序列

{ v ( 1 ) = A u ( 0 ) = A v ( 0 ) , u ( 1 ) = v ( 1 ) max ⁡ { v ( 1 ) } v ( 2 ) = A u ( 1 ) = A 2 v ( 0 ) max ⁡ { A v ( 0 ) } , u ( 2 ) = v ( 2 ) max ⁡ { v ( 2 ) } ⋯ ⋯ v ( k ) = A u ( k − 1 ) = A k v ( 0 ) max ⁡ { A k − 1 v ( 0 ) } , u ( k ) = v ( k ) max ⁡ { v ( k ) } \qquad\qquad\left\{\begin{array}{lc}\textcolor{red}{\boldsymbol v^{(1)}=A\boldsymbol u^{(0)}}=A\boldsymbol v^{(0)},&\boldsymbol u^{(1)}=\dfrac{\boldsymbol v^{(1)}}{\max\{\boldsymbol v^{(1)}\}}\\ \\ \textcolor{red}{\boldsymbol v^{(2)}=A\boldsymbol u^{(1)}}=\dfrac{A^2\boldsymbol v^{(0)}}{\max\{A\boldsymbol v^{(0)}\}},&\boldsymbol u^{(2)}=\dfrac{\boldsymbol v^{(2)}}{\max\{\boldsymbol v^{(2)}\}}\\ \\ \qquad\qquad\cdots&\cdots \\ \\ \textcolor{red}{\boldsymbol v^{(k)}=A\boldsymbol u^{(k-1)}}=\dfrac{A^k\boldsymbol v^{(0)}}{\max\{A^{k-1}\boldsymbol v^{(0)}\}},&\textcolor{mediumblue}{\boldsymbol u^{(k)}=\dfrac{\boldsymbol v^{(k)}}{\max\{\boldsymbol v^{(k)}\}}} \end{array}\right. v(1)=Au(0)=Av(0),v(2)=Au(1)=max{Av(0)}A2v(0),v(k)=Au(k1)=max{Ak1v(0)}Akv(0),u(1)=max{v(1)}v(1)u(2)=max{v(2)}v(2)u(k)=max{v(k)}v(k)

\qquad
\qquad 由于 v ( k ) ≈ α 1 λ 1 k x 1 \textcolor{royalblue}{\boldsymbol v^{(k)}\approx\alpha_1\lambda_1^k\boldsymbol x_1} v(k)α1λ1kx1,如果 ∣ λ 1 ∣ > 1 |\lambda_1|>1 λ1>1(或者 ∣ λ 1 ∣ < 1 |\lambda_1|<1 λ1<1),随着 k k k 值越来越大, λ 1 k \lambda_1^k λ1k 会趋于无穷(或趋于 0 0 0),从而造成计算过程溢出。

\qquad 因此,需要每次迭代时,需要将迭代向量 v ( k ) \boldsymbol v^{(k)} v(k) 规范化,也就是:

u ( k ) = v ( k ) max ⁡ { v ( k ) } \qquad\qquad\textcolor{mediumblue}{\boldsymbol u^{(k)}=\dfrac{\boldsymbol v^{(k)}}{\max\{\boldsymbol v^{(k)}\}}} u(k)=max{v(k)}v(k)

此处, max ⁡ { v ( k ) } \max\{\boldsymbol v^{(k)}\} max{v(k)} 表示迭代向量 v ( k ) \boldsymbol v^{(k)} v(k) 具有最大绝对值的分量

\qquad
幂法求主特征值

步骤 1 : 1: 1: k = 0 k=0 k=0 v ( 0 ) = u ( 0 ) ≠ 0 \boldsymbol v^{(0)}=\boldsymbol u^{(0)}\neq 0 v(0)=u(0)=0

步骤 2 : 2: 2: 计算 v ( k ) = A u ( k − 1 ) \boldsymbol v^{(k)}=A\boldsymbol u^{(k-1)} v(k)=Au(k1) μ ( k ) = max ⁡ { v ( k ) } \mu^{(k)}=\max\{\boldsymbol v^{(k)}\} μ(k)=max{v(k)}

步骤 3 : 3: 3: 计算 u ( k ) = v ( k ) μ ( k ) \boldsymbol u^{(k)}=\dfrac{\boldsymbol v^{(k)}}{\mu^{(k)}} u(k)=μ(k)v(k)(当 k → ∞ k\to\infty k,那么 μ ( k ) → λ 1 \mu^{(k)}\to\lambda_1 μ(k)λ1

重复执行步骤 ( 2 ) (2) (2) ( 3 ) (3) (3),直到 ∣ μ ( k ) − μ ( k − 1 ) ∣ < ε |\mu^{(k)}-\mu^{(k-1)}|<\varepsilon μ(k)μ(k1)<ε,得到主特征值的估计 λ ^ 1 = μ ( k ) \hat\lambda_1=\mu^{(k)} λ^1=μ(k)

\qquad
例1 \textcolor{red}{\textbf{例1}} 1:用幂法求 A = [ 1 1 0.5 1 1 0.25 0.5 0.25 2 ] A=\left[\begin{matrix}1&1&0.5\\1&1&0.25\\0.5&0.25&2\end{matrix}\right] A= 110.5110.250.50.252 的主特征值及对应的特征向量。

import numpy as np
def eig_power(A,v0,eps):
    uk = v0
    flag = 1
    val_old = 0
    n = 0
    while flag:
        n = n+1
        vk = A*uk        
        val = vk[np.argmax(np.abs(vk))]        
        uk = vk/val              
        if (np.abs(val-val_old)<eps):
            flag = 0
        val_old = val
        print(np.asarray(uk).flatten(),val)
    print('max eigenvalue:',val)
    print('eigenvector:',np.asarray(uk).flatten())
    print('iteration:',n)
    return val, uk  
    
if __name__ == '__main__':
    A = np.matrix([[1,   1,      0.5],
                   [1,   1,      0.25],
                   [0.5,   0.25,   2.0]], dtype='float')
    v0 = np.matrix([[1],[1],[1]], dtype='float')
    eps = 1e-10
    val,uk = eig_power(A,v0,eps)

计算结果:

max eigenvalue: 2.536526
eigenvector: [0.74822115 0.64966114 1.        ]
iteration: 41

2.2 幂法的加速方法

1.   原点平移法 \textcolor{red}{\textbf{1. 原点平移法}} 1. 原点平移法

( 1 ) \qquad(1) (1) ∣ λ 2 λ 1 ∣ \left|\dfrac{\lambda_2}{\lambda_1}\right| λ1λ2 的值接近于 1 1 1,也就是 λ 1 \lambda_1 λ1 λ 2 \lambda_2 λ2 的值比较接近,就会导致 v i k + 1 v i k → λ 1 \textcolor{royalblue}{\dfrac{\boldsymbol v^{k+1}_i}{\boldsymbol v^k_i}\rightarrow\lambda_1} vikvik+1λ1 的收敛速度变慢。

( 2 ) \qquad(2) (2) 为了加快收敛速度,可以人为地拉大 λ 1 \lambda_1 λ1 λ 2 \lambda_2 λ2 的距离,也就是让 ∣ λ 2 λ 1 ∣ \left|\dfrac{\lambda_2}{\lambda_1}\right| λ1λ2 的值能够尽可能地偏离 1 1 1,达到加快收敛速度的目的。

\qquad 为此,引入矩阵 B = A − p I B=A-p\bold I B=ApI,可得到矩阵 B B B 的特征值为 λ 1 − p , λ 2 − p , ⋯   , λ n − p \lambda_1-p,\lambda_2-p,\cdots,\lambda_n-p λ1p,λ2p,,λnp。如果能够选择合适的 p p p 值,使得:

∣ λ 2 − p λ 1 − p ∣ < ∣ λ 2 λ 1 ∣ \qquad\qquad\left|\dfrac{\lambda_2-p}{\lambda_1-p}\right|<\left|\dfrac{\lambda_2}{\lambda_1}\right| λ1pλ2p < λ1λ2

\qquad 此时,对矩阵 B B B 应用幂法求出 λ 1 − p \lambda_1-p λ1p 的速度,会比直接用矩阵 A A A λ 1 \lambda_1 λ1 更快。因此,选择一个合适的 p p p 值非常关键。

\qquad
例2 \textcolor{red}{\textbf{例2}} 2:用原点平移法求 A = [ 1 1 0.5 1 1 0.25 0.5 0.25 2 ] A=\left[\begin{matrix}1&1&0.5\\1&1&0.25\\0.5&0.25&2\end{matrix}\right] A= 110.5110.250.50.252 的主特征值及对应的特征向量。

import numpy as np
def eig_power(A,v0,eps,p):
    uk = v0
    flag = 1
    val_old = 0
    n = 0
    A = A-p*np.eye(len(A))
    while flag:
        n = n+1
        vk = A*uk        
        val = vk[np.argmax(np.abs(vk))]        
        uk = vk/val       
        if (np.abs(val-val_old)<eps):
            flag = 0
        val_old = val
        print(np.asarray(uk).flatten(),val)
    print('max eigenvalue:',val+p)
    print('eigenvector:',np.asarray(uk).flatten())
    print('iteration:',n)
    return val+p, uk  
    
if __name__ == '__main__':
    A = np.matrix([[1,   1,      0.5],
                   [1,   1,      0.25],
                   [0.5,   0.25,   2.0]], dtype='float')
    v0 = np.matrix([[1],[1],[1]], dtype='float')
    eps = 1e-10
    val,uk = eig_power(A,v0,eps,0.75)

计算结果:

max eigenvalue: 2.536526
eigenvector: [0.74822115 0.64966114 1.        ]
iteration: 26			对比例1结果,直接采用幂法需要迭代41

\qquad
2.   Rayleigh商加速法 \textcolor{red}{\textbf{2. Rayleigh商加速法}} 2. Rayleigh商加速法

\qquad 假设 n × n n\times n n×n 对称矩阵 A A A 的特征值满足: ∣ λ 1 ∣ > ∣ λ 2 ∣ ≥ ∣ λ 3 ∣ ≥ ⋯ ≥ ∣ λ n ∣ |\lambda_1|>|\lambda_2|\ge|\lambda_3|\ge\cdots\ge|\lambda_n| λ1>λ2λ3λn,规范化向量 u ( k ) \boldsymbol u^{(k)} u(k) 的瑞利商可以给出主特征值 λ 1 \lambda_1 λ1 更好的近似:

( A u ( k ) , u ( k ) ) ( u ( k ) , u ( k ) ) = λ 1 + O ( ( λ 2 λ 1 ) 2 k ) \qquad\qquad\dfrac{(A\boldsymbol u^{(k)},\boldsymbol u^{(k)})}{(\boldsymbol u^{(k)},\boldsymbol u^{(k)})}=\lambda_1+O\left(\left(\dfrac{\lambda_2}{\lambda_1}\right)^{2k}\right) (u(k),u(k))(Au(k),u(k))=λ1+O((λ1λ2)2k)

\qquad
例3 \textcolor{red}{\textbf{例3}} 3:用 Rayleigh \text{Rayleigh} Rayleigh商加速法求 A = [ 1 1 0.5 1 1 0.25 0.5 0.25 2 ] A=\left[\begin{matrix}1&1&0.5\\1&1&0.25\\0.5&0.25&2\end{matrix}\right] A= 110.5110.250.50.252 的主特征值及对应的特征向量。

import numpy as np
def eig_power(A,v0,eps):
    uk = v0
    flag = 1
    val_old = 0
    n = 0
    while flag:
        n = n+1
        vk = A*uk
        t = ((A*uk).T*uk)/(uk.T*uk)        
        val = t[0,0]   
        uk = vk/val     
        if (np.abs(val-val_old)<eps):
            flag = 0
        val_old = val   
        print(np.asarray(uk).flatten(),val)
    print('max eigenvalue:',val)
    print('eigenvector:',np.asarray(uk).flatten())
    print('iteration:',n)
    return val, uk 
    
if __name__ == '__main__':
    A = np.matrix([[1,   1,      0.5],
                   [1,   1,      0.25],
                   [0.5,   0.25,   2.0]], dtype='float')
    v0 = np.matrix([[1],[1],[1]], dtype='float')
    eps = 1e-10
    val,uk = eig_power(A,v0,eps)

计算结果:

max eigenvalue: 2.5365258603724308
eigenvector: [0.92496879 0.80312773 1.23621526]
iteration: 20		对比例1和例2结果,直接采用幂法需要迭代41次,p=0.75原点加速法需要26

2.3 反幂法

\qquad 与幂法的思路一样,反幂法可以计算最小模值的特征值及其特征向量。

\qquad 仍然假设 n × n n\times n n×n 矩阵 A = [ a i j ] A=[a_{ij}] A=[aij] 的特征值 λ i \lambda_i λi 所对应的特征向量为 x i \boldsymbol x_i xi,且特征值的排列满足:

∣ λ 1 ∣ ≥ ∣ λ 2 ∣ ≥ ∣ λ 3 ∣ ≥ ⋯ ≥ ∣ λ n ∣ > 0 \qquad\qquad|\lambda_1|\ge|\lambda_2|\ge|\lambda_3|\ge\cdots\ge|\lambda_n|>0 λ1λ2λ3λn>0

\qquad 那么, A − 1 A^{-1} A1 的特征值满足:

∣ 1 λ n ∣ ≥ ∣ 1 λ n − 1 ∣ ≥ ∣ 1 λ n − 2 ∣ ≥ ⋯ ≥ ∣ 1 λ 1 ∣ \qquad\qquad\left|\dfrac{1}{\lambda_n}\right|\ge\left|\dfrac{1}{\lambda_{n-1}}\right|\ge\left|\dfrac{1}{\lambda_{n-2}}\right|\ge\cdots\ge\left|\dfrac{1}{\lambda_1}\right| λn1 λn11 λn21 λ11

\qquad 对矩阵 A − 1 A^{-1} A1 使用幂法,也就是“反幂法”,可以计算矩阵 A − 1 A^{-1} A1 的主特征值 1 λ n \dfrac{1}{\lambda_n} λn1,也就是矩阵 A A A 的模值最小的特征值。

\qquad
反幂法求最小模值特征值

步骤 1 : 1: 1: k = 0 k=0 k=0 v ( 0 ) = u ( 0 ) ≠ 0 \boldsymbol v^{(0)}=\boldsymbol u^{(0)}\neq 0 v(0)=u(0)=0

步骤 2 : 2: 2: 计算 v ( k ) = A − 1 u ( k − 1 ) \boldsymbol v^{(k)}=A^{-1}\boldsymbol u^{(k-1)} v(k)=A1u(k1) μ ( k ) = max ⁡ { v ( k ) } \mu^{(k)}=\max\{\boldsymbol v^{(k)}\} μ(k)=max{v(k)}

\qquad   其中, v ( k ) \boldsymbol v^{(k)} v(k) 可通过解线性方程组 A v ( k ) = u ( k − 1 ) A\boldsymbol v^{(k)}=\boldsymbol u^{(k-1)} Av(k)=u(k1) 求得

反幂法同样可以采用“原点加速法”:
采用原点加速法时, v ( k ) = ( A − p I ) − 1 u ( k − 1 ) \boldsymbol v^{(k)}=(A-p\bold I)^{-1}\boldsymbol u^{(k-1)} v(k)=(ApI)1u(k1)
通过解线性方程组 ( A − p I ) v ( k ) = u ( k − 1 ) (A-p\bold I)\boldsymbol v^{(k)}=\boldsymbol u^{(k-1)} (ApI)v(k)=u(k1) 求得 v ( k ) \boldsymbol v^{(k)} v(k)

步骤 3 : 3: 3: 计算 u ( k ) = v ( k ) μ ( k ) \boldsymbol u^{(k)}=\dfrac{\boldsymbol v^{(k)}}{\mu^{(k)}} u(k)=μ(k)v(k)(当 k → ∞ k\to\infty k,那么 μ ( k ) → 1 λ n \mu^{(k)}\to\dfrac{1}{\lambda_n} μ(k)λn1

重复执行步骤 ( 2 ) (2) (2) ( 3 ) (3) (3),直到 ∣ μ ( k ) − μ ( k − 1 ) ∣ < ε |\mu^{(k)}-\mu^{(k-1)}|<\varepsilon μ(k)μ(k1)<ε,得到最小模值特征值的估计 λ ^ n = 1 μ ( k ) \hat\lambda_n=\dfrac{1}{\mu^{(k)}} λ^n=μ(k)1

\qquad
例4 \textcolor{red}{\textbf{例4}} 4:用反幂法求 A = [ 2 1 0 1 3 1 0 1 4 ] A=\left[\begin{matrix}2&1&0\\1&3&1\\0&1&4\end{matrix}\right] A= 210131014 的对应于 λ = 1.2679 \lambda=1.2679 λ=1.2679 的特征向量。

import numpy as np   
def eig_invpower(A,v0,eps,p=0):
    uk = v0
    flag = 1
    val_old = 0
    n = 0
    if p!=0:
        A = A-p*np.eye(len(A))
    LU,La,Ua,order0,order1 = Doolittle_pivot(np.asarray(A))   # PA=LU
    while flag:
        n = n+1        
        vk = solveLineq(La,Ua,np.asarray(uk)[order1,:])      
        val = vk[np.argmax(np.abs(vk))]        
        uk = np.asmatrix(vk.reshape(len(A),1))/val        
        print(np.asarray(uk).flatten())
        if (np.abs(1/val-val_old)<eps):
            flag = 0
        val_old = 1/val
    print('min eigenvalue:',1/val+p)
    print('eigenvector:',np.asarray(uk).flatten())
    print('iteration:',n)
    return 1/val+p, uk   

def Doolittle_pivot(A):  # A为np.array,而不是np.matrix
    n = len(A)
    LU = A.copy()
    order1 = np.arange(n)
    for r in range(n):        
        ut = LU[:r,r].reshape(r,1)
        si = A[r:,r] - np.sum(ut*LU[r:,:r].T,axis=0)
        ir = np.argmax(np.abs(si))
        if ir!=0:
            LU[[r,r+ir],:] = LU[[r+ir,r],:]
            order1[[r,r+ir]] = order1[[r+ir,r]]        
        lt = LU[r,:r].reshape(r,1)
        LU[r,r:] = LU[r,r:] - np.sum(lt*LU[:r,r:],axis=0)        
        if r==n-1:
            continue
        LU[r+1:,r] = (LU[r+1:,r] - np.sum(ut*LU[r+1:,:r].T,axis=0))/LU[r,r]       
    U = np.triu(LU)
    L = np.tril(LU) - np.diag(np.diag(LU)) + np.eye(n)
    order0 = []
    [order0.insert(i,np.where(order1==i)[0][0]) for i in range(n)]        
    return LU,L,U,order0,order1

def solveLineq(L,U,b):  # b为np.array,而不是np.matrix
    rows = len(b)
    y = np.zeros(rows)
    y[0] = b[0]/L[0,0]
    for k in range(1,rows):
        y[k] = (b[k] - np.sum(L[k,:k]*y[:k]))/L[k,k]      
    x = np.zeros(rows)
    k = rows-1
    x[k] = y[k]/U[k,k] 
    for k in range(rows-2,-1,-1):
        x[k] = (y[k] - np.sum(x[k+1:]*U[k,k+1:]))/U[k,k]    
    return x    
    
if __name__ == '__main__':
    A = np.matrix([[2,   1,   0],
                   [1,   3,   1],
                   [0,   1,   4]], dtype='float')    
    v0 = np.matrix([[1],[1],[1]], dtype='float')
    eps = 1e-10
    val,uk = eig_invpower(A,v0,eps,1.2679)

计算结果:

A:
 [[0.7321 1.     0.    ]
 [1.     1.7321 1.    ]
 [0.     1.     2.7321]]
L:
 [[ 1.          0.          0.        ]
 [ 0.          1.          0.        ]
 [ 0.7321     -0.26807041  1.        ]]
U:
 [[1.         1.7321     1.        ]
 [0.         1.         2.7321    ]
 [0.         0.         0.00029517]]
L*U:
 [[0.7321 1.     0.    ]
 [1.     1.7321 1.    ]
 [0.     1.     2.7321]]
v1: [ 6776.39884879 -4960.0015972   1815.81991772]
u1: [ 1.         -0.73195243  0.26796237]
v2: [ 20327.46459393 -14880.73682922   5446.72771553]
u2: [ 1.         -0.73205081  0.26794919]
v3: [ 20328.33052096 -14881.37077439   5446.95974656]
u3: [ 1.         -0.73205081  0.26794919]
v4: [ 20328.33054145 -14881.3707894    5446.95975206]
u4: [ 1.         -0.73205081  0.26794919]
min eigenvalue: 1.2679491924311228
eigenvector: [ 1.         -0.73205081  0.26794919]
iteration: 4

【注】:选主元的三角分解求解线性方程组,请参考《解线性方程组的python实现(2)——矩阵三角分解法》 3 3 3部分。
\qquad

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值