11.3 迭代法和预条件子

一、迭代法

截止到目前,我们都是通过直接的方法来求解 Ax=bA\boldsymbol x=\boldsymbol bAx=b,会对 AAA 进行变形,如对 AAA 进行消元处理,可能会进行行交换。现在来考虑迭代法(iterative methods),这个方法将 AAA 用一个更简单的矩阵 SSS 来替代 ,将差值 T=S−AT=S-AT=S−A 移动到方程的右边。用 SSS 代替 AAA 后,这个问题就变得很容易求解,而代价是需要不断的重复计算这个简单的式子。

迭代法很容易构造,只需要将 AAA 分解成适当的 S−TS-TS−T,则:将 Ax=b 改写为Sx=Tx+b(11.3.1)将\,\kern 1ptA\boldsymbol x=\boldsymbol b\,\kern 5pt\pmb{改写为}\kern 10ptS\boldsymbol x=T\boldsymbol x+\boldsymbol b\kern 20pt(11.3.1)将Ax=b改写为Sx=Tx+b(11.3.1)迭代法的新颖处是只需要迭代计算式(11.3.1),由每一步的迭代值 xk\boldsymbol x_kxk 得到下一步的迭代值 xk+1\boldsymbol x_{k+1}xk+1:

迭代格式 Pure iterationSxk+1=Txk+b(11.3.2)\pmb{迭代格式\,{\textrm{Pure\,iteration}}}\kern 20pt{\color{blue}S\boldsymbol x_{k+1}=T\boldsymbol x_k+\boldsymbol b}\kern 20pt(11.3.2)迭代格式PureiterationSxk+1=Txk+b(11.3.2)

从任意初始值 x0\boldsymbol x_0x0 开始,然后迭代 Sx1=Tx0+bS\boldsymbol x_1=T\boldsymbol x_0+\boldsymbol bSx1=Tx0+b,再继续迭代 Sx2=Tx1+bS\boldsymbol x_2=T\boldsymbol x_1+\boldsymbol bSx2=Tx1+b,按照这种方式迭代,成百次的迭代是很常见的,通常迭代次数还会更多,当 xk+1\boldsymbol x_{k+1}xk+1 非常接近 xk\boldsymbol x_kxk(如果有可能)或者残差(residual) rk=b−Axk\boldsymbol r_k=\boldsymbol b-A\boldsymbol x_krk=b−Axk 接近与零时,迭代就可以停止了。我们的目标是让迭代值越来越接近真解,要比消元法更快。当 xk\boldsymbol x_kxk 收敛时,极限 x∞\boldsymbol x_\inftyx∞ 就是式(11.3.1)的解:Sx∞=Tx∞+bS\boldsymbol x_{\infty}=T\boldsymbol x_{\infty}+\boldsymbol bSx∞=Tx∞+b,即 Ax∞=bA\boldsymbol x_{\infty}=\boldsymbol bAx∞=b.

分解成 A=S−TA=S-TA=S−T 的两个目标是:单步计算速度(speed per step)和快速收敛(fast convergence) 。单步计算速度取决于 SSS 而收敛速度取决于 S−1TS^{-1}TS−1T:

  1. 式(11.3.2)要很容易求解 xk+1\boldsymbol x_{k+1}xk+1."预条件子(perconditioner) " SSS 可以选择 AAA 的对角线部分或三角形部分。一个快速的选择是 S=L0U0S=L_0U_0S=L0U0,相比于精确分解 A=LUA=LUA=LU 这个分解中含有更多的零元,这是 "不完全 LU\textrm{LU}LU 分解法".
  2. 误差 ek=x−xk\boldsymbol e_k=\boldsymbol x-\boldsymbol x_kek=x−xk 应该快速收敛到零。用式(11.3.1)减去式(11.3.2)可以消去 b\boldsymbol bb,得到关于误差 ek\boldsymbol e_kek 的方程 :误差方程 Error  equationSek+1=Tek即ek+1=S−1Tek(11.3.3)\pmb{误差方程\,\textrm{Error \,equation}}\kern 10pt{\color{blue}S\boldsymbol e_{k+1}=T\boldsymbol e_k}\kern 5pt即\kern 5pt{\color{blue}\boldsymbol e_{k+1}=S^{-1}T\boldsymbol e_k}\kern 13pt(11.3.3)误差方程Error equationSek+1=Tek即ek+1=S−1Tek(11.3.3)

每一步都已使用 S−1TS^{-1}TS−1T 左乘误差,如果 S−1TS^{-1}TS−1T 很小,那么它的幂将快速收敛至零,问题是什么是 "小"?

极端的分解是 S=AS=AS=A 而 T=OT=OT=O,那么迭代的第一步就是原方程 Ax=bA\boldsymbol x=\boldsymbol bAx=b,由于 S−1TS^{-1}TS−1T 是零矩阵,这将完美收敛。但是这一步正是我们想要避免的,因此关于 SSS 的选择是单步计算速度(需要一个简单的 SSS)和快速收敛(SSS 要接近 AAA)之间的权衡。下面是 SSS 的一些选择方法:

  • JS\pmb{\textrm J}\kern 18ptSJS 选择为 AAA 的对角线部分(这个称为雅可比迭代法 Jacobi's method\textrm{Jacobi's\,method}Jacobi'smethod)
  • GSS\pmb{\textrm{GS}}\kern 10ptSGSS 选择为 AAA 的下三角形部分且包含对角元素(这个称为高斯-赛德尔迭代法 Gauss-Seidel  method\textrm{Gauss-Seidel\, method}Gauss-Seidel method)
  • ILUS\pmb{\textrm{ILU}}\kern 7ptSILUS 选择为 LLL 的近似值左乘 UUU 的近似值 (不完全 LU\textrm{LU}LU 分解法 incomplete LU method\textrm{incomplete LU method}incomplete LU method)

