跳到正文
格致开物MATHWIKI

广义最小残量法

广义最小残量法(generalized minimal residual method,GMRES)在 Krylov 子空间中选择使线性方程残差二范数最小的近似解,适用于一般非对称非奇异系统。它用 Arnoldi 正交化建立基,再解一个较小的最小二乘问题。未重启时搜索空间不断扩大,存储和正交化成本也随迭代增长。

一个非对称系统的首步

取 A=(3102)、b=(1,1)T、x0=0。第一搜索空间只有 b 的倍数,令 x=αb。残差为 (1−4α,1−2α)T,其平方范数为 (1−4α)2+(1−2α)2=20α2−12α+2. 求极小得 α=3/10,所以 x1=(0.3,0.3)T、r1=(−0.2,0.4)T、‖r1‖2=0.2。第二搜索空间由 b,Ab 张成整个平面,故可得到 x∗=(1/6,1/2)T。与 CG 不同,这里最小化的是残差二范数,矩阵也不要求对称正定。

Arnoldi 关系

记初始残差 r0=b−Ax0,β=‖r0‖2。若 β=0 就已解出,否则令 v1=r0/β。依次对 Avj 减去它在已有正交基上的投影: hij=viTAvj,w=Avj−∑i=1jhijvi,hj+1,j=‖w‖2. 若最后范数非零,令 vj+1=w/hj+1,j。收集为 Vm=[v1,…,vm],便有 AVm=Vm+1H¯m, 其中 H¯m 为 (m+1)×m 上 Hessenberg 矩阵。这个关系是每列投影恒等式的集合,不是对 A 作完整稠密分解。SciPy 的 GMRES 文档说明了一般系统、重启和真实残差检验的接口约定。[1]

小最小二乘问题与最优性证明

在 x0+𝒦m(A,r0) 中写 x=x0+Vmy。利用 r0=Vm+1βe1 和 Arnoldi 关系,得 r=b−Ax=Vm+1(βe1−H¯my). 列正交性给出 ‖Vm+1z‖2=‖z‖2,因此大系统的最小残差问题等价于 miny∈ℝm‖βe1−H¯my‖2. 这是 GMRES 最优性的完整来源。搜索空间嵌套,所以下一步可行集合包含上一步,精确算术下未重启残差范数不增加;它可能暂时不变,并不保证每轮严格下降。

首步残差作为 b 到 A乘搜索直线的垂直距离,第二步搜索平面后残差为零
首步在 A乘K₁ 所在直线上投影 b。点 Ax₁=(1.2,0.6),残差 b−Ax₁=(−0.2,0.4) 与方向 (4,2) 垂直。

主例中 v1=(1,1)T/2,Av1=(4,2)T/2,故 h11=3,h21=1,v2=(1,−1)T/2。首个小问题为最小化 ‖(2,0)T−(3,1)Ty‖,其解 y=32/10,再次得到 x1=(0.3,0.3)T。第二列满足 Av2=2v2,新方向范数为零:Krylov 空间已封闭。对非奇异 A,这种精确封闭意味着当前空间中已有精确解,称为 happy breakdown;浮点中仍须核对真实残差。

重启、预条件与收敛边界

完整 GMRES 保存越来越多的基向量,通常每 m 步重启,用当前近似重新开始。重启限制存储,却丢弃此前搜索方向;即使原矩阵非奇异,也可能出现停滞或很慢的收敛。非正规矩阵的行为也不能只看特征值分布。[2]

左预条件最小化的是预条件后的残差;右预条件可保持原始残差最小化的解释,但解空间变量随之改变。无论采用哪一种,验收最终都应查看 b−Ax 的约定范数。若预条件子随步改变,需使用 flexible GMRES 等相应变体。

透明实现与复算

以下 NumPy 演示不重启,对实矩阵使用两遍修正 Gram–Schmidt,并每步直接解小最小二乘。它返回近似解及真实残差历史,不修改输入。若达到封闭空间却未满足容限,会报告失败,避免将数值 breakdown 当作成功。

矩阵为稠密时,m 步矩阵向量积需 O(mn2),正交化需 O(nm2),存储基需 O(nm)。本教学实现反复调用通用最小二乘,在 m 增大时另有约 O(m4) 累积小问题成本;生产实现通常用增量 Givens 旋转避免这一重复。

Python 3
import numpy as np


def gmres_demo(A, b, tol=1e-12):
    A = np.array(A, dtype=float, copy=True)
    b = np.array(b, dtype=float, copy=True)
    if b.ndim != 1 or not b.size or A.shape != (b.size, b.size):
        raise ValueError("square matrix and matching vector required")
    if not np.isfinite(A).all() or not np.isfinite(b).all() or not np.isfinite(tol) or tol <= 0:
        raise ValueError("finite data and positive tolerance required")
    n = b.size; beta = np.linalg.norm(b)
    if not np.isfinite(beta):
        raise ArithmeticError("initial residual norm outside floating-point range")
    target = tol*max(1.0, beta)
    if not np.isfinite(target) or not np.isfinite(np.linalg.norm(A)):
        raise ArithmeticError("residual threshold or matrix norm outside floating-point range")
    if beta <= target:
        return np.zeros(n), [float(beta)]
    V = np.zeros((n, n+1)); H = np.zeros((n+1, n))
    V[:, 0] = b/beta; history = [float(beta)]
    for j in range(n):
        w = A @ V[:, j]
        for _ in range(2):
            for i in range(j+1):
                hij = np.dot(V[:, i], w)
                H[i, j] += hij
                w -= hij*V[:, i]
        H[j+1, j] = np.linalg.norm(w)
        if not np.isfinite(H[:j+2, :j+1]).all() or not np.isfinite(w).all():
            raise ArithmeticError("nonfinite Arnoldi coefficients")
        rhs = np.zeros(j+2); rhs[0] = beta
        y = np.linalg.lstsq(H[:j+2, :j+1], rhs, rcond=None)[0]
        x = V[:, :j+1] @ y
        residual = np.linalg.norm(b-A@x)
        if not np.isfinite(residual):
            raise ArithmeticError("nonfinite residual")
        history.append(float(residual))
        if residual <= target:
            return x, history
        if H[j+1, j] <= np.finfo(float).eps*max(1.0, np.linalg.norm(A)):
            raise RuntimeError("Krylov breakdown before verified convergence")
        V[:, j+1] = w/H[j+1, j]
    raise RuntimeError("true residual did not reach tolerance")


x, history = gmres_demo([[3, 1], [0, 2]], [1, 1])
print(x)        # [0.16666667 0.5]
print(history)  # sqrt(2), sqrt(0.2), roundoff-sized final residual

有解变式取 A=2I、任意非零 b。第一 Krylov 方向就含精确解 x=b/2,Arnoldi 新向量为零且残差也为零;这是一种正确的有限终止。若改成奇异不相容系统 A=0,b≠0,同样出现新方向为零,残差却无法下降,代码应报告失败。这区分了封闭空间与已解出原问题。

参考资料

  1. ↑ SciPy developers. scipy.sparse.linalg.gmres。
  2. ↑ Richard Barrett et al. Templates for the Solution of Linear Systems,GMRES、重启及预条件。