Appearance
10. 稀疏矩阵与定常迭代
大规模离散问题中的矩阵通常很稀疏。此时真正昂贵的不是一个标量运算,而是存储、访存以及不必要的填充。本章先说明如何保存稀疏矩阵,再讨论最基本的迭代解法。
10.1 CSC 存储与稀疏矩阵乘法
压缩列存储(CSC)使用三个数组:
values:按列保存非零元;row_indices:对应的行号;col_ptr:每一列在前两个数组中的起止位置。
计算
若矩阵有
稀疏算法的第一原则:围绕非零元组织计算,不要先把矩阵转成稠密格式。
坐标格式(COO)用三元组
选择格式要服从操作:CSR 适合逐行计算
10.2 矩阵分裂
将线性方程组写成
其中
误差满足
这个判据精确但未必容易直接验证,实际常用对角占优、正定性或范数估计给出充分条件。
10.3 Jacobi、Gauss–Seidel 与 SOR
按约定写
其中
Jacobi
各分量只使用上一轮结果,容易并行。
Gauss–Seidel
新得到的分量会立即参与后续计算,串行依赖更强,但通常比 Jacobi 快。
SOR
引入松弛参数
10.4 何时可以保证收敛
- 若
严格行对角占优,则 Jacobi 与 Gauss–Seidel 均收敛。 - 若
对称正定,则 Gauss–Seidel 收敛。 - 即便残差单调下降,误差也未必按同样速度下降;两者由
的条件数联系。
严格行对角占优下,可用最大模分量证明。若
即可推出
10.5 二维 Poisson 方程
在单位正方形上用五点差分离散
得到
所得矩阵稀疏、对称、正定。随着网格加密,条件数约按
在规则网格上,Jacobi 对高频误差衰减快、对低频误差衰减慢。红黑排序把棋盘相邻点染成不同颜色:同色点之间不直接耦合,可以并行更新;完成红、黑两次更新相当于一种重排后的 Gauss-Seidel。
10.6 停机标准与实现检查
常用相对残差
作为停机指标,并同时设置最大迭代次数。实现时应记录残差历史;若出现停滞或增长,检查矩阵分裂、索引和松弛参数,而不是只增加迭代次数。
10.7 SOR 的参数与谱
SOR 的迭代矩阵为
最佳
10.8 定常迭代就是预条件 Richardson
从分裂
所以每一步都在用
10.9 多重网格思想
细网格上的低频误差在粗网格上看起来更高频,因此可以通过三步循环消除:
- 在细网格做少量平滑,压低高频误差;
- 把残差限制到粗网格,近似求解误差方程;
- 插值校正回细网格,再做后平滑。
若各层工作量按几何级数下降,一个 V-cycle 可达到近
10.10 稀疏实现的验证
- 用小型稠密矩阵核对 COO 到 CSC/CSR 的转换和转置乘法。
- 检查重复坐标是否正确求和、空行/空列的指针是否一致。
- 区分递推残差与显式残差,周期性重算
。 - 报告每步
成本之外,还要报告迭代次数和预处理成本。
自检
- 为什么
与对任意初值收敛等价? - CSC 格式下如何分别实现
与 ? - 为什么细网格上的 Poisson 问题会让 Jacobi 变慢?
- 如何从矩阵分裂看出定常迭代本质上是预条件残差校正?
- 多重网格为什么能同时处理高频与低频误差?