幂法(指数迭代法)

  幂法是通过迭代来计算矩阵的主特征值(按模最大的特征值)与其对应特征向量的方法,适合于用于大型稀疏矩阵。

幂法定义

  设$A = (a_{ij})\in R^{n\times n}$,其特征值为$\lambda_i$,对应特征向量$x_i(i=1,...,n)$,即$Ax_i = \lambda_i x_i(i=1,...,n)$,且$\{x_1,...,x_n\}$线性无关。

  任取一个非零向量$v_0\in R^{n}$,且$v_0\ne 0$,构造一个关于矩阵$A$的乘幂的向量序列:

$v_k = Av_{k-1}=A^2v_{k-2}=A^3v_{k-3}=...=A^kv_{0}$

  称$v_k$为迭代向量。

  设特征值$\lambda_i$的前$r$个为绝对值最大的特征值(ppt中分为$\lambda_1$强占优和非强占优,感觉没必要),即有:

$|\lambda_1|=|\lambda_2|=...=|\lambda_r|>|\lambda_{r+1}|\ge...\ge|\lambda_n|$

  由于$\{x_1,...,x_n\}$ 线性无关,所以构成$R^n$的一个基,于是$v_0$能被表达为:

$v_0=\sum\limits_{i=1}^{n}\alpha_i x_i$(且设$\alpha_1...\alpha_r$非全零)

   由$Ax_i = \lambda_i x_i$:

$v_k = Av_{k-1}=...=A^kv_{0}=\sum\limits_{i=1}^{n}A^k\alpha_i x_i=\sum\limits_{i=1}^{n}\lambda_i^k\alpha_i x_i=\lambda_1^k(\sum\limits_{i=1}^{r}\alpha_ix_i+\varepsilon_k)$

  其中:

$\varepsilon_k = \sum\limits_{i=r+1}^{n}(\frac{\lambda_i}{\lambda_1})^k\alpha_ix_i$ 

  因为$\lambda_1$最大,所以有$|\frac{\lambda_i}{\lambda_1}|<1 (i=r+1,...,n)$,从而有:

$\lim\limits_{k\to \infty}(\frac{\lambda_i}{\lambda_1})^k=0 (i=r+1,...,n)$

  所以有:

$\lim\limits_{k\to \infty}\varepsilon_k = 0$

$\lim\limits_{k\to \infty}v_k = \lim\limits_{k\to \infty}\lambda_1^k(\sum\limits_{i=1}^{r}\alpha_ix_i+\varepsilon_k) = \lim\limits_{k\to \infty}\lambda_1^k(\sum\limits_{i=1}^{r}\alpha_ix_i)$

  因为在上式中$(\sum\limits_{i=1}^{r}\alpha_ix_i)$是固定项,可以看出,迭代到后期,$v_{k+1}$和$v_k$的各个元素有固定比值$\lambda_1$,即:

$\lim\limits_{k\to \infty}\frac{(v_{k+1})_i}{(v_{k})_i} = \lambda_1$

  这样,收敛到主特征值后,还可另外计算它对应的一个特征向量(其实就是构成$v_0$的前$r$项之和,而且只能算一个):

$\lim\limits_{k\to \infty}\frac{v_{k}}{\lambda_1^k} = \sum\limits_{i=1}^{r}\alpha_ix_i$

  其中收敛速度由比值$|\frac{\lambda_{r+1}}{\lambda_1}|$决定,越小收敛越快。

 幂法改进

  以上定义中,随着不断的迭代,如果$|\lambda_1|>1$,$v_k$会无限大;如果$|\lambda_1|<1$,$v_k$则会趋于0。在计算机中就会导致溢出而出错。当然如果$|\frac{\lambda_{r+1}}{\lambda_1}|$很小,使得$\varepsilon_k$能快速收敛为0,并且$|\lambda_1|$不会太大或太小以至于在$\varepsilon_k$收敛前$v_k$就溢出了,那用上述方法就行了。

  但是通常不会碰到那么好的运气,所以就在每次迭代的时候就要对$v_k$进行“规范化”,防止它溢出。规范化就是将向量除以一个标量,使向量的长度为1,而向量的长度有多种度量法,比如$||\cdot||_2、||\cdot||_\infty$等。一般使用$||\cdot||_\infty$,就是向量各个分量的绝对值的最大值(用别的也一样,但是这个复杂度最小,计算机最好算)。

  为了便于理解,将一次迭代分为两步,一步乘矩阵$A$,一步除以向量长度进行规范化:

