diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2017-03-25 14:17:07 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2017-03-25 14:17:07 +0100 |
commit | 35f7829af10c61e33dd2e2a7a015058e11a11ea0 (patch) | |
tree | 7135010dcf8fd0a49f3020d52112709bcb883bd6 /eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h | |
parent | 6e8724193e40a932faf9064b664b529e7301c578 (diff) |
update
Diffstat (limited to 'eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h')
-rw-r--r-- | eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h | 97 |
1 files changed, 31 insertions, 66 deletions
diff --git a/eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h b/eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h index 5512219..454f468 100644 --- a/eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h +++ b/eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h @@ -1,7 +1,7 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr> +// Copyright (C) 2011-2014 Gael Guennebaud <gael.guennebaud@inria.fr> // Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr> // // This Source Code Form is subject to the terms of the Mozilla @@ -27,7 +27,7 @@ namespace internal { */ template<typename MatrixType, typename Rhs, typename Dest, typename Preconditioner> bool bicgstab(const MatrixType& mat, const Rhs& rhs, Dest& x, - const Preconditioner& precond, int& iters, + const Preconditioner& precond, Index& iters, typename Dest::RealScalar& tol_error) { using std::sqrt; @@ -36,9 +36,9 @@ bool bicgstab(const MatrixType& mat, const Rhs& rhs, Dest& x, typedef typename Dest::Scalar Scalar; typedef Matrix<Scalar,Dynamic,1> VectorType; RealScalar tol = tol_error; - int maxIters = iters; + Index maxIters = iters; - int n = mat.cols(); + Index n = mat.cols(); VectorType r = rhs - mat * x; VectorType r0 = r; @@ -59,20 +59,21 @@ bool bicgstab(const MatrixType& mat, const Rhs& rhs, Dest& x, VectorType s(n), t(n); - RealScalar tol2 = tol*tol; + RealScalar tol2 = tol*tol*rhs_sqnorm; RealScalar eps2 = NumTraits<Scalar>::epsilon()*NumTraits<Scalar>::epsilon(); - int i = 0; - int restarts = 0; + Index i = 0; + Index restarts = 0; - while ( r.squaredNorm()/rhs_sqnorm > tol2 && i<maxIters ) + while ( r.squaredNorm() > tol2 && i<maxIters ) { Scalar rho_old = rho; rho = r0.dot(r); if (abs(rho) < eps2*r0_sqnorm) { - // The new residual vector became too orthogonal to the arbitrarily choosen direction r0 + // The new residual vector became too orthogonal to the arbitrarily chosen direction r0 // Let's restart with a new r0: + r = rhs - mat * x; r0 = r; rho = r0_sqnorm = r.squaredNorm(); if(restarts++ == 0) @@ -131,35 +132,33 @@ struct traits<BiCGSTAB<_MatrixType,_Preconditioner> > * \tparam _MatrixType the type of the sparse matrix A, can be a dense or a sparse matrix. * \tparam _Preconditioner the type of the preconditioner. Default is DiagonalPreconditioner * + * \implsparsesolverconcept + * * The maximal number of iterations and tolerance value can be controlled via the setMaxIterations() * and setTolerance() methods. The defaults are the size of the problem for the maximal number of iterations * and NumTraits<Scalar>::epsilon() for the tolerance. * + * The tolerance corresponds to the relative residual error: |Ax-b|/|b| + * + * \b Performance: when using sparse matrices, best performance is achied for a row-major sparse matrix format. + * Moreover, in this case multi-threading can be exploited if the user code is compiled with OpenMP enabled. + * See \ref TopicMultiThreading for details. + * * This class can be used as the direct solver classes. Here is a typical usage example: - * \code - * int n = 10000; - * VectorXd x(n), b(n); - * SparseMatrix<double> A(n,n); - * // fill A and b - * BiCGSTAB<SparseMatrix<double> > solver; - * solver.compute(A); - * x = solver.solve(b); - * std::cout << "#iterations: " << solver.iterations() << std::endl; - * std::cout << "estimated error: " << solver.error() << std::endl; - * // update b, and solve again - * x = solver.solve(b); - * \endcode + * \include BiCGSTAB_simple.cpp * * By default the iterations start with x=0 as an initial guess of the solution. * One can control the start using the solveWithGuess() method. * + * BiCGSTAB can also be used in a matrix-free context, see the following \link MatrixfreeSolverExample example \endlink. + * * \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner */ template< typename _MatrixType, typename _Preconditioner> class BiCGSTAB : public IterativeSolverBase<BiCGSTAB<_MatrixType,_Preconditioner> > { typedef IterativeSolverBase<BiCGSTAB> Base; - using Base::mp_matrix; + using Base::matrix; using Base::m_error; using Base::m_iterations; using Base::m_info; @@ -167,7 +166,6 @@ class BiCGSTAB : public IterativeSolverBase<BiCGSTAB<_MatrixType,_Preconditioner public: typedef _MatrixType MatrixType; typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::Index Index; typedef typename MatrixType::RealScalar RealScalar; typedef _Preconditioner Preconditioner; @@ -190,35 +188,19 @@ public: explicit BiCGSTAB(const EigenBase<MatrixDerived>& A) : Base(A.derived()) {} ~BiCGSTAB() {} - - /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A - * \a x0 as an initial solution. - * - * \sa compute() - */ - template<typename Rhs,typename Guess> - inline const internal::solve_retval_with_guess<BiCGSTAB, Rhs, Guess> - solveWithGuess(const MatrixBase<Rhs>& b, const Guess& x0) const - { - eigen_assert(m_isInitialized && "BiCGSTAB is not initialized."); - eigen_assert(Base::rows()==b.rows() - && "BiCGSTAB::solve(): invalid number of rows of the right hand side matrix b"); - return internal::solve_retval_with_guess - <BiCGSTAB, Rhs, Guess>(*this, b.derived(), x0); - } - + /** \internal */ template<typename Rhs,typename Dest> - void _solveWithGuess(const Rhs& b, Dest& x) const + void _solve_with_guess_impl(const Rhs& b, Dest& x) const { bool failed = false; - for(int j=0; j<b.cols(); ++j) + for(Index j=0; j<b.cols(); ++j) { m_iterations = Base::maxIterations(); m_error = Base::m_tolerance; typename Dest::ColXpr xj(x,j); - if(!internal::bicgstab(*mp_matrix, b.col(j), xj, Base::m_preconditioner, m_iterations, m_error)) + if(!internal::bicgstab(matrix(), b.col(j), xj, Base::m_preconditioner, m_iterations, m_error)) failed = true; } m_info = failed ? NumericalIssue @@ -228,36 +210,19 @@ public: } /** \internal */ + using Base::_solve_impl; template<typename Rhs,typename Dest> - void _solve(const Rhs& b, Dest& x) const + void _solve_impl(const MatrixBase<Rhs>& b, Dest& x) const { -// x.setZero(); - x = b; - _solveWithGuess(b,x); + x.resize(this->rows(),b.cols()); + x.setZero(); + _solve_with_guess_impl(b,x); } protected: }; - -namespace internal { - - template<typename _MatrixType, typename _Preconditioner, typename Rhs> -struct solve_retval<BiCGSTAB<_MatrixType, _Preconditioner>, Rhs> - : solve_retval_base<BiCGSTAB<_MatrixType, _Preconditioner>, Rhs> -{ - typedef BiCGSTAB<_MatrixType, _Preconditioner> Dec; - EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) - - template<typename Dest> void evalTo(Dest& dst) const - { - dec()._solve(rhs(),dst); - } -}; - -} // end namespace internal - } // end namespace Eigen #endif // EIGEN_BICGSTAB_H |