7.2_GMRES_方法

7.2 GMRES方法

7.2.1 算法描述

GMRES 方法是目前求解非对称线性方程组的最常用算法之一. 在该算法中, “最佳近似解”的判别方法为“使得 rm2=bAx(m)2\| r_m\| _2 = \| b - Ax^{(m)}\| _2 最小”, 即

x(m)=argminxx(0)+KmbAx2.(7.6)x ^ {(m)} = \arg \min _ {x \in x ^ {(0)} + \mathcal {K} _ {m}} \| b - A x \| _ {2}. \tag {7.6}

下面我们就根据这个最优性条件来推导出GMRES方法

设迭代初始向量为 x(0)x^{(0)} ,则对任意向量 xx(0)+Kmx\in x^{(0)} + \mathcal{K}_m ,可设 x=x(0)+Vmyx = x^{(0)} + V_{m}y ,其中 yRmy\in \mathbb{R}^m .于是有

r=bAx=bA(x(0)Vmy)=r0AVmy=βv1Vm+1Hm+1,my=Vm+1(βe1Hm+1,my),\begin{array}{l} r = b - A x \\ = b - A \left(x ^ {(0)} - V _ {m} y\right) \\ = r _ {0} - A V _ {m} y \\ = \beta v _ {1} - V _ {m + 1} H _ {m + 1, m} y \\ = V _ {m + 1} \left(\beta e _ {1} - H _ {m + 1, m} y\right), \\ \end{array}

这里 β=r02\beta = \| r_0\| _2 由于 Vm+1V_{m + 1} 列正交,所以

r2=Vm+1(βe1Hm+1,my)2=βe1Hm+1,my2.\| r \| _ {2} = \| V _ {m + 1} (\beta e _ {1} - H _ {m + 1, m} y) \| _ {2} = \| \beta e _ {1} - H _ {m + 1, m} y \| _ {2}.

于是最优性条件 (7.6) 就等价于

y(m)=argminyRmβe1Hm+1,my2.(7.7)y ^ {(m)} = \arg \min _ {y \in \mathbb {R} ^ {m}} \| \beta e _ {1} - H _ {m + 1, m} y \| _ {2}. \tag {7.7}

这是一个最小二乘问题. 由于 Hm+1,mH_{m+1,m} 是一个上 Hessenberg 矩阵, 且通常 mm 不是很大, 所以我们可以用基于 Givens 变换的 QR 分解来求解. 下面就是 GMRES 方法的基本框架.

算法7.4.GMRES方法基本框架

1: 选取初值 x(0)x^{(0)} , 停机标准 ε>0\varepsilon > 0 , 以及最大迭代步数 IterMax

2: r0=bAx(0),β=r02r_0 = b - Ax^{(0)},\beta = \| r_0\| _2
3: v1=r0/βv_{1} = r_{0} / \beta
4: for j=1j = 1 to IterMax do
5: w=Avjw = Av_{j}
6: for i=1i = 1 to jj do % Arnoldi 过程
7: hi,j=(vi,w)h_{i,j} = (v_i, w)
8: w=whi,jviw = w - h_{i,j}v_i
9: end for
10: hj+1,j=w2h_{j + 1,j} = \| w\| _2
11: if hj+1,j=0h_{j + 1,j} = 0 then
12: m=j,m = j, break
13: end if

14: vj+1=w/hj+1,jv_{j + 1} = w / h_{j + 1,j}
15: relres = ||rj||2/β %相对残量
16: if relres <ε< \varepsilon then % 检测是否收敛
17: m=j,m = j, break
18: end if
19: end for
20: 解最小二乘问题 (7.7), 得到 y(m)y^{(m)}
21: x(m)=x(0)+Vmy(m)x^{(m)} = x^{(0)} + V_m y^{(m)}

7.2.2 具体实施细节

需要解决的问题有:

(1) 如何计算残量 rjbAx(j)r_j \triangleq b - Ax^{(j)} 的范数?
(2) 如何求解最小二乘问题 (7.7)?

这两个问题可以同时处理. 首先采用 QR 分解来求解最小二乘问题. 设 Hm+1,mH_{m+1,m} 的 QR 分解为

Hm+1,m=Qm+1Rm+1,m,H _ {m + 1, m} = Q _ {m + 1} ^ {\top} R _ {m + 1, m},