迭代序号  乘$A$($v_i$) 规范化($u_i$)
初始化 随机取$v_0=\sum\limits_{i=0}^{n}\alpha_ix_i$ $u_0=\frac{v_0}{||v_0||}$
1 $v_1=Au_0=\frac{Av_0}{\left\|v_0\right\|}$ $u_1=\frac{v_1}{||v_1||}=\frac{\frac{Av_0}{\left\|v_0\right\|}}{\left\|\frac{Av_0}{\left\|v_0\right\|}\right\|}=\frac{Av_0}{\left\|Av_0\right\|}$
2 $v_2=Au_1=\frac{A^2v_0}{\left\|Av_0\right\|}$ $u_2=\frac{v_2}{||v_2||}=\frac{\frac{A^2v_0}{\left\|Av_0\right\|}}{\left\|\frac{A^2v_0}{\left\|Av_0\right\|}\right\|}=\frac{A^2v_0}{\left\|A^2v_0\right\|}$
... ... ...
k $v_k=Au_{k-1}=\frac{A^kv_0}{\left\|A^{k-1}v_0\right\|}$ $u_k=\frac{v_k}{||v_k||}=\frac{\frac{A^kv_0}{\left\|A^{k-1}v_0\right\|}}{\left\|\frac{A^kv_0}{\left\|A^{k-1}v_0\right\|}\right\|}=\frac{A^kv_0}{\left\|A^kv_0\right\|}$
... ... ...

  根据迭代,以下计算主特征值和对应的特征向量。

主特征值  

  对于向量序列${v_k}$:

$v_k=\frac{A^kv_0}{\left\|A^{k-1}v_0\right\|}=\frac{\lambda_1^k(\sum\limits_{i=1}^{r}\alpha_ix_i+\varepsilon_k)}{\left\|\lambda_1^{k-1}(\sum\limits_{i=1}^{r}\alpha_ix_i+\varepsilon_{k-1})\right\|}$

  对$v_k$取范数:

$||v_k||=\frac{\left\|\lambda_1^k(\sum\limits_{i=1}^{r}\alpha_ix_i+\varepsilon_k)\right\|}{\left\|\lambda_1^{k-1}(\sum\limits_{i=1}^{r}\alpha_ix_i+\varepsilon_{k-1})\right\|}=|\lambda_1|\frac{\left\|\sum\limits_{i=1}^{r}\alpha_ix_i+\varepsilon_k\right\|}{\left\|\sum\limits_{i=1}^{r}\alpha_ix_i+\varepsilon_{k-1}\right\|}\to\left|\lambda_1\right|, (k\to\infty)$

  注意!在计算机中并不是直接通过这个极限$k\to\infty$来计算,而是通过上面表格的迭代来实现$k\to\infty$,由于每一步的“规范化”,才能使得计算成为可能。而且如果直接用这个极限算的话就和前面的没区别了,“规范化”的优势没有用起来。

  另外,因为算范数的时候是先取向量分量的绝对值再算的,所以改进后的方法计算出来的主特征值不可避免带有绝对值,因此特征值的符号还要再判断一下(下面判断)。而改进之前的是不带的(因为没有计算范数进行规范化),如果符合条件,改进之前的也可一试。

主特征值对应的一个特征向量

  观察向量$u_k$:

$u_k=\frac{A^kv_0}{\left\|A^kv_0\right\|}=\frac{\lambda_1^k(\sum\limits_{i=1}^{r}\alpha_ix_i+\varepsilon_k)}{\left\|\lambda_1^{k}(\sum\limits_{i=1}^{r}\alpha_ix_i+\varepsilon_{k})\right\|}\to{\rm sign}(\lambda_1^k)\frac{\sum\limits_{i=1}^{r}\alpha_ix_i}{\left\|\sum\limits_{i=1}^{r}\alpha_ix_i\right\|},(k\to\infty)$

  如上,通过$u_k$可获得一个单位化的主特征值特征向量。因为还乘上了$\lambda_1^k$的符号,所以向量各个分量的符号和迭代的次数$k$有关。当$k$足够大(使迭代收敛),连续两次迭代,$u_k$的分量的符号不变时,则可以判断主特征值符号为正,否则为负,从而解决了上面主特征值符号未知的问题。

  另外,求出的单位特征向量(如果用L2范数)是主特征值的所有不相关特征向量的线性组合,与设置的$v_0$有关。当然如果主特征值的没有重根,且$\alpha_1$不为零(为零的话就迭代出第二大的特征值),规范化后得出的都是同一个特征向量(如果特征值为负,符号可能随迭代次数改变)。

Python代码

 1 import numpy as np
 2 
 3 #矩阵A
 4 A = np.matrix(
 5     [[-5.6,2.,0.],
 6     [3.,-1.,1.],
 7     [0.,1.,3.]])
 8 L0=2#范数类型
 9 v = np.matrix([[-2.],[-7.],[1.]])#v0
10 u = v/(np.linalg.norm(v,L0))#u0
11 
12 #迭代函数
13 def iterate_fun(A,u,final,L):
14     i=0
15     while i<final: 
16         v = A*u
17         u = v/(np.linalg.norm(v,L))
18         i=i+1
19     print("幂法特征值:")
20     print(np.linalg.norm(v,L))
21     print("numpy特征值:")
22     print(np.linalg.eig(A)[0])
23     print("幂法特征向量:")
24     print(u)
25     print("numpy特征向量:")
26     print(np.linalg.eig(A)[1])
27 
28 iterate_fun(A,u,1010,L0)

  结果截图:

  主特征值与numpy算出来绝对值一致。这里用的是L2范数,且主特征值无重根,所以计算出来的特征向量单位化后和numpy主特征值对应的向量除符号外相同。

猜你喜欢

转载自www.cnblogs.com/qizhou/p/12271287.html