下面我们要考虑的第一个问题是线性代数理论中的问题:什么时候 xk\boldsymbol x_kxk 会收敛到 x\boldsymbol xx ? 这个答案揭露了 ∣λmax∣|\lambda_{\textrm{max}}|∣λmax∣ 控制这收敛速度。在雅可比和高斯 - 赛德尔迭代法中,我们会计算 "谱半径" ∣λ∣max|\lambda|_{\textrm{max}}∣λ∣max,它就是迭代矩阵 B=S−1TB=S^{-1}TB=S−1T 中绝对值最大的特征值。

二、谱半径 ρ(B)\rho(B)ρ(B) 控制收敛速度

式(11.3.3)是 ek+1=S−1Tek\boldsymbol e_{k+1}=S^{-1}T\boldsymbol e_kek+1=S−1Tek,每一步迭代都会用同样的矩阵 B=S−1TB=S^{-1}TB=S−1T 左乘误差,第 kkk 次迭代后的误差是 ek=Bke0\boldsymbol e_k=B^k\boldsymbol e_0ek=Bke0. 当矩阵 B=S−1TB=S^{-1}TB=S−1T 的幂趋近于零时,误差也将趋近于零 。矩阵 BBB 的特征值 ------ 尤其是绝对值最大的特征值,控制着矩阵的幂 BkB^kBk.

矩阵的幂 BkB^kBk 趋于零当且仅当 BBB 所有的特征值都满足 ∣λ∣<1|\lambda|<1∣λ∣<1. 矩阵 BBB 的谱半径(spectral radius)控制着其幂的收敛速度 :ρ=max∣λ(B)∣\color{blue}\rho=\textrm{max}|\lambda(B)|ρ=max∣λ(B)∣.

判断收敛的检验条件是 ∣λ∣max<1|\lambda|{\textrm{max}}<1∣λ∣max<1. 实数特征值一定要在 −1-1−1 和 111 之间,复数特征值 λ=a+ib\lambda=a+ibλ=a+ib 必须满足 ∣λ∣2=a2+b2<1|\lambda|^2=a^2+b^2<1∣λ∣2=a2+b2<1. 谱半径 "ρ\rhoρ" 是 000 到 B=S−1TB=S^{-1}TB=S−1T 特征值最大的距离,即 ρ=∣λ∣max\rho=|\lambda|{\textrm{max}}ρ=∣λ∣max.
∣λ∣max<1|\lambda|_{\textrm{max}}<1∣λ∣max<1 是必要的:假设起始误差 e0\boldsymbol e_0e0 恰好为 BBB 的一个特征向量,迭代一次后误差为 Be0=λe0B\boldsymbol e_0=\lambda\boldsymbol e_0Be0=λe0,迭代 kkk 次后的误差是 Bke0=λke0B^k\boldsymbol e_0=\lambda^k\boldsymbol e_0Bke0=λke0. 如果我们的起始误差是一个特征向量,那么后续迭代都会与这个特征向量有关,而因子 λk\lambda^kλk 只有当 ∣λ∣<1|\lambda|<1∣λ∣<1 时才会趋于零。对于任意的特征向量都需要满足这个条件。

下面看一下为什么 ∣λ∣max<1|\lambda|_{\textrm{max}}<1∣λ∣max<1 是误差趋于零的充分条件:假设 e0\boldsymbol e_0e0 是特征向量的线性组合:e0=c1x1+c2x2+⋯+cnxn迭代 k 此后得ek=c1(λ1)kx1+c2(λ2)kx2+⋯+cn(λn)kxn(11.3.4)\boldsymbol e_0=c_1\boldsymbol x_1+c_2\boldsymbol x_2+\cdots+c_n\boldsymbol x_n\kern 5pt迭代\,k\,此后得\kern 5pt\boldsymbol e_k=c_1(\lambda_1)^k\boldsymbol x_1+c_2(\lambda_2)^k\boldsymbol x_2+\cdots+c_n(\lambda_n)^k\boldsymbol x_n\kern 15pt(11.3.4)e0=c1x1+c2x2+⋯+cnxn迭代k此后得ek=c1(λ1)kx1+c2(λ2)kx2+⋯+cn(λn)kxn(11.3.4)这个是由特征向量的性质得来的!当用 BBB 左乘 e0\boldsymbol e_0e0 后,每个特征向量 xi\boldsymbol x_ixi 都被 λi\lambda_iλi 乘,如果所有的 ∣λ∣i<1|\lambda|_i<1∣λ∣i<1,则式(11.3.4)能够确保 ek\boldsymbol e_kek 趋于零。

