Eigen迭代求解器类
1. 迭代求解器核心类概览
Eigen 提供多种迭代法求解稀疏线性方程组 Ax=bAx=b,适用于大规模稀疏矩阵:
求解器类 | 适用矩阵类型 | 算法 | 关键特性 |
---|---|---|---|
ConjugateGradient | 对称正定(SPD) | 共轭梯度法(CG) | 高精度,内存效率高 |
LeastSquaresConjugateGradient | 矩形矩阵 | 最小二乘 CG(LSQR) | 解最小二乘问题 min∥Ax−b∥2min∥Ax−b∥2 |
BiCGSTAB | 非对称 | 稳定双共轭梯度法 | 适用一般矩阵,收敛速度快 |
GMRES | 非对称 | 广义最小残差法 | 适合病态系统,需重启参数 |
DGMRES | 非对称 | 动态 GMRES | 自适应子空间大小 |
MINRES | 对称不定 | 最小残差法 | 无需正定性 |
2. 通用属性与方法
所有迭代求解器继承自 Eigen::IterativeSolverBase
,提供统一接口:
核心方法
方法 | 参数说明 | 返回值/功能 | 示例 |
---|---|---|---|
compute(const MatrixType& A) | A : 稀疏矩阵 | 预计算分解(如预处理) | solver.compute(A); |
solve(const VectorType& b) | b : 右侧向量 | 返回解向量 xx | VectorXd x = solver.solve(b); |
info() | 无 | 返回收敛状态(Success /NoConvergence ) | if (solver.info() != Success) {...} |
iterations() | 无 | 返回实际迭代次数 | int iters = solver.iterations(); |
error() | 无 | 返回最后一次迭代的误差估计 | double err = solver.error(); |
通用参数设置
方法 | 参数说明 | 默认值 | 示例 |
---|---|---|---|
setTolerance(Scalar tol) | 设置收敛容差 | 1e-10 | solver.setTolerance(1e-6); |
setMaxIterations(int max_it) | 设置最大迭代次数 | 取决于求解器 | solver.setMaxIterations(1000); |
setPreconditioner(Precond) | 设置预条件子(见下文) | Identity | solver.setPreconditioner(ILU); |
3. 各求解器特有方法
(1) ConjugateGradient
(CG)
-
特有设置:
cpp
// 设置对角预条件子(默认启用) solver.setPreconditioner(DiagonalPreconditioner<double>());
(2) BiCGSTAB
-
重启参数(无默认重启):
cpp
// 设置重启周期(GMRES/DGMRES 适用) solver.set_restart(30); // 每30次迭代重启
(3) GMRES
/ DGMRES
-
子空间大小:
cpp
// 设置子空间维度(默认30) GMRES<SparseMatrix<double>> solver; solver.set_restart(50); // 重启周期=子空间大小
4. 预条件子(Preconditioner)
预条件子可加速收敛,Eigen 提供以下选项:
预条件子类 | 适用场景 | 配置方法 |
---|---|---|
DiagonalPreconditioner | 对角占优矩阵 | 默认启用(CG) |
IncompleteLUT (ILU) | 通用稀疏矩阵 | solver.preconditioner().setFillfactor(2); |
IdentityPreconditioner | 无预处理(默认) | 无需配置 |
ILU 预条件子示例
cpp
ConjugateGradient<SparseMatrix<double>, Lower, IncompleteLUT<double>> solver;
solver.preconditioner().setFillfactor(2); // 填充因子
solver.compute(A);
VectorXd x = solver.solve(b);
5. 代码示例
基本使用(CG 求解对称正定系统)
cpp
#include <Eigen/Sparse>
#include <Eigen/IterativeLinearSolvers>
using namespace Eigen;SparseMatrix<double> A(1000, 1000);
VectorXd b = VectorXd::Random(1000);
// 填充 A 为对称正定矩阵...ConjugateGradient<SparseMatrix<double>> solver;
solver.setTolerance(1e-8);
solver.setMaxIterations(1000);
solver.compute(A);VectorXd x = solver.solve(b);
std::cout << "#iterations: " << solver.iterations() << ", error: " << solver.error() << std::endl;
BiCGSTAB 解非对称系统
cpp
BiCGSTAB<SparseMatrix<double>> solver;
solver.setTolerance(1e-6);
solver.compute(A);
VectorXd x = solver.solve(b);
6. 参数选择建议
参数 | 推荐值/策略 | 说明 |
---|---|---|
容差 (tolerance ) | 1e-6 ~ 1e-10 | 根据精度需求调整 |
最大迭代次数 | 1000~5000 | 避免无限循环 |
预条件子 | ILU 或 Diagonal | 依矩阵特性选择 |
重启周期(GMRES) | 30~50 | 内存与收敛速度的权衡 |
7. 性能优化技巧
-
矩阵格式:确保输入矩阵为
SparseMatrix
且已调用makeCompressed()
。 -
预条件子:对病态系统,ILU 预条件子可显著提升收敛速度。
-
** warm-start**:若多次求解相同矩阵不同 bb,复用
compute(A)
结果。
8. 常见错误处理
-
不收敛:检查矩阵是否满足求解器要求(如 CG 需对称正定)。
-
数值不稳定:尝试调整容差或改用更稳定的算法(如 MINRES)。
-
内存不足:减小 GMRES 重启参数或使用内存友好的 CG。
掌握这些迭代求解器后,可高效处理大规模稀疏线性系统!更多细节见 Eigen 文档。