GMRES算法数学原理及推导过程

363 阅读3分钟

背景介绍

广义最小残差法(Generalized Minimal Residual, GMRES)广泛应用于计算流体力学和电磁仿真等领域,是科学计算中求解大型稀疏线性方程组Ax=bA\mathbf{x}=b的主流迭代算法之一,适用的问题比较广,其中A为稀疏矩阵,b通常称为右端向量。与传统的直接解法相比,GMRES通过Krylov子空间投影逐步逼近方程的解,从而减少计算量并提高数值稳定性。

传统的解法一般就是求AA的逆矩阵A1A^{-1}x=A1b\mathbf{x} = A^{-1}b

基本数学知识

Cayley-Hamilton Theorem

对于n×nn \times n矩阵AA,特征值λ\lambda和特征向量x\mathbf{x}满足:

Ax=λx    (x0)A\mathbf{x} = \lambda \mathbf{x} \;\; (\mathbf{x} \neq \mathbf{0})

移项可得:

(λInA)x=0(\lambda I_n - A)\mathbf{x}=\mathbf{0}

其中InI_nn×nn \times n单位矩阵,可以理解成向量中的1,也是标量λ\lambda变成向量参与运算的媒介。由于x\mathbf{x}是非零向量,齐次线性方程组(1)(1)有非零解的充要条件是系数矩阵的行列式为0

det(λInA)=0det(\lambda I_n - A) = 0

即特征方程,展开左边:

λInA=(λa11a12a1na21λa22a2nan1an2λann)\lambda I_n - A = \begin{pmatrix} \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{pmatrix}

根据Leibniz公式λ\lambda的最高次项为nn即主对角线相乘(λa11)(λa22)(λann)(\lambda - a_{11})(\lambda - a_{22})\cdots(\lambda - a_{nn}),且系数为1。这个式子中每包含一个非对角线元素,则必然会替换掉一个主对角线的λ\lambda项,从而得到λn1,λn2,,λ0\lambda^{n-1},\lambda^{n-2},\cdots,\lambda^{0}。当λ=0\lambda=0时,det(0InA)=(1)ndet(A)det(0 \cdot I_n - A) = (-1)^ndet(A),因此常数项c0=(1)ndet(A)c_0 = (-1)^ndet(A)

最终得到特征多项式方程,即:

p(λ)=λn+cn1λn1+cn2λn2++c1λ+c0=0p(\lambda) = \lambda^n + c_{n-1}\lambda^{n-1} + c_{n-2}\lambda^{n-2} + \cdots + c_1\lambda + c_0 = 0

Cayley-Hamilton Theorem的核心结论就是:矩阵 A 满足其自身的特征多项式方程

p(A)=An+cn1An1+cn2An2++c1A+c0=0        (1)p(A) = A^n + c_{n-1}A^{n-1} + c_{n-2}A^{n-2} + \cdots + c_1A + c_0 = 0 \;\;\;\; (1)

Krylov Subspace

对式子(1)两边同时乘以一个A1A^{-1}:

An1+cn1An2+cn2An3++c1I+c0A1=0A^{n-1} + c_{n-1}A^{n-2} + c_{n-2}A^{n-3} + \cdots + c_1I + c_0A^{-1} = 0

再同除一个c0c_0并移项:

A1=1c0An1+cn1c0An2++c1c0IA^{-1} = \frac {-1}{c_0} A^{n-1} + \frac {-c_{n-1}}{c_0}A^{n-2} + \cdots + \frac {-c_1}{c_0}I

于是我们可以得到:

A1span{An1,An2,,I}A^{-1} \in span\{A^{n-1},A^{n-2},\ldots,I\}

A1A^{-1}在这些向量张成的子空间里,但这并不是最终的Krylov Subspace,我们还要新设一个向量r\mathbf{r},然后对上面的式子两边同乘r\mathbf{r},得到:

A1rspan{r,A1r,A2r,,An1r}        (2)A^{-1}\mathbf{r} \in span\{\mathbf{r},A^{1}\mathbf{r},A^{2}\mathbf{r},\ldots,A^{n-1}\mathbf{r}\} \;\;\;\; (2)

这才是Krylov Subspace,至于为什么要乘以一个mathsubrmathsub{r},后面将会解释。

Gram-Schmidt and Arnoldi Iteration