例1 】B=[0.60.50.60.5]B=\begin{bmatrix}0.6&0.5\\0.6&0.5\end{bmatrix}B=[0.60.60.50.5] 的 λmax=1.1B′=[0.61.100.5]\lambda_{\textrm{max}}=1.1\kern 15ptB'=\begin{bmatrix}0.6&1.1\\0&0.5\end{bmatrix}λmax=1.1B′=[0.601.10.5] 的 λmax=0.6\lambda_{\textrm{max}}=0.6λmax=0.6.
B2B^2B2 是 1.11.11.1 乘 BBB,B3B^3B3 是 (1.1)2(1.1)^2(1.1)2 乘 BBB,依次类推可知 BBB 的幂会无限增大。而 B′B'B′ 的幂完全相反,矩阵 (B′)k(B')^k(B′)k 的对角线上的元素是 (0.6)k(0.6)^k(0.6)k 和 (0.5)k(0.5)^k(0.5)k,非对角线元素也含有 ρk=(0.6)k\rho^k=(0.6)^kρk=(0.6)k,这使得 (B′)k(B')^k(B′)k 收敛到零矩阵,且 ρ\rhoρ 控制这收敛速度。

注: 当特征向量太少时,式(11.3.4)就不是正确的了。此时对于矩阵 BBB 这种由于特征向量缺失而无法对角化情形,我们要转向它的若尔当形(Jordan form):若尔当形 JB=MJM−1和Bk=MJkM−1(11.3.5)\pmb{若尔当形\,J}\kern 15ptB=MJM^{-1}\kern 15pt和\kern 15ptB^k=MJ^kM^{-1}\kern 15pt(11.3.5)若尔当形JB=MJM−1和Bk=MJkM−1(11.3.5)而 JJJ 和 JkJ^kJk 是由具有重复特征值的 "子块" 所构成(见 8.3 节):J 中的 2×2 子块矩阵的幂为[λ10λ]k=[λkkλk−10λk]J\,中的\,2×2\,子块矩阵的幂为\kern 10pt\begin{bmatrix}\lambda&1\\0&\lambda\end{bmatrix}^k=\begin{bmatrix}\lambda^k&k\lambda^{k-1}\\0&\lambda^k\end{bmatrix}J中的2×2子块矩阵的幂为[λ01λ]k=[λk0kλk−1λk]如果 ∣λ∣<1|\lambda|<1∣λ∣<1,额外的因子 kkk 的增大会被衰减因子 λk−1\lambda^{k-1}λk−1 所抵消,使得这些子块矩阵的幂趋于零。这适用于所有的若尔当块:无论是否可以对角化:ρ=∣λ∣max<1 时 Bk→O 且收敛速度取决于 ρ.\color{blue}无论是否可以对角化:\rho =|\lambda|_{\textrm{max}}<1\,时\,B^k\rightarrow O\,且收敛速度取决于\,\rho.无论是否可以对角化:ρ=∣λ∣max<1时Bk→O且收敛速度取决于ρ.

三、雅可比迭代法对比高斯 - 赛德尔迭代法

我们现在要通过分解矩阵 AAA 求解下面这个 2×22\times22×2 的问题,注意谱半径 ∣λ∣max|\lambda|_{\textrm{max}}∣λ∣max.Ax=b2u−v=4−u+2v=−2的解为[uv]=[20](11.3.6)A\boldsymbol x=\boldsymbol b\kern 10pt\begin{array}{l}\kern 3pt2u-\kern 5ptv=\kern 7pt4\\-u+2v=-2\end{array}\kern 10pt的解为\kern 10pt\begin{bmatrix}u\\v\end{bmatrix}=\begin{bmatrix}2\\0\end{bmatrix}\kern 20pt(11.3.6)Ax=b2u−v=4−u+2v=−2的解为[uv]=[20](11.3.6)第一种分解使用雅可比方法(Jacobi's methods) ,将 AAA 的对角线元素放到左边(这就是 SSS),将 AAA 的非对角线元素移动到右边(即 SSS),得到迭代式:

雅可比迭代 Jacobi's iterationSxk+1=Txk+b2uk+1=vk+42vk+1=uk−2\pmb{雅可比迭代\,\textrm{Jacobi's iteration}}\kern 10pt{\color{blue}S\boldsymbol x_{k+1}=T\boldsymbol x_k+\boldsymbol b}\color{blue}\kern 10pt\begin{array}{l}2u_{k+1}=v_k+4\\2v_{k+1}=u_k-2\end{array}雅可比迭代Jacobi's iterationSxk+1=Txk+b2uk+1=vk+42vk+1=uk−2

从 u0=v0=0u_0=v_0=0u0=v0=0 开始,迭代一步可得 u1=2,v1=−1u_1=2, v_1=-1u1=2,v1=−1,持续迭代得到的迭代值如下:[00],[2−1],[320],[2−14],[1580],[2−116],... 趋于 [20]\begin{bmatrix}0\\0\end{bmatrix},\begin{bmatrix}\kern 7pt2\\-1\end{bmatrix},\begin{bmatrix}\dfrac{3}{2}\\[1.5ex]0\end{bmatrix},\begin{bmatrix}\kern 7pt2\\[0.5ex]-\dfrac{1}{4}\end{bmatrix},\begin{bmatrix}\dfrac{15}{8}\\[1.5ex]0\end{bmatrix},\begin{bmatrix}\kern 7pt2\\[0.5ex]-\dfrac{1}{16}\end{bmatrix},...\,趋于\,\begin{bmatrix}2\\0\end{bmatrix}[00],[2−1], 230 , 2−41 , 8150 , 2−161 ,...趋于[20]这表明迭代值是收敛的,在迭代第 1,3,51,3,51,3,5 步中,第二个分量分别是 −1,−14,−116-1,-\dfrac{1}{4},-\dfrac{1}{16}−1,−41,−161,每两步迭代,它都会变为原来的四分之一。误差方程为 Sek+1=TekS\boldsymbol e_{k+1}=T\boldsymbol e_kSek+1=Tek:误差方程[2002]ek+1=[0110]ek或ek+1=[012120]ek(11.3.7)\pmb{误差方程}\kern 15pt\begin{bmatrix}2&0\\0&2\end{bmatrix}\boldsymbol e_{k+1}=\begin{bmatrix}0&1\\1&0\end{bmatrix}\boldsymbol e_k\kern 7pt或\kern 7pt\boldsymbol e_{k+1}=\begin{bmatrix}0&\pmb{\dfrac{1}{2}}\\[1.5ex]\pmb{\dfrac{1}{2}}&0\end{bmatrix}\boldsymbol e_k\kern 10pt(11.3.7)误差方程[2002]ek+1=[0110]ek或ek+1= 021210 ek(11.3.7)最后一个矩阵是 B=S−1TB=S^{-1}TB=S−1T,它的特征值是 12\dfrac{1}{2}21 和 −12-\dfrac{1}{2}−21,所以它的谱半径为 ρ(B)=12\rho(B)=\dfrac{1}{2}ρ(B)=21:B=S−1T=[012120]的 ∣λ∣max=12且[012120]2=[140014]B=S^{-1}T=\begin{bmatrix}0&\dfrac{1}{2}\\[1.5ex]\dfrac{1}{2}&0\end{bmatrix}的\,|\lambda|_{\textrm{max}}=\dfrac{1}{2}\kern 10pt且\kern 5pt\begin{bmatrix}0&\dfrac{1}{2}\\[1.5ex]\dfrac{1}{2}&0\end{bmatrix}^2=\begin{bmatrix}\dfrac{1}{4}&0\\[1.5ex]0&\dfrac{1}{4}\end{bmatrix}B=S−1T= 021210 的∣λ∣max=21且 021210 2= 410041 在这个特殊的例子中,误差会在每两步迭代后精确的缩小为原来的 14\dfrac{1}{4}41. 有一个重要信息:雅可比迭代法在 AAA 的主对角线元素的绝对值比非对角线元素的绝对值大时效果很好。对角线元素生成的矩阵是 SSS,剩余元素生成的举止是 −T-T−T,我们希望的是对角线元素的绝对值占优(即对角线元素的绝对值是该行所有元素中绝对值最大的)。