其中 Qm+1R(m+1)×(m+1)Q_{m + 1}\in \mathbb{R}^{(m + 1)\times (m + 1)} 是正交矩阵, Rm+1,mR(m+1)×mR_{m + 1,m}\in \mathbb{R}^{(m + 1)\times m} 是上三角矩阵. 则

βe1Hm+1,my2=βQm+1e1Rm+1,my2=βq1[Rm0]y2,(7.8)\| \beta e _ {1} - H _ {m + 1, m} y \| _ {2} = \| \beta Q _ {m + 1} e _ {1} - R _ {m + 1, m} y \| _ {2} = \left\| \beta q _ {1} - \left[ \begin{array}{c} R _ {m} \\ 0 \end{array} \right] y \right\| _ {2}, \tag {7.8}

其中 RmRm×mR_{m}\in \mathbb{R}^{m\times m} 是非奇异上三角矩阵(这里假定 Hm+1,mH_{m + 1,m} 不可约).所以问题(7.7)的解为

y(m)=βRm1q1(1:m),y ^ {(m)} = \beta R _ {m} ^ {- 1} q _ {1} (1: m),

rm2=bAx(m)2=βe1Hm+1,my(m)2=βq1(m+1),\| r _ {m} \| _ {2} = \| b - A x ^ {(m)} \| _ {2} = \| \beta e _ {1} - H _ {m + 1, m} y ^ {(m)} \| _ {2} = \beta \cdot | q _ {1} (m + 1) |,

其中 q1(m+1)q_{1}(m + 1) 表示 q1q_{1} 的第 m+1m + 1 个分量

Hm+1,mH_{m + 1,m} 的QR分解的递推计算方法

由于 Hm+1,mH_{m + 1,m} 是上Hessenberg矩阵,因此我们采用Givens变换

(1) 当 m=1m = 1 时, H21=[h11h21]H_{21} = \begin{bmatrix} h_{11} \\ h_{21} \end{bmatrix} , 构造 Givens 变换 G1G_{1} 使得

G1H21=[0]=R21,H21=G1TR21.G _ {1} H _ {2 1} = {\left[ \begin{array}{l} {*} \\ 0 \end{array} \right]} = R _ {2 1}, \quad \text {即} \quad H _ {2 1} = G _ {1} ^ {\mathsf {T}} R _ {2 1}.

(2) 假定存在 G1,G2,,Gm1G_{1}, G_{2}, \ldots, G_{m-1} , 使得

(Gm1G2G1)Hm,m1=Rm,m1,\left(G _ {m - 1} \dots G _ {2} G _ {1}\right) H _ {m, m - 1} = R _ {m, m - 1},

Hm,m1=(Gm1G2G1)TRm,m1QmTRm,m1.H _ {m, m - 1} = \left(G _ {m - 1} \dots G _ {2} G _ {1}\right) ^ {\mathsf {T}} R _ {m, m - 1} \triangleq Q _ {m} ^ {\mathsf {T}} R _ {m, m - 1}.

为了书写方便, 这里假定 GiG_{i} 的维数自动扩张, 以满足矩阵乘积的需要.

(3) 考虑 Hm+1,mH_{m+1,m} 的 QR 分解. 易知

Hm+1,m=[Hm,m1hm0hm+1,m],其 中hm=[h1m,h2m,,hmm]T.H _ {m + 1, m} = \left[ \begin{array}{c c} {{H _ {m, m - 1}}} & {{h _ {m}}} \\ {{0}} & {{h _ {m + 1, m}}} \end{array} \right], \quad \text {其 中} \quad h _ {m} = [ h _ {1 m}, h _ {2 m}, \ldots , h _ {m m} ] ^ {\mathsf {T}}.

所以有

[Qm001]Hm+1,m=[Rm,m1Qmhm0hm+1,m]=[Rm1h~m10h^mm0hm+1,m],\left[ \begin{array}{c c} Q _ {m} & 0 \\ 0 & 1 \end{array} \right] H _ {m + 1, m} = \left[ \begin{array}{c c} R _ {m, m - 1} & Q _ {m} h _ {m} \\ 0 & h _ {m + 1, m} \end{array} \right] = \left[ \begin{array}{c c} R _ {m - 1} & \tilde {h} _ {m - 1} \\ 0 & \hat {h} _ {m m} \\ 0 & h _ {m + 1, m} \end{array} \right],

