如何在Eigen中使用自定义预处理器 [英] How to use custom preconditioner with Eigen
问题描述
我正在尝试将自定义的预处理器用于Eigen的迭代求解器(例如CG).具体来说,我必须多次解决类似的问题:矩阵略有变化,但保持接近均值矩阵.我想计算我的均值矩阵的Cholesky分解,然后将其用作前置条件.
我的想法是这样的:
ConjugateGradient<稀疏矩阵Double,下半部,CholmodSupernodalLLT SparseMatrix double.>求解器(meanMatrix);resolver.preconditioner().compute(meanMatrix);//在n个相似的矩阵上循环for(int i = 0; i< n; i ++){//创建矩阵:它与meanMatrix相似(在结构和值上)SparseMatrix< double>矩阵= ...;//创建右侧VectorXd rhs = ...;//更新求解器的矩阵参考Solver.compute(matrix);//使用预处理的CG求解Solver.solve(rhs);}
问题在于,调用 solver.compute(matrix)实际上会导致ConjugateGradient(实际上是IterativeSolverBase)在其预处理器上调用 compute (请参阅IterativeSolverBase的第111条.h,本征3.2.9):
m_preconditioner.compute(* mp_matrix);
换句话说,基于均值矩阵的预处理器被新矩阵的Cholesky分解所取代,因此CG解在1次迭代中收敛.相反,我想保留相同的预处理器(均值矩阵的Cholesky分解,在循环之前一劳永逸地计算),并使用预处理的CG求解不同的矩阵./p>
有没有一种简单的方法可以实现我想要做的事情?
在此先感谢您的帮助!我希望这是有道理的.如果没有,请不要犹豫,让我澄清一下.
一种方法是在 The problem is that calling solver.compute(matrix) actually causes ConjugateGradient (in fact IterativeSolverBase) to call compute on its preconditioner (see l. 111 of IterativeSolverBase.h, Eigen 3.2.9): In other words, the preconditioner based on the mean matrix is replaced by the Cholesky decomposition of the new matrix, and thus the CG solve converges in 1 iteration. On the contrary, I would like to keep the same preconditioner (the Cholesky decomposition of the mean matrix, computed once and for all before the loop), and solve for the different matrices using the preconditioned CG. Is there an easy way to achieve what I am trying to do? Many thanks in advance for your help! I hope this makes sense. If not, please do not hesitate to ask me to clarify. One way would be to write a small wrapper around 这篇关于如何在Eigen中使用自定义预处理器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! CholmodSupernodalLLT
周围写一个小的包装,展示所需的前置条件API及其 compute()
方法将是无操作的.这可以从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);
}
m_preconditioner.compute(*mp_matrix);
CholmodSupernodalLLT
exhibiting the required preconditioner API and whose compute()
method would be a no-op. This can be done in 10-15 lines of code taking inspiration from the IdentityPreconditioner.
The only required changes is to store a CholmodSupernodalLLT
object (or reference) and implement solve
to return m_llt.solve(b);
.