一般解大型稀疏矩阵AA,维度nn是非常大的,虽然我们已经得到了Krylov Subspace,但是我们无法保证张成这个子空间的基向量都是线性独立的,以至于如果直接在这个子空间里搜寻近似解x\mathbf{x},效率其实是很低的。为此,我们要想办法用更少的基向量来张成这个子空间。于是我们很容易想到,如果这个子空间里的基向量都相互正交并且范数都为1的话,所需要的基向量数肯定是最少的,也就大大提高了我们搜寻正确答案的效率。

我们从第一个元素r\mathbf{r}开始,易得:

q0=rrq_0 = \frac{\mathbf{r}}{\mathbf{||r||}}

再来看第二个元素A1rA^1\mathbf{r},很简单,我们只需要找到它垂直于q0q_0的分量,具体如图:

image-20250804212418223.png

我们设k1=Ark_1=A\mathbf{r}u1u_1k1k_1垂直于q0q_0的分量,proj_q0(k1)proj\_q_0(k_1)k1k_1q0q_0上的投影,易得:

u1=k1proj_q0(k1)q1=u1u1u_1 = k_1 - proj\_q_0(k_1) \\ q_1 = \frac{u_1}{||u_1||}

以此类推:

u2=k2proj_q0(k2)proj_q1(k2),  q2=u2u2u3=k3proj_q0(k3)proj_q1(k3)proj_q2(k3),  q3=u3u3um=kmi=0m1proj_qi(km),  qm=umum        (3)u_2 = k_2 - proj\_q_0(k2) - proj\_q_1(k2), \; q_2 = \frac{u2}{||u2||} \\ u_3 = k_3 - proj\_q_0(k3) - proj\_q_1(k3) - proj\_q_2(k3), \; q_3 = \frac{u3}{||u3||} \\ \cdots \\ u_m = k_m - \sum_{i=0}^{m-1} proj\_q_i(k_{m}), \; q_m = \frac{u_m}{||u_m||} \;\;\;\; (3)

计算uu的过程被称为Gram-Schmidt Orthogonalization(正交化),计算qq的过程被称为Gram-Schmidt Orthonomalization(正交归一化),每一个被计算出来的qq又被称为Arnoldi Vector,整个过程我们称为Arnoldi Iteration

需要注意的是:这里的mm一定是小于nn的,除非最开始的Krylov Subspace里的向量就全部互相正交,但这显然不太可能,当我们计算出的qi=0q_i = 0的时候,我们就可以认为QQ里已经包含了所有的维度,不再需要迭代

GMRES算法过程

回到Ax=bA\mathbf{x} = \mathbf{b}问题本身,大多数时候,我们并不关注正确答案本身,而是假设一个答案x0\mathbf{x_0},当这个答案与正确答案x\mathbf{x}之间的差值r\mathbf{r}足够小的时候,我们就认为我们找到了正确答案。

设初始答案为x0\mathbf{x_0},则有:

r0=Ax0bA1r0=x0A1bA1r0=x0xx=x0A1r0        \begin{align*} &\mathbf{r_0} = A\mathbf{x_0} - \mathbf{b} \\ &A^{-1}\mathbf{r_0} = \mathbf{x_0} - A^{-1}\mathbf{b} \\ &A^{-1}\mathbf{r_0} = \mathbf{x_0} - \mathbf{x} \\ &\mathbf{x} = \mathbf{x_0} - A^{-1}\mathbf{r_0} \;\;\;\; \end{align*}

看到这里,我相信你已经知道为什么前面的Krylov Subspace,即A1rspan{r,A1r,A2r,,An1r}A^{-1}\mathbf{r} \in span\{\mathbf{r},A^{1}\mathbf{r},A^{2}\mathbf{r},\ldots,A^{n-1}\mathbf{r}\}需要这样构造了吧。再经过Arnoldi Iteration,我们就能得到维度更小,但是空间一致的子空间span{q0,q1,q2,,qm}span\{q_0,q_1,q_2,\cdots,q_m\}。可以表示为Qm=[q0  q1  q2    qm]Q_m = [q_0 \; q_1 \; q_2 \; \cdots \; q_m]

于是我们可以得到:

x=x0Qmy        \mathbf{x} = \mathbf{x_0} - Q_my \;\;\;\;

为了使等式成立,我们引进了新的变量yy,这个yy可以理解成xx在各个维度上的分量。

所以:

r=Axbr=A(x0Qiy)br=r0AQiy        (4)\begin{align*} &\mathbf{r} = A\mathbf{x} - \mathbf{b} \\ &\mathbf{r} = A(\mathbf{x_0} - Q_iy) - \mathbf{b} \\ &\mathbf{r} = \mathbf{r_0} - AQ_iy \;\;\;\; (4) \end{align*}

这里的x\mathbf{x}指的不是正确答案,而是在误差范围内我们要寻找的答案,ii指的是迭代次数,即:

for    i    in    range(m):r=r0AQiy\begin{aligned} &for \;\; i \;\; in \;\; range(m): \\ &\mathbf{r} = \mathbf{r_0} - AQiy \end{aligned}

这就是GMRES算法的迭代过程,当r<resid_limitr < resid\_limit,这里的resid_limitresid\_limit是我们规定的误差范围,一般为1e61e^{-6},迭代终止,也就认为我们找到了最终答案。为了方便我们的迭代,我们引入了一个新的矩阵,Hessenberg Matrix(海森堡矩阵),它的格式固定为:

Hi+1,i=(h0,0h0,1h0,ih1,0h1,1h1,i0h2,1h2,i00h3,i00hi+1,i)H_{i+1,i} = \begin{pmatrix} h_{0,0} & h_{0,1} & \cdots & h_{0,i} \\ h_{1,0} & h_{1,1} & \cdots & h_{1,i} \\ 0 & h_{2,1} & \cdots & h_{2,i} \\ 0 & 0 & \cdots & h_{3,i} \\ \cdots & \cdots & \cdots & \cdots \\ 0 & 0 & \cdots & h_{i+1,i} \\ \end{pmatrix}

我们将这个矩阵记为H~i\widetilde{H}_i,他是用来搭建AQiAQ_iQi+1Q_{i+1}之间关系的桥梁,即:AQi=Qi+1H~AQ_i = Q_{i+1} \widetilde{H}

回忆Arnoldi Iteration**(注意:以下的m指的不是Krylov Subspace维度数,而是迭代次数)**:

um=kmi=0m1proj_qi(km),  qm=umumu_m = k_m - \sum_{i=0}^{m-1} proj\_q_i(k_{m}), \; q_m = \frac{u_m}{||u_m||}

因为proj_qi(km)proj\_q_i(k_m)kmk_mqiq_i上的投影,也就可以理解成一个常数乘以qiq_i。很明显,qmq_mumu_m也是这样的关系,所以:

um=amqm=kmi=0m1biqiqm=c0km+c1q0+c2q1++cmqm1u_m = a_mq_m = k_m - \sum_{i=0}^{m-1}b_iq_i \\ q_m = c_0k_m + c_1q_0 + c_2q_1 + \cdots + c_mq_{m-1}

也就是说qmspan{km,  q0,  q1,    ,  qm1}q_m \in span\{k_m,\;q_0,\;q_1,\;\cdots\;,\;q_{m-1}\},而我们又很容易知道span{q0,  q1,    ,  qm1}=span{k0,  k1,    ,  km1}span\{q_0,\;q_1,\;\cdots\;,\;q_{m-1}\} = span\{k_0,\;k_1,\;\cdots\;,\;k_{m-1}\},因为前者只是用互相正交且范数为1的基重新去表示了Krylov Subspace,张成的空间肯定是一致的。所以:

qmspan{k0km}Aqmspan{Ak0Akm}q_m \in span\{k_0 \cdots k_m\} \\ Aq_m \in span\{Ak_0 \cdots Ak_m\}

又因为km=Amrk_m = A^mr,所以:

Aqmspan{k1km+1}Aq_m \in span\{k_1 \cdots k_{m+1}\}

这里的AqmAq_m是新加入的向量,于是我们就会发现,与其按照式子(2)的方式来得到新的维度km+1k_{m+1},不如直接计算AqmAq_m来得到km+1k_{m+1},然后就能得到新的qm+1q_{m+1}维度,加入QmQ_m变成Qm+1Q_{m+1}进入下一个迭代,我们记通过这种方式得到的子空间span{k1km+1}span\{k_1 \cdots k_{m+1}\}km+1k_{m+1}^{’}

所以我们可以展开AQmAQ_m:

AQm=[Aq0,,Aqm]=[k1,,km+1]=Km+1AQ_m = [Aq_0,\cdots,Aq_m] = [k_1^{’},\cdots,k_{m+1}^{’}] = K_{m+1}^{’}