其中 h~m1\tilde{h}_{m-1}QmhmQ_{m}h_{m} 的前 m1m-1 个元素组成的向量, h^mm\hat{h}_{mm}QmhmQ_{m}h_{m} 的最后一个元素. 构造Givens变换 GmG_{m} :

Gm=[Im1000cmsm0smcm]R(m+1)×(m+1),G _ {m} = \left[ \begin{array}{c c c} I _ {m - 1} & 0 & 0 \\ 0 & c _ {m} & s _ {m} \\ 0 & - s _ {m} & c _ {m} \end{array} \right] \in \mathbb {R} ^ {(m + 1) \times (m + 1)},

其中

cm=h^m,mh~m,m,sm=hm+1,mh~m,m,h~m,m=h^m,m2+hm+1,m2.c _ {m} = \frac {\hat {h} _ {m , m}}{\tilde {h} _ {m , m}}, s _ {m} = \frac {h _ {m + 1 , m}}{\tilde {h} _ {m , m}}, \tilde {h} _ {m, m} = \sqrt {\hat {h} _ {m , m} ^ {2} + h _ {m + 1 , m} ^ {2}}.

Qm+1=Gm[Qm001],Q _ {m + 1} = G _ {m} \left[ \begin{array}{c c} Q _ {m} & 0 \\ 0 & 1 \end{array} \right],

Qm+1Hm+1,m=Gm[Rm1h~m10h^m,m0hm+1,m]=[Rm1h~m10h~m,m00]Rm+1,m.Q _ {m + 1} H _ {m + 1, m} = G _ {m} \left[ \begin{array}{c c} R _ {m - 1} & \tilde {h} _ {m - 1} \\ 0 & \hat {h} _ {m, m} \\ 0 & h _ {m + 1, m} \end{array} \right] = \left[ \begin{array}{c c} R _ {m - 1} & \tilde {h} _ {m - 1} \\ 0 & \tilde {h} _ {m, m} \\ 0 & 0 \end{array} \right] \triangleq R _ {m + 1, m}.

所以可得 Hm+1,mH_{m + 1,m} 的QR分解 Hm+1,m=Qm+1TRm+1,mH_{m + 1,m} = Q_{m + 1}^{\mathsf{T}}R_{m + 1,m}

Hm,m1H_{m,m - 1} 的QR分解到 Hm+1,mH_{m + 1,m} 的QR分解,我们需要

(1) 计算 QmhmQ_{m}h_{m} ,即将之前的 m1m - 1 个Givens变换作用到 Hm+1,mH_{m + 1,m} 的最后一列的前 mm 个元素上,所以我们需要保留所有的Givens变换;
(2) 残量计算: rm2=βq1(m+1)=βQm+1(m+1,1)\| r_{m}\|_{2} = |\beta q_{1}(m + 1)| = |\beta Q_{m + 1}(m + 1,1)| , 即

GmGm1G2G1(βe1)G _ {m} G _ {m - 1} \dots G _ {2} G _ {1} (\beta e _ {1})

的最后一个分量的绝对值. 由于在计算 rm1r_{m-1} 时就已经计算出 Gm1G2G1(βe1)G_{m-1} \cdots G_2 G_1(\beta e_1) , 因此这里只需做一次 Givens 变换即可;

(3) y(m)y^{(m)} 的计算:当相对残量满足精度要求时,需要计算 y(m)=Rm1q1(1:m)y^{(m)} = R_m^{-1}q_1(1:m) ,而 q1q_{1} 即为 GmGm1G2G1(βe1)G_{m}G_{m - 1}\dots G_{2}G_{1}(\beta e_{1})

算法7.5.实用GMRES方法

20:[hijhi+1,j]=[cisisici][hijhi+1,j]2 0: \quad \left[ \begin{array}{c} h _ {i j} \\ h _ {i + 1, j} \end{array} \right] = \left[ \begin{array}{c c} c _ {i} & s _ {i} \\ - s _ {i} & c _ {i} \end{array} \right] \left[ \begin{array}{c} h _ {i j} \\ h _ {i + 1, j} \end{array} \right]
25:τ=hjj/hj+1,j,sj=1/1+τ2,cj=sjτ2 5: \quad \tau = h _ {j j} / h _ {j + 1, j}, s _ {j} = 1 / \sqrt {1 + \tau^ {2}}, c _ {j} = s _ {j} \tau

