Eigen的LeastSquaresConjugateGradient求解器:使用不完整的Cholesky预处理器并指定系数起始值

时间:2019-09-13 15:44:26

标签: eigen rcpp least-squares

要求解方程的矩形稀疏线性系统,我想使用Eigen的LeastSquaresConjugateGradient。除了默认的Jacobi和Identity预处理器之外,我想知道是否还可以在LeastSquaresConjugateGradient中将Incomplete Cholesky用作预处理器?

我拥有的Rcpp代码使用默认的Jacobi([LeastSquareDiagonalPreconditioner]预处理器)是:

library(inline)
library(RcppEigen)

solve_sparse_lsconjgrad <- cxxfunction( signature(input_ = "list"), '
    using Eigen::VectorXd;
    using Eigen::MatrixXd;
    using Eigen::Lower;
    using Eigen::Map;
    using Eigen::SparseMatrix;
    using Eigen::IdentityPreconditioner;
    // using Eigen::IncompleteCholesky;
    using Eigen::LeastSquaresConjugateGradient;
    List input(input_);
    const Map<SparseMatrix<double> > m1 = input[0]; // X
    const Map<VectorXd>              v1 = input[1]; // y
    const Map<VectorXd>              x = input[2]; // initial coefficient guess
    SparseMatrix<double>             m2(m1.cols(), m1.cols());
    m2.selfadjointView<Lower>().rankUpdate(m1.adjoint());
    Eigen::LeastSquaresConjugateGradient<SparseMatrix<double> > solver; 
    solver.setMaxIterations(100);
    solver.setTolerance(1E-20);
    solver.compute(m1);
    VectorXd                        res = solver.solveWithGuess(v1, x); 
    return List::create(_["res"]   = res,
                        _["rows"]  = double(solver.rows()),
                        _["cols"]  = double(solver.cols()));
',
                                      plugin = "RcppEigen")

用法是

solve_sparse_lsconjgrad(list(X, y, coefficient_starting_values))

但是我应该如何修改它以使用IncompleteCholesky作为前置条件呢?在另一个堆栈溢出问题中,我看到需要定义

typedef LeastSquaresConjugateGradient<SparseMatrix<double>, IncompleteCholesky<double> > ICCG;

但是我不确定然后如何在上面的代码中使用它。有什么想法吗?我还想知道我是否正确传递了初始系数估算值,因为我注意到,如果我解决了一次问题,并且将获得的系数用作新的拟合值的起始值,我几乎不会获得任何速度优势,我认为这很奇怪...

0 个答案:

没有答案