矩阵特征值计算的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(λI−A)= λ−a11−a21⋮−an1−a12λ−a22⋮−an2⋯⋯⋱⋯−a1n−a2n⋮λ−ann
\qquad 矩阵 A A A 的特征方程定义为:
φ ( λ ) = det ( λ I − A ) = 0 \qquad\qquad\varphi(\lambda)=\det(\lambda\bold I-A)=0 φ(λ)=det(λI−A)=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
(λI−A)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=1∑n∣aij∣,i=1,2,⋯,nDi={z ∣z−aij∣≤ri,z∈C}
\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 ∣λ−aii∣≤ri=j=ij=1∑n∣aij∣,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 n−m 个圆盘是分离的,那么 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=
4111010−1−4
⟹⎩
⎨
⎧D1=∣λ−4∣≤1D2=∣λ∣≤2D3=∣λ+4∣≤2
\qquad
由于
D
1
D_1
D1 是孤立圆盘,可得到:
3
≤
λ
1
≤
5
3\le\lambda_1\le5
3≤λ1≤5
\qquad
矩阵
A
A
A 的三个特征值位于三个圆盘的并集中,即:
λ
i
∈
D
1
∪
D
2
∪
D
3
\lambda_i\in D_1\cup D_2\cup D_3
λi∈D1∪D2∪D3
\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=2∑nα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=2∑nα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
⟹k→∞limε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}
⟹k→∞limλ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,i⟹k→∞limvikvik+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(k−1)=max{Ak−1v(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(k−1), μ ( 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)−μ(k−1)∣<ε,得到主特征值的估计 λ ^ 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=A−pI,可得到矩阵 B B B 的特征值为 λ 1 − p , λ 2 − p , ⋯ , λ n − p \lambda_1-p,\lambda_2-p,\cdots,\lambda_n-p λ1−p,λ2−p,⋯,λn−p。如果能够选择合适的 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| λ1−pλ2−p < λ1λ2
\qquad 此时,对矩阵 B B B 应用幂法求出 λ 1 − p \lambda_1-p λ1−p 的速度,会比直接用矩阵 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} A−1 的特征值满足:
∣ 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 ≥ λn−11 ≥ λn−21 ≥⋯≥ λ11
\qquad 对矩阵 A − 1 A^{-1} A−1 使用幂法,也就是“反幂法”,可以计算矩阵 A − 1 A^{-1} A−1 的主特征值 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)=A−1u(k−1), μ ( 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(k−1) 求得
反幂法同样可以采用“原点加速法”:
采用原点加速法时, v ( k ) = ( A − p I ) − 1 u ( k − 1 ) \boldsymbol v^{(k)}=(A-p\bold I)^{-1}\boldsymbol u^{(k-1)} v(k)=(A−pI)−1u(k−1)
通过解线性方程组 ( A − p I ) v ( k ) = u ( k − 1 ) (A-p\bold I)\boldsymbol v^{(k)}=\boldsymbol u^{(k-1)} (A−pI)v(k)=u(k−1) 求得 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)−μ(k−1)∣<ε,得到最小模值特征值的估计 λ ^ 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