又因为:km+1span{q0qm+1}k_{m+1}^{’} \in span\{q_0 \cdots q_{m+1}\},也就是Qm+1Q_{m+1}的一个线性组合,所以:

Km+1=[h0q0,  h1q1,  ,  hm+1qm+1]=[q0,  q1,  ,  qm+1][h0,0h0,1h0,mh1,0h1,1h1,m0h2,1h2,m00h3,m00hm+1,m]=Qm+1H~\begin{align*} K_{m+1}^{’} &= \begin{bmatrix} h_0q_0,\;h_1q_1,\;\cdots ,\;h_{m+1}q_{m+1} \end{bmatrix} \\ &= \begin{bmatrix} q_0,\;q_1,\;\cdots,\;q_{m+1} \end{bmatrix} \begin{bmatrix} h_{0,0} & h_{0,1} & \cdots & h_{0,m} \\ h_{1,0} & h_{1,1} & \cdots & h_{1,m} \\ 0 & h_{2,1} & \cdots & h_{2,m} \\ 0 & 0 & \cdots & h_{3,m} \\ \cdots & \cdots & \cdots & \cdots \\ 0 & 0 & \cdots & h_{m+1,m} \\ \end{bmatrix} \\ &=Q_{m+1}\widetilde{H} \end{align*}

相当于我们的H~\widetilde{H}矩阵里的每一列hih_i实际上记录着的就是如何将q0qi+1q_0 \cdots q_{i+1}转变为ki+1k_{i+1}^{’}的信息。所以,式子(3)可以重写为:

km+1=qm+1um+1+i=0mproj_qi(km+1)=qm+1um+1+i=0m(km+1qi)qi=um+1+i=0mhiqi=Aqm\begin{align*} k_{m+1}^{’}&=q_{m+1} * ||u_{m+1}|| + \sum_{i=0}^{m}proj\_q_i(k_{m+1}^{’})\\ &=q_{m+1} * ||u_{m+1}|| + \sum_{i=0}^{m}(k_{m+1}^{’}·q_i)q_i\\ &=u_{m+1} + \sum_{i=0}^{m}h_iq_i \\ &=Aq_m \end{align*}

然后我们就只需要解出um+1u_{m+1},也就得到了对应的qm+1q_{m+1}um+1||u_{m+1}||。关系为:

qm+1=Aqmi=0mhiqiAqmi=0mhiqi=um+1um+1q_{m+1} = \frac{Aq_m - \sum_{i=0}^{m}h_iq_i}{||Aq_m - \sum_{i=0}^{m}h_iq_i||} = \frac{u_{m+1}}{||u_{m+1}||}

um+1||u_{m+1}||恰好就是我们想要的hm+1,mh_{m+1,m},因为我们看Qm+1H~Q_{m+1}\widetilde{H}的最后一列:

Aqm=hm+1,mqm+1+i=0mhi,mqi=um+1qm+1+i=0mhiqi\begin{align*} Aq_m &= h_{m+1,m}q_{m+1} + \sum_{i=0}^{m}h_{i,m}q_i \\ &=||u_{m+1}||q_{m+1} + \sum_{i=0}^{m}h_iq_i \end{align*}

这也就是完整的一次迭代过程,每次迭代实际上都是在计算H~\widetilde{H}的第mm列。

式子(4)也就能改写为:

r=r0Qm+1H~m+1,myr=βq0Qm+1H~m+1,myr=Qm+1(βeH~m+1,my)r2=Qm+1(βeH~m+1,my)2\begin{align*} &r = r_0 - Q_{m+1}\widetilde{H}_{m+1,m}y\\ &r = \beta q_0 - Q_{m+1}\widetilde{H}_{m+1,m}y \\ &r = Q_{m+1}(\beta e - \widetilde{H}_{m+1,m}y) \\ &||r||_2 = ||Q_{m+1}(\beta e - \widetilde{H}_{m+1,m}y)||_2 \end{align*}

又因为Qm+1Q_{m+1}的所有矢量都是单位矢量且互相正交,所以:

r2=(βeH~m+1,my)2||r||_2 = ||(\beta e - \widetilde{H}_{m+1,m}y)||_2

到这里,问题也就简化为了求最小二乘解的问题了,一般用QR分解求解。在这里,由于GMRES算法求解的大多数是稀疏矩阵乘,采用Givens变换比较好。