矩阵平衡(Matrix Balancing)是一种通过相似变换改善矩阵条件数的技术,旨在加速迭代求解的收敛并提高数值稳定性。以下是关键算法实现及步骤详解:
1. 对角缩放法(Diagonal Scaling)
核心思想:通过左乘和右乘对角矩阵 ( D ) 和 ( D^{-1} ) 对矩阵 ( A ) 进行平衡,使得变换后矩阵 ( B = DAD^{-1} ) 的行和列范数接近。
算法步骤:
- 计算缩放因子 :
- 对每行 ( i ),计算 ( d_i = \sqrt{|A_{i,:}|1 / |A{:,i}|_1} )(即行和与列和的几何平均)。
- 构造对角矩阵 :
- ( D = \text{diag}(d_1, d_2, \dots, d_n) )。
- 应用变换 :
- 平衡后的矩阵 ( B = DAD^{-1} )。
特点:
- 保持对称性(若 ( A ) 对称,( B ) 仍对称)。
- 适用于非对称矩阵,显著降低条件数。
2. Sinkhorn-Knopp 算法
目标:使矩阵的双随机性(行和与列和均为1)最大化,适用于非负矩阵。
迭代步骤:
- 交替缩放行和列:
- 行缩放:( A_{ij} \leftarrow A_{ij} / \sum_k A_{ik} )(使每行和为1)。
- 列缩放:( A_{ij} \leftarrow A_{ij} / \sum_k A_{kj} )(使每列和为1)。
- 重复直至收敛(行和列和接近1)。
应用场景:
- 概率转移矩阵、图像处理中的归一化。
3. Parlett-Reinsch 算法(对称矩阵平衡)
步骤:
- 计算对称矩阵 ( A ) 的按行/列无穷范数。
- 通过对角变换 ( DAD^{-1} ) 使行列范数均衡。
优势:
- 保持特征值不变,优化条件数 ( \kappa_2(A) )。
4. 分块平衡(Block Balancing)
适用场景 :大型稀疏矩阵或分块矩阵。
方法:
- 对每个对角块独立应用对角缩放,全局协调缩放因子。
5. 基于特征值的平衡(LAPACK 实现)
LAPACK 例程 :xGEBAL
(如 DGEBAL
for double precision)
步骤:
- 计算行列缩放因子,避免溢出。
- 可选左/右缩放或同时缩放。
- 通过置换进一步优化数值稳定性。
输出:
- 缩放后的矩阵 ( B ) 和缩放因子 ( D ),可用于后续求解(如
xGESV
)。
效果评估
- 条件数改善:平衡后 ( \kappa(B) \ll \kappa(A) )。
- 加速迭代法:如共轭梯度法(CG)、GMRES 的收敛步数减少。
- 数值稳定性:避免病态矩阵导致的浮点误差放大。
代码示例(Python)
python
import numpy as np
from scipy.linalg import balance
# 生成病态矩阵
A = np.array([[1e6, 1], [1, 1e-6]])
# 平衡矩阵
B, D = balance(A, scale=True) # D 为对角缩放矩阵
print("原矩阵条件数:", np.linalg.cond(A))
print("平衡后条件数:", np.linalg.cond(B))
总结
- 密集矩阵 :优先使用 LAPACK 的
xGEBAL
。 - 非负矩阵:Sinkhorn-Knopp 适合双随机化。
- 对称矩阵:Parlett-Reinsch 算法保持结构。
- 稀疏矩阵:分块平衡或迭代缩放。
平衡技术虽增加预处理开销,但能显著提升求解效率,尤其适合病态系统的迭代法和直接法(如 LU 分解)。