该例中的特征值 λ=12\lambda=\dfrac{1}{2}λ=21 比较小了,十次迭代后会将误差减小到原来的 1210=11024\dfrac{1}{2^{10}}=\dfrac{1}{1024}2101=10241。实际中更典型的情况是 ∣λ∣max=0.99|\lambda|{\textrm{max}}=0.99∣λ∣max=0.99 或 0.9990.9990.999,此时需要更多的计算量。
高斯 - 赛德尔方法(Gauss-Seidel method) 是将矩阵 AAA 的整个下三角部分设为 SSS:高斯−赛德尔迭代法2uk+1=vk+4−uk+1+2vk+1=−  2或uk+1=12vk+2vk+1=12uk+1−1(11.3.8)\pmb{高斯-赛德尔迭代法}\kern 10pt\begin{array}{ll}\kern 2pt2u
{k+1}&=v_k+4\\-u_{k+1}+2v_{k+1}&=\kern 12pt-\,\,2\end{array}\kern 5pt或\kern 5pt\begin{array}{l}u_{k+1}=\dfrac{1}{2}v_k+2\\[1.5ex]v_{k+1}=\dfrac{1}{2}u_{k+1}-1\end{array}\kern 10pt(11.3.8)高斯−赛德尔迭代法2uk+1−uk+1+2vk+1=vk+4=−2或uk+1=21vk+2vk+1=21uk+1−1(11.3.8)注意迭代格式的变化,第一个方程得到的迭代值 uk+1u_{k+1}uk+1 会直接在第二个方程中使用。雅可比迭代法中,我们需要保留旧的迭代值 uku_kuk 直到当前整个迭代步骤完成;高斯 - 赛德尔迭代法中,新的迭代值 uk+1u_{k+1}uk+1 代入到右端后即可丢弃掉旧值 uku_kuk,这可以减少一半的存储量,通常来说,这也会加速迭代过程,且计算量并不会超过雅可比迭代法。

这里我们选择另一组初始值 u0=0,v0=−1u_0=0,v_0=-1u0=0,v0=−1 来进行测试(如果选择初始值 u0=0,v0=0u_0=0,v_0=0u0=0,v0=0 只需要迭代一步):[0−1],[32−14],[158−116],[6332−164],...趋于[20]\begin{bmatrix}\kern 7pt0\\-1\end{bmatrix},\begin{bmatrix}\kern 7pt\dfrac{3}{2}\\[1.5ex]-\dfrac{1}{4}\end{bmatrix},\begin{bmatrix}\kern 7pt\dfrac{15}{8}\\[1.5ex]-\dfrac{1}{16}\end{bmatrix},\begin{bmatrix}\kern 7pt\dfrac{63}{32}\\[1.5ex]-\dfrac{1}{64}\end{bmatrix},...\kern 3pt趋于\kern 3pt\begin{bmatrix}2\\0\end{bmatrix}[0−1], 23−41 , 815−161 , 3263−641 ,...趋于[20]第一个分量的误差分别是 2,12,18,1322,\dfrac{1}{2},\dfrac{1}{8},\dfrac{1}{32}2,21,81,321,第二个分量的误差分别是 −1,−14,−116,−132-1,-\dfrac{1}{4},-\dfrac{1}{16},-\dfrac{1}{32}−1,−41,−161,−321. 此时每一步(而不是两步)迭代的误差都会除以 444. 高斯 - 赛德尔迭代法的效率是雅可比迭代法的两倍 。当 AAA 是正定三对角矩阵时,有 ρGS=(ρJ)2\rho_{\textrm{\pmb{GS}}}=(\rho_{\textrm {\pmb J}})^2ρGS=(ρJ)2:S=[20−12],T=[0100]且S−1T=[012014]S=\begin{bmatrix}\kern 7pt2&0\\-1&2\end{bmatrix},\kern 5ptT=\begin{bmatrix}0&1\\0&0\end{bmatrix}\kern 15pt且\kern 5ptS^{-1}T=\begin{bmatrix}\pmb0&\dfrac{1}{2}\\[1.5ex]0&\dfrac{1}{4}\end{bmatrix}S=[2−102],T=[0010]且S−1T= 002141 高斯 - 赛德尔迭代法对应的矩阵 BBB 的特征值是 000 和 14\dfrac{1}{4}41,对比雅可比迭代法对应矩阵 BBB 的特征值 12\dfrac{1}{2}21 和 −12-\dfrac{1}{2}−21,谱半径要小一倍。

我们更进一步可以得到逐次超松弛法(successive overrelaxation method:SOR) . 该方法的思想是在迭代中引入一个参数 ω\omegaω,然后通过选取 ω\omegaω 使得 S−1TS^{-1}TS−1T 的谱半径尽可能的小。

