最近在做科研的时候需要快速地解一个大型稀疏矩阵最小的几个特征值和对应的特征向量,经过文献调研发现 Arnoldi iteration 方法可以应用到这上面来。我花了一些时间了解 Arnoldi iteration 以及与其相关的 Lanczos iteration、Krylov 子空间,在这里整理一下。
从幂法讲起
我们知道,求解一个 n×n 矩阵 A 的最大特征值和对应的特征向量可以使用幂法(power method)。具体地,我们迭代地计算并归一化序列
x,Ax,A2x,…
在第 k 步迭代时,我们可以得到 x(k)=Akx/∥Akx∥,随着 k 的增大,我们得到的 x(k) 也将收敛于最大特征值对应的特征向量。
听起来很好,对吧?但是仔细一想,我们进行了多次迭代,最终只用到了最后的结果来得到输出,前面的所有迭代是否浪费了?如果利用前面的迭代,我们对特征向量的估计能否更加准确,或者说具有输出多个特征值对应的特征向量的近似值的能力?
想要回答这个问题,就需要来研究序列 x,Ax,A2x,…。事实上,这个序列在数学上有其对应的名字,这个序列的前 r 个向量张成 Krylov 子空间(假设 r<=m)
Kr(x)=Kr(x,A)≜span{x,Ax,A2x,⋯,Ar−1x}=R(Kr(x))⊂Fn.
下面我们看如何基于这个子空间来近似求解矩阵 A 的特征值和特征向量。
Rayleigh-Ritz 法求特征值的近似
我们可以利用 Gram-Schmidt 正交化方法提取上述子空间的一组单位正交基 V∈Fn×r,然后即可得到 A 在基 V 下的投影矩阵
T=V∗AV∈Fj×j,
对 T 做特征值分解,可以得到
TY=YΛT,
其中 Y 的各列 y1,…,yr 为 T 的特征向量,对应 ΛT 的对角线元素(特征值)。
能否用 T 的特征值来近似代替 A 的特征值?幸运的是,答案是肯定的,这样的方法称作 Rayleigh-Ritz 方法。设 T 的特征值和特征向量分别为 μi 和 yi(1≤i≤r),那么我们可以用 λ~i=μi 来近似表示 A 的第 i 个特征值,用 x~i=Vyi 来表示该特征值对应的特征向量。
如果投影向量 V 恰巧是由 A 的 r 个特征向量 x1,x2,…,xr 张成的空间的单位正交基,那么可以证明求得的 λ~i 和 x~i 和 A 的特征值和特征向量完全相同。此时存在单位正交矩阵 P∈Fr×r,使得
V=XP,
因此
T=V∗AV=P∗X∗AXP=P∗ΛAP,
因此 T 和 A 具有相同的特征值,即 μi 也是 A 的特征值。进一步,
yi∗V∗AVyi=∥Vyi∥2yi∗V∗AVyi=μi,
因此 x~i=Vyi 也是 A 的特征向量。
由此可以预见,近似特征值和特征向量的 Rayleigh-Ritz 方法的精度取决于 V 的精度,即 V 是否包含了我们想要的特征值和特征向量。幸运的是,Krylov 子空间近似为 A 的最大的几个特征值所张成,这让我们能够以较高的精度来近似。
Arnoldi / Lanczos 分解
Arnoldi 分解 和 Lanczos 分解 都是计算 Krylov 子空间的单位正交基 V 的高效算法,尤其适用于大型稀疏的 A。其中,Lanczos 方法是 Arnoldi 方法的一个特例,当 A 是埃尔米特矩阵(Hermitian)时 Arnoldi 方法变为 Lanczos 方法,更加高效。
下面是 Arnoldi 分解的步骤:
- 选择一个随机的向量 v1,要求 ∥v1∥=1。
- 对于所有的 j=1,…,r−1,
- 令 wj+1′=Avj
- 对于所有的 k=1,…,j,令 Tk,j=vk∗wj+1′
- 令 wj+1=wj+1′−∑k=1jTk,jvk
- 令 Tj+1,j=∥wj+1∥
- 若 Tj+1,j=0,令 vj+1=wj+1/Tj+1,j;否则,选择任意一个模长为 1 且对称于 v1,…,vj 的向量作为 vj+1
由此方法得到的各个 vi 构成单位正交基,且 T=V∗AV。通过 Arnoldi 分解得到的正交基 V 可以让进一步得到的矩阵 T 为上 Hessenberg 型1矩阵。当矩阵 A 为 Hermitian 时,T 进一步简化为三对角矩阵。Hessenberg 矩阵的特征值可以高效地求得,如使用 QR 分解;再加上 T 的大小仅为 r×r,当 r≪n 时这种算法将会相当高效。
在实践中,我们往往发现通过 Arnoldi 方法得到的 Ritz 特征值能够接近 A 的部分特征值,一般来说特别是最大的几个特征值们。下图是一个摘自维基百科的 Arnoldi 方法求一个 400×400 大小的矩阵的特征值的动图示例,红点为 Ritz 特征值,黑点为实际特征值——
Implicitly Restarted Arnoldi / Lanczos Method
前面提到,Arnoldi 分解可以用来高效地近似部分矩阵的特征值和特征向量。但是,普通的 Arnoldi 方法可能会遇到数值问题,且精度不够。Implicitly Restarted Arnoldi Method(IRAM)算法可以看作是对其的改进(当输入矩阵为 Hermitian 时,变为 IRLM)。
简单来讲,IRAM 通过多次重启 Arnoldi 分解来让求得的特征值近似每次重启都变得更好。每次重启中,IRAM 都会尝试去掉特征值中不满足要求的部分。这样,经过多次重启之后,求得的特征值和特征向量将会收敛到一个稳定的值。
著名的 ARPACK 包即实现了 IRAM / IRLM 算法,在 Python 和 Matlab 中都能方便地调用。在 Python 中,可以通过 scipy.sparse.linalg.eigs
/ scipy.sparse.linalg.eigsh
来调用。下面以 eigsh
为例,讲解一下部分调用的参数:
k
:需要的特征值的个数。
ncv
:每次 IRAM 重启中计算 k
个特征值用到的正交基维数。一般来说,ncv > 2*k
是一个较好的选择。
maxiter
:最多重启轮数。如果未指定则默认为 10 * n
。
复杂度分析
IRLM 的时间复杂度和 n 呈线性关系。下图是我做的不同 n 下对 A 运行 scipy.sparse.linalg.eigsh
的实验。横轴是 n,纵轴是时间,单位秒。在不同的 n 下,A 每行的非零元素均保持为 d≈50,且每次只求 r=100 个最大特征值(即 scipy.sparse.lilnalg.eigsh
的 which
参数为 LM
)。
可以看到,当 n 超过 50000 之后,n 和时间之间的关系确实是线性关系。为了看得更明显,我还基于 n 从 50000 到 200000 部分的数据做了一个单变量线性拟合(如橙色线段所示)。拟合得到的斜率为 0.00158,说明每增加一个样本,求特征向量的用时将会增加 1.58 ms。
此外,我还用一个例子对比了 numpy.linalg.eigh
和 scipy.sparse.linalg.eigsh
的时间差别,该例子中,矩阵 A 是 10000×10000 方阵,平均每行 50 个非零元素。可以看到,做全分解、且未利用稀疏特性的 numpy.linalg.eigh
花费的时间要多出很多。
函数 | 运行时间 |
---|
numpy.linalg.eigh | 2min 19s |
scipy.sparse.linalg.eigsh ,k=6 ,which='LM' | 26s |
附录
Krylov 子空间
我们定义矩阵
Km(x)=Km(x,A)=[xAxA2x⋯Am−1x]
为 Krylov 矩阵。其实这正是迭代到第 m 步时,我们把各个迭代得到的向量作为矩阵的各列得到的。同时,Krylov 矩阵的各列张成 Krylov (子)空间
Km(x)=Km(x,A)≜span{x,Ax,A2x,⋯,Am−1x}=R(Km(x))⊂Fn.
下面我们来探讨一下 Krylov 子空间的维度。首先 Krylov 子空间 Km(x) 的维度不可能超过 n,因为它各列向量的长度为 n:
dim(Km(x))≤n.
这也就意味着矩阵 Kn+1(x) 的各列是线性相关的。从另外一个角度来说,如果 x 是 A 的一个特征向量,那么 Ax=λx,这意味着 Km(x)=K1(x) ∀m>=1。初始的 x 必然由张满 Fn 的各个特征向量线性组合而成,因此 x 成分中有几个特征向量,Km(x) 各列便(这里的简单分析不考虑广义特征向量情形)最多张成几维空间。所以,可以预见,对于任意 x∈Rn 存在一个最小的 m,1≤m≤n,使得
K1(x)⫋K2(x)⫋⋯⫋Km(x)=Km+1(x)
成立。对于这个 m,Km+1(x)∈Fn×(m+1) 开始有线性相关的列。即存在 a∈Fm+1,使得
Km+1(x)a=0
成立,即
p(A)x=amAmx+⋯+a1Ax+a0x=0.
其中
p(λ)=amλm+⋯+a1λ+a0.
由于从 m 开始矩阵的各列才开始线性相关,所以
我们称 p(λ) 为 A 相对于 x 的最小多项式(我之前博客中关于矩阵的最小多项式的介绍见这里)。
Galerkin 条件和 Ritz 对
设有 Fn 的某 r 维子空间 V,一个向量 v∈V 满足 Galerkin 条件
⟨w,Av−λv⟩=0, ∀w∈V
时,我们说向量 v 和 λ 构成 Ritz 对,其中 λ 为 Ritz 值,v 为 Ritz 向量。
设 V 的某组单位正交基构成矩阵 W∈Fn×r,定义
G≜W∗AW∈Fr×r,
设 G 的特征值和特征向量构成对 si,θi,i=1,…,r,我们有
Gsi=θisi.
设 vi≜Wsi,我们可以看到
Avi−θivi=AWsi−θiWsi.
进一步,
Gsi=θisi ⇒ W∗(Avi−θivi)=0,
且 Range(W)=V,所以
⟨w,Avi−θivi⟩=0, ∀w∈V.
所以我们得出结论:当且仅当 s,θ 是 G 的一对特征向量和特征值时,v≜Ws,λ≜θ 是 A 的一对 Ritz 向量和 Ritz 值,即 Ritz 对。
Householder 变换
Householder 变换可以理解成(实数域下,复数域下几何性质有所不同)给定一个超平面,把输入向量沿着这个超平面做一个对称,得到的向量作为输出。
具体地,给定一个超平面的单位法向量 v,线性变换
x↦x−2v(v∗x)
即为 Householder 变换。此线性变换对应矩阵
P=I−2vv∗.
容易看出,矩阵 P 是酉(unitary)矩阵且 Hermitian 的,满足下列性质:
- P∗=P−1
- P∗=P
- P−1=P,由 1 和 2 导出。
Householder 变换可以把一个矩阵转换为 Hessenberg 型。见 维基百科相关词条。
Schur 分解
设矩阵 A∈Cn×n,存在一个酉矩阵 Q 和一个上三角矩阵 R,使得
AQ=QR.
其中 R 的对角元为 A 的特征值。