我正在尝试使用一个自定义预条件与Eigen的迭代求解器(例如CG)。具体来说,我必须多次解决类似的问题:矩阵略有变化,但保持接近平均矩阵。我想计算均值矩阵的Cholesky分解,然后将其用作预条件。
我的想法是这样的:
ConjugateGradient< SparseMatrix<double>, Lower, CholmodSupernodalLLT<SparseMatrix<double>> > solver(meanMatrix);
solver.preconditioner().compute(meanMatrix);
// Loop on n similar matrices
for(int i = 0; i < n; i++){
// create matrix: it is similar (in structure and in values) to meanMatrix
SparseMatrix<double> matrix = ...;
// create right-hand-side
VectorXd rhs = ...;
// update matrix reference for solver
solver.compute(matrix);
// solve using the preconditioned CG
solver.solve(rhs);
}
问题在于调用solver.compute(matrix)实际上会导致共轭梯度(实际上是IterativeSolverBase)在其前置条件上调用compute(参见IterativeSolverBase.h的1.111节,本章3.2.9节):
m_preconditioner.compute(*mp_matrix);
即基于均值矩阵的预条件被新矩阵的Cholesky分解所取代,因此CG解在1次迭代中收敛。相反,我想保持相同的预条件(平均矩阵的Cholesky分解,在循环之前一次性计算),并使用预条件CG求解不同的矩阵。
是否有一种简单的方法来实现我想做的事情?
提前感谢您的帮助!我希望这是有意义的。如果没有,请不要犹豫,让我澄清。
一种方法是围绕CholmodSupernodalLLT
编写一个小包装器,显示所需的预调节器API,其compute()
方法将是no-op。这可以从identitypreconditioning中获得灵感,在10-15行代码中完成。唯一需要更改的是存储CholmodSupernodalLLT
对象(或引用)并实现solve
以返回m_llt.solve(b);
。