1: 选取初值 x(0)x^{(0)} , 停机标准 ε>0\varepsilon > 0 , 以及最大迭代步数 IterMax
2: r0=bAx(0),β=r02r_0 = b - Ax^{(0)},\beta = \| r_0\| _2
3: if β/b2<ε\beta / \| b \|_2 < \varepsilon then
4: 停止计算, 输出近似解 x(0)x^{(0)}
5: end if
6: v1=r0/βv_{1} = r_{0} / \beta
7: ξ=βe1\xi = \beta e_{1}
8: for j=1j = 1 to IterMax do
9: w=Avjw = Av_{j}
10: for i=1i = 1 to jj do %\% Arnoldi过程
11: hi,j=(vi,w)h_{i,j} = (v_i,w)
12: w=whi,jviw = w - h_{i,j}v_{i}
13: end for
14: hj+1,j=w2h_{j + 1,j} = \| w\| _2
15: if hj+1,j=0h_{j+1,j} = 0 then % 迭代中断
16: m=jm = j , break
17: end if
18: vj+1=w/hj+1,jv_{j + 1} = w / h_{j + 1,j}
19: fori=1\mathbf{for}i = 1 to j1j - 1 do %\% 计算 Gj1G2G1Hj+1,j(1:j,j)G_{j - 1}\dots G_2G_1H_{j + 1,j}(1:j,j)
21: end for
22: if hjj>hj+1,j|h_{jj}| > |h_{j+1,j}| then % 构造 Givens 变换 GjG_j
23: τ=hj+1,j/hjj,cj=1/1+τ2,sj=cjτ\tau = h_{j + 1,j} / h_{jj},c_{j} = 1 / \sqrt{1 + \tau^{2}},s_{j} = c_{j}\tau
24: else
26: end if
27: hjj=cjhjj+sjhj+1,jh_{jj} = c_j h_{jj} + s_j h_{j+1,j} %\% 计算 GjHj+1,j(1:j,j)G_j H_{j+1,j}(1:j,j)
28: hj+1,j=0h_{j + 1,j} = 0
[ξjξj+1]=[cjsjsjcj][ξj0]\left[ \begin{array}{l}\xi_{j}\\ \xi_{j + 1} \end{array} \right] = \left[ \begin{array}{ll}c_{j} & s_{j}\\ -s_{j} & c_{j} \end{array} \right]\left[ \begin{array}{l}\xi_{j}\\ 0 \end{array} \right] % 计算 Gj(βGj1G2G1e1)G_{j}(\beta G_{j - 1}\dots G_{2}G_{1}e_{1})
30: relres = |ξj+1|/β %相对残量
31: if relres <ε< \varepsilon then

32: m=j,m = j, break
33: end if
34: end for
35: m=jm = j
36: y(m)=H(1:m,1:m)\ξ(1:m)y^{(m)} = H(1:m, 1:m) \backslash \xi(1:m) %\% 求最小二乘问题的解, 回代求解
37: x(m)=x(0)+Vmy(m)x^{(m)} = x^{(0)} + V_m y^{(m)}
38: if relres <ε< \varepsilon then
39: 输出近似解 xx 及相关信息
40: else
41: 输出算法失败信息
42: end if

7.2.3 GMRES 方法的中断

在上面的GMRES方法中,当执行到某一步时有 hk+1,k=0h_{k + 1,k} = 0 ,则算法会中断(breakdown).如果出现这种中断,则我们就找到了精确解.

定理7.4 设 ARn×nA \in \mathbb{R}^{n \times n} 非奇异且 r00r_0 \neq 0 . 若 hi+1,i0,i=1,2,,k1h_{i+1,i} \neq 0, i = 1,2,\ldots,k-1 , 则 hk+1,k=0h_{k+1,k} = 0 当且仅当 x(k)x^{(k)} 是方程组的精确解. (不考虑舍入误差) (板书)

证明. 设 hk+1,k=0h_{k+1,k} = 0 , 则有

AVk=VkHk,y(k)=Hk1(βe1).A V _ {k} = V _ {k} H _ {k}, \quad y ^ {(k)} = H _ {k} ^ {- 1} (\beta e _ {1}).

所以

