如何使用自定义预处理器与Eigen

时间:2016-10-11 14:48:32

标签: c++ eigen eigen3

我正在尝试使用自定义预处理器为迭代求解器(例如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>

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

非常感谢您的帮助!我希望这是有道理的。如果没有,请不要犹豫让我澄清。

1 个答案:

答案 0 :(得分:1)

一种方法是在CholmodSupernodalLLT周围编写一个小包装器,展示所需的预处理器API,其compute()方法将是无操作。这可以在10-15行代码中完成,灵感来自IdentityPreconditioner。 唯一需要的更改是存储CholmodSupernodalLLT对象(或引用)并实现solve以返回m_llt.solve(b);