我正在尝试使用自定义预处理器为迭代求解器(例如CG)和Eigen。具体来说,我必须多次解决类似的问题:矩阵略有变化,但仍然接近平均矩阵。我想计算我的均值矩阵的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)实际上会导致ConjugateGradient(实际上是IterativeSolverBase)在其预处理器上调用 compute (参见IterativeSolverBase的111)。 h,Eigen 3.2.9):
m_preconditioner.compute(*mp_matrix);
换句话说,基于均值矩阵的预处理器被新矩阵的Cholesky分解所取代,因此CG求解在1次迭代中收敛。相反,我想保持相同的预处理器(均值矩阵的Cholesky分解,在循环之前一劳永逸地计算),并使用预处理的CG求解不同的矩阵。 / p>
有没有一种简单的方法来实现我想要做的事情?
非常感谢您的帮助!我希望这是有道理的。如果没有,请不要犹豫让我澄清。
答案 0 :(得分:1)
一种方法是在CholmodSupernodalLLT
周围编写一个小包装器,展示所需的预处理器API,其compute()
方法将是无操作。这可以在10-15行代码中完成,灵感来自IdentityPreconditioner。
唯一需要的更改是存储CholmodSupernodalLLT
对象(或引用)并实现solve
以返回m_llt.solve(b);
。