rk2=bAx(k)2=bA(x(0)+Vky(k))2=r0VkHky(k)2=βv1Vk(βe1)2=0.\begin{array}{l} \| r _ {k} \| _ {2} = \| b - A x ^ {(k)} \| _ {2} = \| b - A \left(x ^ {(0)} + V _ {k} y ^ {(k)}\right) \| _ {2} \\ = \| r _ {0} - V _ {k} H _ {k} y ^ {(k)} \| _ {2} = \| \beta v _ {1} - V _ {k} (\beta e _ {1}) \| _ {2} = 0. \\ \end{array}

反之,设 x(k)x^{(k)} 是精确解,则

0=bAx(k)=r0Vk+1Hk+1,ky(k)=Vk+1(βe1Hk+1,ky(k)).0 = b - A x ^ {(k)} = r _ {0} - V _ {k + 1} H _ {k + 1, k} y ^ {(k)} = V _ {k + 1} \left(\beta e _ {1} - H _ {k + 1, k} y ^ {(k)}\right).

反证法, 假设 hk+1,k0h_{k+1,k} \neq 0 , 则 vk+10v_{k+1} \neq 0 . 因此 Vk+1V_{k+1} 单位列正交, 故列满秩, 所以由上式可知

βe1Hk+1,ky(k)=0.\beta e _ {1} - H _ {k + 1, k} y ^ {(k)} = 0.

由于 Hk+1,kH_{k + 1,k} 是上Hessenberg矩阵,且 hi+1,i0,i=1,2,,k.h_{i + 1,i}\neq 0,i = 1,2,\ldots ,k. 通过向后回代求解可得 y(k)=0y^{(k)} = 0 于是 β=0.\beta = 0. 这与 r00r_0\neq 0 矛盾.所以 hk+1,k=0h_{k + 1,k} = 0

7.2.4 带重启的GMRES方法

由于随着迭代步数的增加, GMRES 方法的每一步所需的运算量和存储量都会越来越大. 因此当迭代步数很大时, GMRES 方法就不太实用. 通常的解决方法就是重启, 即事先设定一个重启迭代步数 kk , 如 k=20k = 20 或 50 等等, 当 GMRES 达到这个迭代步数时仍不收敛, 则计算出方程组在 x(0)+Kkx^{(0)} + \mathcal{K}_k 中的最佳近似解 x(k)x^{(k)} , 然后令 x(0)=x(k)x^{(0)} = x^{(k)} , 并重新开始新的 GMRES 迭代. 不断重复该过程, 直到收敛为止.

算法7.6.GMRES (k)(k) :带重启的GMRES方法
1: 设定重启步数 k (n)k \ (\ll n)
2: 选取初值 x(0)x^{(0)} , 停机标准 ε>0\varepsilon > 0 , 以及最大迭代
3: r0=bAx(0),β=r02r_0 = b - Ax^{(0)}, \beta = \| r_0\|_2
4: if β/b2<ε\beta / \| b \|_2 < \varepsilon then
5: 停止计算, 输出近似解 x=x(0)x = x^{(0)}
6: end if
7: for iter=1 to ceil(IterMax/k) do % 外循环
8: v1=r0/βv_1 = r_0 / \beta
9: ξ=βe1\xi = \beta e_1
10: for j=1j = 1 to kk do
11: 调用 GMRES 循环
12: end for
13: m=jm = j
14: y(m)=H(1:m,1:m)\ξ(1:m)y^{(m)} = H(1:m, 1:m) \backslash \xi(1:m)
15: x(m)=x(0)+Vmy(m)x^{(m)} = x^{(0)} + V_m y^{(m)}
16: if relres < ε\varepsilon then
17: break
18: end if
19: x(0)=x(m)x^{(0)} = x^{(m)} % 重启 GMRES
20: r0=bAx(0),β=r02r_0 = b - Ax^{(0)}, \beta = \| r_0\|_2
21: end for
22: if relres < ε\varepsilon then
23: 输出近似解 x(m)x^{(m)} 及相关信息
24: else
25: 输出算法失败信息
26: end if

带重启的GMRES方法需要注意的问题:

(1) 如何选取合适的重启步数 kk ? 一般只能依靠经验来选取;
(2) 不带重启的 GMRES 方法能保证算法的收敛性, 但带重启的 GMRES 方法却无法保证, 有时可能出现停滞现象 (stagnation).