Eigen库使用带不完全Cholesky预处理器的共轭梯度法编译报错
报错核心原因
你遇到的编译错误本质是更换预处理器后,ConjugateGradient类的三角标记模板参数传入值不符合IncompleteCholesky预处理器的接口要求:
- Eigen中
ConjugateGradient的第二个模板参数UpLo用于指定矩阵参与求解的三角部分范围,原代码传入Eigen::Lower | Eigen::Upper的组合标记时,求解器会把输入矩阵包装为对应组合标记的SelfAdjointView对象 - 原代码使用默认预处理器时,组合三角标记是兼容的,因为默认预处理器不会调用需要单一三角标记的
twistedBy接口;但IncompleteCholesky类的内部实现(对应报错行202的位置)会调用twistedBy方法实现换序分解,这个接口只有标记为单一上三角/下三角的SelfAdjointView才会实现,组合标记的视图没有这个接口,因此触发编译报错。
具体修复方案
- 修正模板参数的三角标记值。不完全Cholesky分解本身仅需要访问对称正定矩阵的单侧三角部分,不需要传入组合标记:如果你的矩阵是按下三角存储有效信息,传
Eigen::Lower;如果按上三角存储有效信息,传Eigen::Upper即可,代码示例如下:// 下三角存储的对称正定矩阵场景 Eigen::ConjugateGradient< Eigen::MatrixXd, Eigen::Lower, // 移除原代码中的| Eigen::Upper部分 Eigen::IncompleteCholesky<double> > cg; - 调用分解接口时显式传入矩阵的单侧三角视图,避免自动推导错误:
// A为待求解的对称正定矩阵 cg.compute(A.selfadjointView<Eigen::Lower>()); - 确认Eigen版本兼容性:
IncompleteCholesky类是Eigen 3.3.0版本之后正式加入的模块,低于该版本的Eigen库存在接口缺失的问题,建议使用3.4及以上稳定版本。
额外注意事项
不完全Cholesky预处理器仅适用于对称正定线性系统,不能用于求解非对称矩阵的方程组,否则会在分解过程中出现零主元的数值计算错误。
内容的提问来源于stack exchange,提问作者Bo Jiang
相关产品推荐
相关产品推荐

