如何在Eigen中使用自定义预处理器 [英] How to use custom preconditioner with Eigen

查看:132
本文介绍了如何在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>

有没有一种简单的方法可以实现我想要做的事情?

在此先感谢您的帮助!我希望这是有道理的.如果没有,请不要犹豫,让我澄清一下.

解决方案

一种方法是在 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); }

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):

m_preconditioner.compute(*mp_matrix);

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 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);.

这篇关于如何在Eigen中使用自定义预处理器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