将 Ax=bA\boldsymbol x=\boldsymbol bAx=b 改写成 ωAx=ωb\omega A\boldsymbol x=\omega\boldsymbol bωAx=ωb,SOR 中的矩阵 SSS 的对角线元素与原始矩阵 AAA 的相同,但是对角线下的元素使用 ωA\omega AωA 中的元素,右侧的 T=S−ωAT=S-\omega AT=S−ωA,代入 ωAx=ωb\omega A\boldsymbol x=\omega\boldsymbol bωAx=ωb 即可得到上例中 SOR 的迭代式:SOR2uk+1=(2−2ω)uk+ωvk+4ω−ωuk+1+2vk+1=(2−2ω)vk−2ω(11.3.9)\textrm{\pmb{SOR}}\kern 15pt\begin{array}{ll}\kern 9pt2u_{k+1}&=(2-2\omega)u_k+\omega v_k+4\omega\\-\omega u_{k+1}+2v_{k+1}&=\kern 30pt(2-2\omega)v_k-2\omega\end{array}\kern 15pt(11.3.9)SOR2uk+1−ωuk+1+2vk+1=(2−2ω)uk+ωvk+4ω=(2−2ω)vk−2ω(11.3.9)这个式子虽然看起来更复杂,但是计算机求解时的速度是一样快的。SOR 就像高斯 - 赛德尔迭代法,只是增加了一个可调参数 ω\omegaω,最优的 ω\omegaω 可以使得计算的更快。

下面使用一个非常有价值的 nnn 阶测试矩阵,−1,2,−1-1,2,-1−1,2,−1 三对角矩阵 KKK. 这个矩阵的对角线矩阵是 2I2I2I,对角线下面和上面的元素都是 −1-1−1,上述例子使用的是 n=2n=2n=2 的情形,因此可知 cos⁡π3=12\cos\dfrac{π}{3}=\dfrac{1}{2}cos3π=21 是雅可比迭代法的特征值,注意此时 ∣λ∣max2|\lambda|_{\textrm{max}}^2∣λ∣max2 是高斯 - 赛德尔迭代法对应矩阵的特征值:

将 nnn 阶的 −1,2,−1-1,2,-1−1,2,−1 三对角矩阵分解为 K=S−TK=S-TK=S−T,并计算对应 B=S−1TB=S^{-1}TB=S−1T 的特征值:Jacobi (S 是 0,2,0 三对角矩阵):S−1T 有 ∣λ∣max=cos⁡πn+1Gauss-Seidel (S 是 −1,2,0 三对角矩阵):S−1T 有 ∣λmax∣=(cos⁡πn+1)2SOR (最优 ω):S−1T 有 ∣λmax∣=(cos⁡πn+1)2(1+sin⁡πn+1)2\begin{array}{lr}\pmb{\textrm{Jacobi}}\,(S\,是\,0,2,0\,三对角矩阵):&\color{blue}S^{-1}T\,有\,|\lambda|{\textrm{max}}=\cos\dfrac{π}{n+1}\\[2ex]\textrm{\pmb{Gauss-Seidel}}\,(S\,是\,-1,2,0\,三对角矩阵):&\color{blue}S^{-1}T\,有\,|\lambda{\textrm{max}}|=(\cos\dfrac{π}{n+1})^2\\[2ex]\textrm{\textrm{SOR}}\,(最优\,\omega):&\color{blue}S^{-1}T\,有\,|\lambda_{\textrm{max}}|=\dfrac{(\cos\dfrac{π}{n+1})^2}{(1+\sin\dfrac{π}{n+1})^2}\end{array}Jacobi(S是0,2,0三对角矩阵):Gauss-Seidel(S是−1,2,0三对角矩阵):SOR(最优ω):S−1T有∣λ∣max=cosn+1πS−1T有∣λmax∣=(cosn+1π)2S−1T有∣λmax∣=(1+sinn+1π)2(cosn+1π)2

澄清一下:对于 −1,2,−1-1,2,-1−1,2,−1 这样的三对角矩阵,这些迭代法并不合适!对三对角矩阵进行消元非常快(能得到精确的 LULULU). 迭代法适用的是在院里中心对角线处位置含有非零元的大型稀疏矩阵,这些矩阵的 LULULU 分解中确切的 LLL 和 UUU 要比原矩阵的非零元更多,而这将零元变成非零元 的过程也就是为什么消元法计算量很大的原因。

下面介绍另一种分解法,"不完全 LU 分解法(incomplete LU) " 的思想是将 LLL 和 UUU 中的绝对值很小的非零元改为零,这将重新使得三角形矩阵 L0L_0L0 和 U0U_0U0 变为稀疏矩阵,这种分解的 S=L0U0S=L_0U_0S=L0U0 在左边,每一步的迭代都很快:不完全 LU 分解法 Incomplete LUL0U0xk+1=(L0U0−A)xk+b\pmb{不完全\,\textrm{LU}\,分解法\,\textrm{Incomplete LU}}\kern 15ptL_0U_0\boldsymbol x_{k+1}=(L_0U_0-A)\boldsymbol x_k+\boldsymbol b不完全LU分解法Incomplete LUL0U0xk+1=(L0U0−A)xk+b右边进行系数矩阵 - 向量的乘法,不要直接使用 L0L_0L0 左乘 U0U_0U0,它们都是矩阵,计算量会很大,先计算 U0xkU_0\boldsymbol x_kU0xk,然后再用 L0L_0L0 左乘,即 L0(U0xk)L_0(U_0\boldsymbol x_k)L0(U0xk). 然后在左边依次进行向下和向上的回代得到 xk+1\boldsymbol x_{k+1}xk+1. 如果 L0U0L_0U_0L0U0 非常接近矩阵 AAA,那么 ∣λ∣max|\lambda|_{\textrm{max}}∣λ∣max 就会很小,只需要几步迭代就可以得到一个很精确的解。

四、多重网格法和共轭梯度算法

虽说雅可比迭代法和高斯 - 赛德尔迭代法都是很好的方法,但是仍然有可以改进的空间。通常 "低频" 误差会衰减的很慢,这就需要多次进行迭代。有两个重要的思想该解决这个问题带来了巨大的进展,多重网格法(multigrid) 在求解某些 nnn 阶问题时只需要 O(n)O(n)O(n) 步;带有恰当的预条件子的共轭梯度法(conjugate gradients) 已经成为数值线性代数中最流行和强大的算法之一。

多重网格法: 使用粗网格求解更小规模问题时,每一次迭代的计算量都更小,计算速度也会更快。然后在粗网格之间进行插值,进一步的快速求解全尺度的问题。使用多重网格法可以向下和向后移动 444 个网格层。

