/** testing of the Eigen CG. tests return true when they succeed. * * Copyright 2007-2013 IMP Inventors. All rights reserved. */ #ifndef IMPISD_INTERNAL_CG_EIGEN_H #define IMPISD_INTERNAL_CG_EIGEN_H #include #include #include #include IMPISD_BEGIN_INTERNAL_NAMESPACE using Eigen::MatrixXd; using Eigen::VectorXd; /** Simple implementation of the conjugate gradient method for matrices * This version is for Eigen dense matrices * */ class ConjugateGradientEigen : public base::Object { private: MatrixXd A_,B_,X0_,R_; bool has_A_,has_B_,has_X0_,has_tol_,success_,col_success_; double tol_; unsigned M_,N_,nsteps_,vec_steps_; public: //! Conjugate gradient algorithm for Eigen dense matrices ConjugateGradientEigen() : Object("cgEigen"), has_A_(false), has_B_(false), has_X0_(false), has_tol_(false), success_(false) {} /* \param[in] A the spd matrix for which the system AX=B * is to be solved. */ void set_A(const MatrixXd& A) { unsigned M = A.rows(); IMP_USAGE_CHECK(A.cols() == M, "must provide spd matrix!"); M_ = M; A_ = A; has_A_ = true; success_=false; } // \param[in] B void set_B(const MatrixXd& B) { N_ = B.cols(); B_ = B; has_B_ = true; success_=false; } // \param[in] X0 an initial guess for X void set_X0(const MatrixXd& X0) { X0_ = X0; has_X0_ = true; success_=false; } // set tolerance void set_tol(double tol) { if (tol < tol_) success_ = false; IMP_USAGE_CHECK(tol> 0, "Must provide positive tolerance!"); tol_=tol; has_tol_ = true; } // returns a number and a sign. The number is the total number of CG steps // performed. The sign is positive if all columns had residuals smaller than // the target, and negative otherwise. int info() { if(success_) { return nsteps_; } else { if (nsteps_