BiCGSTAB.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. // This file is part of Eigen, a lightweight C++ template library
  2. // for linear algebra.
  3. //
  4. // Copyright (C) 2011-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
  5. // Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
  6. //
  7. // This Source Code Form is subject to the terms of the Mozilla
  8. // Public License v. 2.0. If a copy of the MPL was not distributed
  9. // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
  10. #ifndef EIGEN_BICGSTAB_H
  11. #define EIGEN_BICGSTAB_H
  12. namespace Eigen {
  13. namespace internal {
  14. /** \internal Low-level bi conjugate gradient stabilized algorithm
  15. * \param mat The matrix A
  16. * \param rhs The right hand side vector b
  17. * \param x On input and initial solution, on output the computed solution.
  18. * \param precond A preconditioner being able to efficiently solve for an
  19. * approximation of Ax=b (regardless of b)
  20. * \param iters On input the max number of iteration, on output the number of performed iterations.
  21. * \param tol_error On input the tolerance error, on output an estimation of the relative error.
  22. * \return false in the case of numerical issue, for example a break down of BiCGSTAB.
  23. */
  24. template<typename MatrixType, typename Rhs, typename Dest, typename Preconditioner>
  25. bool bicgstab(const MatrixType& mat, const Rhs& rhs, Dest& x,
  26. const Preconditioner& precond, Index& iters,
  27. typename Dest::RealScalar& tol_error)
  28. {
  29. using std::sqrt;
  30. using std::abs;
  31. typedef typename Dest::RealScalar RealScalar;
  32. typedef typename Dest::Scalar Scalar;
  33. typedef Matrix<Scalar,Dynamic,1> VectorType;
  34. RealScalar tol = tol_error;
  35. Index maxIters = iters;
  36. Index n = mat.cols();
  37. VectorType r = rhs - mat * x;
  38. VectorType r0 = r;
  39. RealScalar r0_sqnorm = r0.squaredNorm();
  40. RealScalar rhs_sqnorm = rhs.squaredNorm();
  41. if(rhs_sqnorm == 0)
  42. {
  43. x.setZero();
  44. return true;
  45. }
  46. Scalar rho = 1;
  47. Scalar alpha = 1;
  48. Scalar w = 1;
  49. VectorType v = VectorType::Zero(n), p = VectorType::Zero(n);
  50. VectorType y(n), z(n);
  51. VectorType kt(n), ks(n);
  52. VectorType s(n), t(n);
  53. RealScalar tol2 = tol*tol*rhs_sqnorm;
  54. RealScalar eps2 = NumTraits<Scalar>::epsilon()*NumTraits<Scalar>::epsilon();
  55. Index i = 0;
  56. Index restarts = 0;
  57. while ( r.squaredNorm() > tol2 && i<maxIters )
  58. {
  59. Scalar rho_old = rho;
  60. rho = r0.dot(r);
  61. if (abs(rho) < eps2*r0_sqnorm)
  62. {
  63. // The new residual vector became too orthogonal to the arbitrarily chosen direction r0
  64. // Let's restart with a new r0:
  65. r = rhs - mat * x;
  66. r0 = r;
  67. rho = r0_sqnorm = r.squaredNorm();
  68. if(restarts++ == 0)
  69. i = 0;
  70. }
  71. Scalar beta = (rho/rho_old) * (alpha / w);
  72. p = r + beta * (p - w * v);
  73. y = precond.solve(p);
  74. v.noalias() = mat * y;
  75. alpha = rho / r0.dot(v);
  76. s = r - alpha * v;
  77. z = precond.solve(s);
  78. t.noalias() = mat * z;
  79. RealScalar tmp = t.squaredNorm();
  80. if(tmp>RealScalar(0))
  81. w = t.dot(s) / tmp;
  82. else
  83. w = Scalar(0);
  84. x += alpha * y + w * z;
  85. r = s - w * t;
  86. ++i;
  87. }
  88. tol_error = sqrt(r.squaredNorm()/rhs_sqnorm);
  89. iters = i;
  90. return true;
  91. }
  92. }
  93. template< typename _MatrixType,
  94. typename _Preconditioner = DiagonalPreconditioner<typename _MatrixType::Scalar> >
  95. class BiCGSTAB;
  96. namespace internal {
  97. template< typename _MatrixType, typename _Preconditioner>
  98. struct traits<BiCGSTAB<_MatrixType,_Preconditioner> >
  99. {
  100. typedef _MatrixType MatrixType;
  101. typedef _Preconditioner Preconditioner;
  102. };
  103. }
  104. /** \ingroup IterativeLinearSolvers_Module
  105. * \brief A bi conjugate gradient stabilized solver for sparse square problems
  106. *
  107. * This class allows to solve for A.x = b sparse linear problems using a bi conjugate gradient
  108. * stabilized algorithm. The vectors x and b can be either dense or sparse.
  109. *
  110. * \tparam _MatrixType the type of the sparse matrix A, can be a dense or a sparse matrix.
  111. * \tparam _Preconditioner the type of the preconditioner. Default is DiagonalPreconditioner
  112. *
  113. * \implsparsesolverconcept
  114. *
  115. * The maximal number of iterations and tolerance value can be controlled via the setMaxIterations()
  116. * and setTolerance() methods. The defaults are the size of the problem for the maximal number of iterations
  117. * and NumTraits<Scalar>::epsilon() for the tolerance.
  118. *
  119. * The tolerance corresponds to the relative residual error: |Ax-b|/|b|
  120. *
  121. * \b Performance: when using sparse matrices, best performance is achied for a row-major sparse matrix format.
  122. * Moreover, in this case multi-threading can be exploited if the user code is compiled with OpenMP enabled.
  123. * See \ref TopicMultiThreading for details.
  124. *
  125. * This class can be used as the direct solver classes. Here is a typical usage example:
  126. * \include BiCGSTAB_simple.cpp
  127. *
  128. * By default the iterations start with x=0 as an initial guess of the solution.
  129. * One can control the start using the solveWithGuess() method.
  130. *
  131. * BiCGSTAB can also be used in a matrix-free context, see the following \link MatrixfreeSolverExample example \endlink.
  132. *
  133. * \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner
  134. */
  135. template< typename _MatrixType, typename _Preconditioner>
  136. class BiCGSTAB : public IterativeSolverBase<BiCGSTAB<_MatrixType,_Preconditioner> >
  137. {
  138. typedef IterativeSolverBase<BiCGSTAB> Base;
  139. using Base::matrix;
  140. using Base::m_error;
  141. using Base::m_iterations;
  142. using Base::m_info;
  143. using Base::m_isInitialized;
  144. public:
  145. typedef _MatrixType MatrixType;
  146. typedef typename MatrixType::Scalar Scalar;
  147. typedef typename MatrixType::RealScalar RealScalar;
  148. typedef _Preconditioner Preconditioner;
  149. public:
  150. /** Default constructor. */
  151. BiCGSTAB() : Base() {}
  152. /** Initialize the solver with matrix \a A for further \c Ax=b solving.
  153. *
  154. * This constructor is a shortcut for the default constructor followed
  155. * by a call to compute().
  156. *
  157. * \warning this class stores a reference to the matrix A as well as some
  158. * precomputed values that depend on it. Therefore, if \a A is changed
  159. * this class becomes invalid. Call compute() to update it with the new
  160. * matrix A, or modify a copy of A.
  161. */
  162. template<typename MatrixDerived>
  163. explicit BiCGSTAB(const EigenBase<MatrixDerived>& A) : Base(A.derived()) {}
  164. ~BiCGSTAB() {}
  165. /** \internal */
  166. template<typename Rhs,typename Dest>
  167. void _solve_vector_with_guess_impl(const Rhs& b, Dest& x) const
  168. {
  169. m_iterations = Base::maxIterations();
  170. m_error = Base::m_tolerance;
  171. bool ret = internal::bicgstab(matrix(), b, x, Base::m_preconditioner, m_iterations, m_error);
  172. m_info = (!ret) ? NumericalIssue
  173. : m_error <= Base::m_tolerance ? Success
  174. : NoConvergence;
  175. }
  176. protected:
  177. };
  178. } // end namespace Eigen
  179. #endif // EIGEN_BICGSTAB_H