共轭梯度法: 像 xk+1=xk−Axk+b\boldsymbol x_{k+1}=\boldsymbol x_k-A\boldsymbol x_k+\boldsymbol bxk+1=xk−Axk+b 这样的普通迭代,每一步都需要计算矩阵 AAA 和向量的乘法。如果 AAA 是稀疏的,那计算量就不会太大:只需要计算 AxkA\boldsymbol x_kAxk 即可。每次迭代都向包含逼近值且不断扩张的 "克雷洛夫空间(Krylov spaces)" 增加了一个基向量。但是 xk+1\boldsymbol x_{k+1}xk+1 并不是 x0,Ax0,A2x0,⋯ ,Akx0\boldsymbol x_0, A\boldsymbol x_0, A^2\boldsymbol x_0,\cdots,A^k\boldsymbol x_0x0,Ax0,A2x0,⋯,Akx0 最优的线性组合 再加上 b\boldsymbol bb. 普通的迭代简单,但是远没有达到最优的效果。

共轭梯度法(简记为:CG)就是在每一步都选择构成 xk\boldsymbol x_kxk 的最优组合 ,而额外的计算量(除去一次 AAA 左乘向量的乘法)并不是很大。CG 迭代法的思想,需要注意的是,该方法是针对系数矩阵为对称正定矩阵的方程组构造的。如果矩阵 AAA 不对称,一个好的选择是广义最小残差法(generalized minimal residual method,GMRES). 得当 A=ATA=A^TA=AT 但是不正定时,可以使用最小残差法(minimal residual method,MINRES). 围绕对每个迭代值 xk\boldsymbol x_kxk 进行最优选择的思想,现在已经开辟了一个高性能迭代方法的领域。

Gilbert Strong 的 Computational Science and EnginerringComputational\,Science\,and \,EnginerringComputationalScienceandEnginerring 中更详细的介绍了多重网格法和共轭梯度法。

共轭梯度循环中是通过计算新的逼近值 xk\boldsymbol x_kxk、新的残差 rk=b−Axk\boldsymbol r_k=\boldsymbol b-A\boldsymbol x_krk=b−Axk 和新的搜索方向 dk\boldsymbol d_kdk 来寻找下一个 xk+1\boldsymbol x_{k+1}xk+1.
预条件子 SSS 可以加速收敛的速度,原始方程为 Ax=bA\boldsymbol x=\boldsymbol bAx=b,预条件方程是 S−1Ax=S−1bS^{-1}A\boldsymbol x=S^{-1}\boldsymbol bS−1Ax=S−1b,将代码进行小的改动就可以得到预条件共轭梯度法 ------ 求解正定系统中最重要的迭代方法。

迭代法最大的竞争对手是直接消元法,消元法可以将方程组重新排列来最大程度的利用系数矩阵 AAA 中的零元,其它方法要超越高斯消元法并不容易。

五、求特征值的迭代法

现在我们将目光从 Ax=bA\boldsymbol x=\boldsymbol bAx=b 移到 Ax=λxA\boldsymbol x=\lambda\boldsymbol xAx=λx. 迭代法对于求解线性方程只是可选的方法之一,但是对于求特征值是必须的。一个 n×nn\times nn×n 的矩阵的特征值是一个 nnn 阶多项式的根,A−λIA-\lambda IA−λI 的行列式的最高次项是 (−λ)n(-\lambda)^n(−λ)n. 用 det⁡(A−λI)=0\det(A-\lambda I)=0det(A−λI)=0 来求解特征值是一个非常糟糕的方法 ------ 除非 nnn 很小!

当 n>4n>4n>4 时,求解 det⁡(A−λI)=0\det(A-\lambda I)=0det(A−λI)=0 的一般公式不存在,更糟糕的是,λ\lambdaλ 的值可能非常不稳定。更好的选择是,利用矩阵 AAA 本身的特征,逐渐的将其化成对角矩阵或者三角形矩阵,此时特征值就会出现在对角线上。

下面简要的讨论幂法和 QRQRQR 法(LAPACK使用的是此方法)来计算特征值。

1、幂法和反幂法(Power methods and inverse power methods) 选择任意向量 u0\boldsymbol u_0u0 作为初始值,用矩阵 AAA 左乘 u0\boldsymbol u_0u0 得到 u1\boldsymbol u_1u1,继续用 AAA 左乘 u1\boldsymbol u_1u1 得到 u2\boldsymbol u_2u2. 如果 u0\boldsymbol u_0u0 可以表示成 AAA 特征向量的线性组合,那么 AAA 左乘特征向量 xi\boldsymbol x_ixi 相当于特征值 λi\lambda_iλi 乘 xi\boldsymbol x_ixi,在第 kkk 步后可以得到 (λi)k(\lambda_i)^k(λi)k:uk=Aku0=c1(λ1)kx1+c2(λ2)kx2+⋯+cn(λn)kxn(11.3.10)\boldsymbol u_k=A^k\boldsymbol u_0=c_1(\lambda_1)^k\boldsymbol x_1+c_2(\lambda_2)^k\boldsymbol x_2+\cdots+c_n(\lambda_n)^k\boldsymbol x_n\kern 20pt(11.3.10)uk=Aku0=c1(λ1)kx1+c2(λ2)kx2+⋯+cn(λn)kxn(11.3.10)随着幂法的继续,绝对值最大的特征值将占主导地位 。如果 λ1\lambda_1λ1 是绝对值最大的特征值,则向量 uk\boldsymbol u_kuk 将会趋近于占主导的特征向量 x1\boldsymbol x_1x1. 从下面的马尔可夫矩阵可以看到这点:A=[0.90.30.10.7]有λmax=1,对应特征向量[0.750.25]A=\begin{bmatrix}0.9&0.3\\0.1&0.7\end{bmatrix}\kern 5pt有\kern 5pt\lambda_{\textrm{max}}=1,\kern 5pt对应特征向量\kern 5pt\begin{bmatrix}0.75\\0.25\end{bmatrix}A=[0.90.10.30.7]有λmax=1,对应特征向量[0.750.25]设初始向量为 u0\boldsymbol u_0u0,每一步都用矩阵 AAA 左乘:u0=[10],u2=[0.90.1],u2=[0.840.16],⋯ ,趋于u∞=[0.750.25]\boldsymbol u_0=\begin{bmatrix}1\\0\end{bmatrix},\boldsymbol u_2=\begin{bmatrix}0.9\\0.1\end{bmatrix},\boldsymbol u_2=\begin{bmatrix}0.84\\0.16\end{bmatrix},\cdots,\kern 5pt趋于\kern 5pt\boldsymbol u_{\infty}=\begin{bmatrix}0.75\\0.25\end{bmatrix}u0=[10],u2=[0.90.1],u2=[0.840.16],⋯,趋于u∞=[0.750.25]收敛的速度取决于绝对值第二大的特征值 λ2\lambda_2λ2 与绝对值最大的特征值 λ1\lambda_1λ1 的比值。我们不希望 ∣λ1|\lambda_1∣λ1| 太小,我们希望的是 ∣λ2λ1∣\Big|\dfrac{\lambda_2}{\lambda_1}\Big| λ1λ2 要比较小。这里 λ2=0.6, λ1=1\lambda_2=0.6,\,\lambda_1=1λ2=0.6,λ1=1,收敛速度比较快。对于大型矩阵经常会碰到 ∣λ2λ1∣\Big|\dfrac{\lambda_2}{\lambda_1}\Big| λ1λ2 很接近 111 的情况,这时幂法的收敛速度就会很慢。

