Eigen::VectorXf testEigen2(const Eigen::MatrixXf &A,const Eigen::VectorXf &b){ Eigen::VectorXf x(size); Eigen::ConjugateGradient<Eigen::MatrixXf > cg; cg.compute(A); x = cg.solve(b); std::cout << "#iterations: " << cg.iterations() << std::endl; std::cout << "estimated error: " << cg.error() << std::endl; return x; }
int main() { int n = 10; Eigen::SparseMatrix<double> S = Eigen::MatrixXd::Random(n,n).sparseView(0.5,1); S = S.transpose()*S; MatrixReplacement A; A.attachMyMatrix(S); Eigen::VectorXd b(n), x; b.setRandom(); // Solve Ax = b using various iterative solver with matrix-free version: { Eigen::ConjugateGradient<MatrixReplacement, Eigen::Lower|Eigen::Upper, Eigen::IdentityPreconditioner> cg; cg.compute(A); x = cg.solve(b); std::cout << "CG: #iterations: " << cg.iterations() << ", estimated error: " << cg.error() << std::endl; } { Eigen::BiCGSTAB<MatrixReplacement, Eigen::IdentityPreconditioner> bicg; bicg.compute(A); x = bicg.solve(b); std::cout << "BiCGSTAB: #iterations: " << bicg.iterations() << ", estimated error: " << bicg.error() << std::endl; } { Eigen::GMRES<MatrixReplacement, Eigen::IdentityPreconditioner> gmres; gmres.compute(A); x = gmres.solve(b); std::cout << "GMRES: #iterations: " << gmres.iterations() << ", estimated error: " << gmres.error() << std::endl; } { Eigen::DGMRES<MatrixReplacement, Eigen::IdentityPreconditioner> gmres; gmres.compute(A); x = gmres.solve(b); std::cout << "DGMRES: #iterations: " << gmres.iterations() << ", estimated error: " << gmres.error() << std::endl; } { Eigen::MINRES<MatrixReplacement, Eigen::Lower|Eigen::Upper, Eigen::IdentityPreconditioner> minres; minres.compute(A); x = minres.solve(b); std::cout << "MINRES: #iterations: " << minres.iterations() << ", estimated error: " << minres.error() << std::endl; } }
std::pair<unsigned int, Real> EigenSparseLinearSolver<T>::solve (SparseMatrix<T> &matrix_in, NumericVector<T> &solution_in, NumericVector<T> &rhs_in, const double tol, const unsigned int m_its) { START_LOG("solve()", "EigenSparseLinearSolver"); this->init (); // Make sure the data passed in are really Eigen types EigenSparseMatrix<T>& matrix = libmesh_cast_ref<EigenSparseMatrix<T>&>(matrix_in); EigenSparseVector<T>& solution = libmesh_cast_ref<EigenSparseVector<T>&>(solution_in); EigenSparseVector<T>& rhs = libmesh_cast_ref<EigenSparseVector<T>&>(rhs_in); // Close the matrix and vectors in case this wasn't already done. matrix.close(); solution.close(); rhs.close(); std::pair<unsigned int, Real> retval(0,0.); // Solve the linear system switch (this->_solver_type) { // Conjugate-Gradient case CG: { Eigen::ConjugateGradient<EigenSM> solver (matrix._mat); solver.setMaxIterations(m_its); solver.setTolerance(tol); solution._vec = solver.solveWithGuess(rhs._vec,solution._vec); libMesh::out << "#iterations: " << solver.iterations() << std::endl; libMesh::out << "estimated error: " << solver.error() << std::endl; retval = std::make_pair(solver.iterations(), solver.error()); break; } // Bi-Conjugate Gradient Stabilized case BICGSTAB: { Eigen::BiCGSTAB<EigenSM> solver (matrix._mat); solver.setMaxIterations(m_its); solver.setTolerance(tol); solution._vec = solver.solveWithGuess(rhs._vec,solution._vec); libMesh::out << "#iterations: " << solver.iterations() << std::endl; libMesh::out << "estimated error: " << solver.error() << std::endl; retval = std::make_pair(solver.iterations(), solver.error()); break; } // // Generalized Minimum Residual // case GMRES: // { // libmesh_not_implemented(); // break; // } // Unknown solver, use BICGSTAB default: { libMesh::err << "ERROR: Unsupported Eigen Solver: " << Utility::enum_to_string(this->_solver_type) << std::endl << "Continuing with BICGSTAB" << std::endl; this->_solver_type = BICGSTAB; STOP_LOG("solve()", "EigenSparseLinearSolver"); return this->solve (matrix, solution, rhs, tol, m_its); } } STOP_LOG("solve()", "EigenSparseLinearSolver"); return retval; }