有没有求绝对值最小特征值的方法呢?------ 这在实际应用中也非常重要。答案是有的 ------ 反幂法:用 A−1A^{-1}A−1 而不是 AAA 来左乘初始向量 u0\boldsymbol u_0u0. 由于我们并不想要计算 A−1A^{-1}A−1,实际上我们是求解 Au1=u0A\boldsymbol u_1=\boldsymbol u_0Au1=u0,通过保存 LULULU 分解因子,下一步计算 Au2=u1A\boldsymbol u_2=\boldsymbol u_1Au2=u1 就会很快。第 kkk 步则有 Auk=uk−1A\boldsymbol u_k=\boldsymbol u_{k-1}Auk=uk−1:反幂法 Inverse power methoduk=A−ku0=c1x1(λ1)k+c2x2(λ2)k+⋯+cnxn(λn)k(11.3.11)\pmb{反幂法\,\textrm{Inverse power method}}\kern 10pt\boldsymbol u_k=A^{-k}\boldsymbol u_0=\dfrac{c_1\boldsymbol x_1}{(\lambda_1)^k}+\dfrac{c_2\boldsymbol x_2}{(\lambda_2)^k}+\cdots+\dfrac{c_n\boldsymbol x_n}{(\lambda_n)^k}\kern 15pt(11.3.11)反幂法Inverse power methoduk=A−ku0=(λ1)kc1x1+(λ2)kc2x2+⋯+(λn)kcnxn(11.3.11)此时最小的特征值 λmin\lambda_{\textrm{min}}λmin 将占主导地位:当它非常小的情况下,因子 1λmink\dfrac{1}{\lambda^k_{\textrm{min}}}λmink1 就很大。为了加快收敛速度,我们可以将矩阵 AAA 平移,得到 A−λ∗IA-\lambda^*IA−λ∗I,这将会使得 λmin\lambda_{\textrm{min}}λmin 变得更小。

这种平移并不会改变特征向量(λ∗\lambda^*λ∗ 可以选择 AAA 的对角元素,更好的选择是瑞利商 xTAxxTx\dfrac{\boldsymbol x^TA\boldsymbol x}{\boldsymbol x^T\boldsymbol x}xTxxTAx). 如果 λ∗\lambda^*λ∗ 非常接近 λmin\lambda_{\textrm{min}}λmin,则 (A−λ∗I)−1(A-\lambda^*I)^{-1}(A−λ∗I)−1 将有非常大的特征值 (λmin−λ∗)−1(\lambda_{\textrm{min}}-\lambda^*)^{-1}(λmin−λ∗)−1. 平移后的反幂法每一步都用这个很大的特征值来乘特征向量,这样特征向量将很快占主导地位。

2、QR\pmb{QR}QR 方法(The QR method) 这是数值线性代数中一个很重要的成就。上世纪 505050 年代,特增值的计算不仅低效,而且也不准确,当时人们甚至还没有意识到求解 det⁡(A−λI)=0\det(A-\lambda I)=0det(A−λI)=0 来求特征值是一个非常糟糕的方法。雅可比曾经建议过应该将矩阵 AAA 逐步化成三角形 ------ 然后特征值就会自动出现在对角线上。他曾使用 2×22\times22×2 的旋转矩阵来将非对角线上的元素转换成零(不幸的是,这样之前的零元也会再次变成非零元,但是雅可比的方法在并行计算机上得到了部分应用)。而现在,QR\pmb{QR}QR 方法 是计算特征值的首选方法。

我们要用 QRQRQR 方法来求解 AAA 的特征值,其基本步骤就是要将 AAA 分解成 QRQRQR. 从 Gram-Schmidt 方法得到 QQQ 是正交矩阵,而 RRR 是三角形矩阵。求特征值的关键思想是:交换 QQQ 和 RRR 的顺序 ,得到新的矩阵 A1=RQA_1=RQA1=RQ,A=QRA=QRA=QR 和 A1=RQA_1=RQA1=RQ 有相同的特征值,这是因为 A=QRA=QRA=QR 与 A1=RQ=Q−1AQA_1=RQ=Q^{-1}AQA1=RQ=Q−1AQ 相似:A1=RQ 与 A=QR 有相同的特征值 λ由 QRx=λx可得RQ(Q−1x)=λ(Q−1x)(11.3.12)\pmb{A_1=RQ\,与\,A=QR\,有相同的特征值\,\lambda}\kern 8pt由\,QR\boldsymbol x=\lambda\boldsymbol x\kern 5pt可得\kern 5ptRQ(Q^{-1}\boldsymbol x)=\lambda(Q^{-1}\boldsymbol x)\kern 10pt(11.3.12)A1=RQ与A=QR有相同的特征值λ由QRx=λx可得RQ(Q−1x)=λ(Q−1x)(11.3.12)重复上述操作,将新的矩阵 A1A_1A1 分解成 Q1R1Q_1R_1Q1R1,然后再交换这两个因子的顺序得到 A2=R1Q1A_2=R_1Q_1A2=R1Q1,此时的 A2A_2A2 也与 A1A_1A1 相似,它的特征值不会变化。令人惊奇的是,随着这个的持续进行,特征值将会出现在矩阵的对角线上。很快 AnA_nAn 的右下角就会出现一个比较准确的特征值,此时,我们去掉最后一行和最后一列,然后继续使用更小一些的矩阵来求下一个特征值。

两个额外的技巧可以使得这个方法成功实施。第一是将矩阵先减去 III 的倍数,然后再将其分解成 QRQRQR,那么 RQRQRQ 平移回来即可得到 Ak+1A_{k+1}Ak+1:将 Ak−ckI 分解成 QkRk. 下一个矩阵是 Ak+1=RkQk+ckI.将\,A_k-c_kI\,分解成\,Q_kR_k. \,下一个矩阵是\,A_{k+1}=R_kQ_k+c_kI.将Ak−ckI分解成QkRk.下一个矩阵是Ak+1=RkQk+ckI.Ak+1A_{k+1}Ak+1 和 AkA_kAk 有相同的特征值,也与初始矩阵 A0=AA_0=AA0=A 的特征值相同。好的平移用到的常数 ccc 应该要接近一个暂时未知的特征值,这个特征值将近似等于 Ak+1A_{k+1}Ak+1 对角线中的某个元素 ------ 这会告诉我们下一步 Ak+2A_{k+2}Ak+2 要如何选择一个更好的 ccc.

第二个技巧是在 QRQRQR 方法开始前先将某些非对角元素变成零,用消元矩阵 EEE 或者吉文斯(Givens)旋转矩阵可以完成这件事,但是不要忘了还要右乘相应的逆矩阵 E−1E^{-1}E−1,否则特征值会改变:EAE−1=[11−11][123145167][1111]=[153195042]与 A 有相同的 λEAE^{-1}=\begin{bmatrix}1&\\&\kern 7pt1\\&-1&1\end{bmatrix}\begin{bmatrix}1&2&3\\\pmb1&4&5\\\pmb1&\pmb6&7 \end{bmatrix}\begin{bmatrix}1\\&1\\&1&1\end{bmatrix}=\begin{bmatrix}1&5&3\\\pmb1&9&5\\\pmb0&\pmb4&2\end{bmatrix}\kern 10pt\pmb{与\,A\,有相同的\,\lambda}EAE−1= 11−11 111246357 1111 = 110594352 与A有相同的λ次对角线上的非零元 111 和 444 不需处理,尽管使用更多的消元矩阵 EEE 可以消去它们,但是右乘 E−1E^{-1}E−1 后又会使得对应位置再次出现非零元。这是一个 "黑森伯格(Hessenberg matrix) ",主对角线下有一个非零的次对角线。左下角的零元在 QRQRQR 方法中仍然保持零元,这个操作使得每次的 QRQRQR 分解算法的复杂度从 O(n3)O(n^3)O(n3) 降至 O(n2)O(n^2)O(n2).

下面是一个针对黑森伯格矩阵结合第一个技巧的使用 QRQRQR 方法的例子,此例中首先将矩阵平移 7I7I7I,即将 AAA 对角线中的所有元素都减去 777(最后需要平移回来以得到 A1A_1A1):A=[12345600.0017]得到A1=[−0.541.690.8350.316.53−6.65600.000027.012]A=\begin{bmatrix}1&2&3\\4&5&6\\0&0.001&7\end{bmatrix}\kern 5pt得到\kern 5ptA_1=\begin{bmatrix}-0.54&1.69&\kern 7pt0.835\\\kern 7pt0.31&6.53&-6.656\\\kern 7pt0&0.00002&\kern 7pt7.012\end{bmatrix}A= 140250.001367 得到A1= −0.540.3101.696.530.000020.835−6.6567.012 将 A−7IA-7IA−7I 进行 QRQRQR 分解,然后得到 A1=RQ+7IA_1=RQ+7IA1=RQ+7I. 注意这里有一个非常小的元素 0.000020.000020.00002,对角线元素 7.0127.0127.012 与 A1A_1A1 的一个特征值就很接近了。对矩阵 A1A_1A1 减去 7.012I7.012I7.012I,再进行一次 QRQRQR 方法将会得到一个精度非常高的特征值。

相关推荐
X在敲AI代码2 小时前
【无标题】
算法·leetcode·职场和发展
bubiyoushang8882 小时前
NSGA-II 带精英策略的双目标遗传算法
算法
qq_430855882 小时前
线代第二章矩阵第八节逆矩阵、解矩阵方程
线性代数·算法·矩阵
月明长歌2 小时前
【码道初阶】Leetcode136:只出现一次的数字:异或一把梭 vs HashMap 计数(两种解法完整复盘)
java·数据结构·算法·leetcode·哈希算法
Swift社区2 小时前
LeetCode 456 - 132 模式
java·算法·leetcode
LYFlied2 小时前
【每日算法】LeetCode 152. 乘积最大子数组(动态规划)
前端·算法·leetcode·动态规划
爱学大树锯2 小时前
【(格式化字符串)】
算法
wearegogog1232 小时前
压缩感知和稀疏表示恢复算法中的L1同伦算法
人工智能·算法
core5123 小时前
决策树 (Decision Tree):像“猜猜看”游戏一样的AI算法
人工智能·算法·决策树