So-Bogus
A c++ sparse block matrix library aimed at Second Order cone problems
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
KrylovMethods.hpp
1 /*
2  * This file is part of bogus, a C++ sparse block matrix library.
3  *
4  * Copyright 2013 Gilles Daviet <gdaviet@gmail.com>
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 */
10 
11 #ifndef BOGUS_KRYLOV_METHODS_HPP
12 #define BOGUS_KRYLOV_METHODS_HPP
13 
14 #include "../BlockSolvers.fwd.hpp"
15 
16 #include "../Utils/LinearSolverBase.hpp"
17 #include "../Utils/Signal.hpp"
18 #include "../Utils/NumTraits.hpp"
19 #include "../Utils/CppTools.hpp"
20 
21 #define BOGUS_KRYLOV_METHODS \
22  BOGUS_PROCESS_KRYLOV_METHOD(CG )\
23  BOGUS_PROCESS_KRYLOV_METHOD(BiCG )\
24  BOGUS_PROCESS_KRYLOV_METHOD(BiCGSTAB)\
25  BOGUS_PROCESS_KRYLOV_METHOD(CGS )\
26  BOGUS_PROCESS_KRYLOV_METHOD(GMRES )\
27  BOGUS_PROCESS_KRYLOV_METHOD(TFQMR )
28 
29 
30 namespace bogus {
31 
33 namespace krylov {
34 
41 template< template < typename, typename, typename > class Method,
42  typename Matrix, typename Preconditioner, typename Traits >
44  : public LinearSolverBase< Method< Matrix, Preconditioner, Traits > >
45 {
48  typedef typename Traits::Scalar Scalar ;
50 
51  const Matrix *m_A ;
52  const Preconditioner *m_P;
53  const SignalType *m_callback ;
54 
55  Scalar m_tol ;
56  unsigned m_maxIters;
57 
58  KrylovSolverBase( const Matrix &A,
59  unsigned maxIters, Scalar tol,
60  const Preconditioner *P,
61  const SignalType *callback
62  )
63  : m_A( &A ), m_P( P ), m_callback( callback ),
64  m_tol( tol ), m_maxIters( maxIters ),
65  m_parallelizeRhs( false ), m_enableResCaching( false )
66  {}
67 
69  : m_A( BOGUS_NULL_PTR(const Matrix) ),
70  m_P( BOGUS_NULL_PTR(const Preconditioner) ),
71  m_callback( BOGUS_NULL_PTR(const SignalType) ),
72  m_tol( 0 ), m_maxIters( 0 ),
73  m_parallelizeRhs( false ), m_enableResCaching( false )
74  {}
75 
77  template < typename RhsT >
78  typename LinearSolverTraits< Derived >::template Result< RhsT >::Type
79  solve( const RhsT& rhs ) const
80  {
81  typedef typename LinearSolverTraits< Derived >::template Result< RhsT >::Type ReturnType ;
82  static ReturnType s_cachedRes ;
83 
84  if( !m_enableResCaching ) {
85  ReturnType x( m_A->rows(), rhs.cols() ) ;
86  x.setZero() ;
87  Base::solve( rhs, x ) ;
88  return x ;
89  }
90 
91  if( s_cachedRes.rows() != m_A->rows() || s_cachedRes.cols() != rhs.cols() ) {
92  s_cachedRes.resize( m_A->rows(), rhs.cols() ) ;
93  s_cachedRes.setZero() ;
94  }
95 
96  Base::solve( rhs, s_cachedRes ) ;
97  return s_cachedRes ;
98  }
99 
101  template < typename ResT, typename RhsT >
102  Scalar solve( const RhsT& rhs, ResT& x ) const
103  {
104  Scalar res = 0;
105 #ifndef BOGUS_DONT_PARALLELIZE
106 #pragma omp parallel for reduction( +:res ) if ( m_parallelizeRhs )
107 #endif
108  for( std::ptrdiff_t c = 0 ; c < (std::ptrdiff_t) rhs.cols() ; ++c )
109  {
110  res += Base::derived().vectorSolve( rhs.col( c ), x.col( c ) ) ;
111  }
112 
113  return res ;
114  }
115 
117  Derived& parallelizeRhs( bool parallelize = true )
118  {
119  m_parallelizeRhs = parallelize ;
120  return Base::derived() ;
121  }
122 
124 
125  Derived& enableResCaching( bool doCache = true )
126  {
127  m_enableResCaching = doCache ;
128  return Base::derived() ;
129  }
130 
131 protected:
132  bool m_parallelizeRhs ;
133  bool m_enableResCaching ;
134 
135 } ;
136 
138 namespace solvers {
139 
140 // Useful macros for common declarations
141 
142 #define BOGUS_MAKE_KRYLOV_SOLVER_TYPEDEFS( MethodName ) \
143  typedef KrylovSolverBase< solvers::MethodName, Matrix, Preconditioner, Traits > Base ; \
144  typedef typename Traits::Scalar Scalar ; \
145  \
146  using Base::m_A ; \
147  using Base::m_P ; \
148  using Base::m_maxIters ; \
149  using Base::m_tol ; \
150  using Base::m_callback ; \
151 
152 #define BOGUS_MAKE_KRYLOV_SOLVER_HEADER( MethodName ) \
153  BOGUS_MAKE_KRYLOV_SOLVER_TYPEDEFS( MethodName ) \
154  MethodName( const Matrix &A, \
155  unsigned maxIters, \
156  Scalar tol = NumTraits< Scalar >::epsilon(), \
157  const Preconditioner *P = BOGUS_NULL_PTR(const Preconditioner), \
158  const typename Base::SignalType *callback = BOGUS_NULL_PTR(const typename Base::SignalType ) )\
159  : Base( A, maxIters, tol, P, callback ) \
160  {} \
161  \
162  MethodName():Base() {} \
163  \
164  template < typename RhsT, typename ResT > \
165  Scalar vectorSolve( const RhsT &b, ResT x ) const ; \
166 
167 
168 // Conjugate Gradient
169 
171 
177 template < typename Matrix,
178  typename Preconditioner = TrivialPreconditioner< Matrix >,
180 struct CG : public KrylovSolverBase< CG, Matrix, Preconditioner, Traits >
181 {
182 
183 
184  BOGUS_MAKE_KRYLOV_SOLVER_HEADER( CG )
185 
186 } ;
187 
189 
196 template < typename Matrix,
197  typename Preconditioner = TrivialPreconditioner< Matrix >,
199 struct BiCG : public KrylovSolverBase< BiCG, Matrix, Preconditioner, Traits>
200 {
201 
202  BOGUS_MAKE_KRYLOV_SOLVER_HEADER( BiCG )
203 
204 } ;
205 
207 
217 template < typename Matrix,
218  typename Preconditioner = TrivialPreconditioner< Matrix >,
220 struct BiCGSTAB : public KrylovSolverBase< BiCGSTAB, Matrix, Preconditioner, Traits>
221 {
222 
223  BOGUS_MAKE_KRYLOV_SOLVER_HEADER( BiCGSTAB )
224 
225 } ;
226 
228 
235 template < typename Matrix,
236  typename Preconditioner = TrivialPreconditioner< Matrix >,
238 struct CGS : public KrylovSolverBase< CGS, Matrix, Preconditioner, Traits>
239 {
240 
241  BOGUS_MAKE_KRYLOV_SOLVER_HEADER( CGS )
242 } ;
243 
244 
246 
260 template < typename Matrix,
261  typename Preconditioner = TrivialPreconditioner< Matrix >,
263 struct GMRES : public KrylovSolverBase< GMRES, Matrix, Preconditioner, Traits>
264 {
265  BOGUS_MAKE_KRYLOV_SOLVER_TYPEDEFS( GMRES )
266 
267  GMRES() : Base(), m_restart( 0 )
268  {}
269 
270  GMRES( const Matrix &A,
271  unsigned maxIters,
272  Scalar tol = NumTraits< Scalar >::epsilon(),
273  const Preconditioner *P = BOGUS_NULL_PTR( const Preconditioner),
274  const typename Base::SignalType *callback = BOGUS_NULL_PTR(const typename Base::SignalType),
275  unsigned restart = 0 )
276  : Base( A, maxIters, tol, P, callback ),
277  m_restart( restart )
278  {}
279 
280  GMRES &setRestart( unsigned restart )
281  {
282  m_restart = restart ;
283  return *this ;
284  }
285 
286  template < typename RhsT, typename ResT >
287  Scalar vectorSolve( const RhsT &b, ResT x ) const ;
288 
289 protected:
290  unsigned m_restart ;
291 } ;
292 
294 
303 template < typename Matrix,
304  typename Preconditioner = TrivialPreconditioner< Matrix >,
306 struct TFQMR : public KrylovSolverBase< TFQMR, Matrix, Preconditioner, Traits>
307 {
308  BOGUS_MAKE_KRYLOV_SOLVER_HEADER( TFQMR )
309 };
310 
311 
312 } //namespace solvers
313 
314 } //namespace krylov
315 
316 
317 // Sovlers traits ( in bogus namespace )
318 
319 #define BOGUS_PROCESS_KRYLOV_METHOD( MethodName ) \
320  template< typename Matrix, typename Preconditioner, class Traits > \
321  struct LinearSolverTraits< krylov::solvers::MethodName< Matrix, Preconditioner, Traits > > \
322  { \
323  typedef Matrix MatrixType ; \
324  template < typename RhsT > struct Result { \
325  typedef typename Traits::template MutableClone< RhsT >::Type Type ; \
326  } ; \
327  } ; \
328  template< typename Matrix, typename Preconditioner, class Traits, \
329  typename RhsBlockT, bool TransposeLhs, bool TransposeRhs > \
330  struct BlockBlockProductTraits < krylov::solvers::MethodName< Matrix, Preconditioner, Traits >, RhsBlockT, TransposeLhs, TransposeRhs > \
331  { \
332  typedef typename BlockBlockProductTraits < Matrix, RhsBlockT, TransposeLhs, TransposeRhs >::ReturnType \
333  ReturnType ; \
334  } ; \
335 
336 BOGUS_KRYLOV_METHODS
337 #undef BOGUS_PROCESS_KRYLOV_METHOD
338 
339 } //namespace bogus
340 
341 #endif
Definition: LinearSolverBase.hpp:22
Solves ( m_A * x = b ) using the BiConjugate Gradient algorithm.
Definition: KrylovMethods.hpp:199
Solves ( m_A * x = b ) using the Conjugate Gradient Squared algorithm.
Definition: KrylovMethods.hpp:238
Base class for linear solvers on base ( i.e. non-block ) matrices.
Definition: LinearSolverBase.hpp:26
Derived & enableResCaching(bool doCache=true)
Whether to enable caching of solve(rhs) result for warmstarting purposes.
Definition: KrylovMethods.hpp:125
Definition: BlockSolvers.fwd.hpp:33
Solves ( m_A * x = b ) using the transpose-free Quasi Minimal Reisual method.
Definition: KrylovMethods.hpp:306
Solves ( m_A * x = b ) using the BiConjugate Gradient stabilized algorithm.
Definition: KrylovMethods.hpp:220
Definition: NumTraits.hpp:22
Definition: KrylovMethods.hpp:43
Method
Definition: BlockSolvers.fwd.hpp:20
Solves ( m_A * x = b ) using the Conjugate Gradient algorithm.
Definition: KrylovMethods.hpp:180
Derived & parallelizeRhs(bool parallelize=true)
Whether to process multiple rhs in parallel.
Definition: KrylovMethods.hpp:117
Solves ( m_A * x = b ) using the (restarted) Generalized Minimum Residual.
Definition: KrylovMethods.hpp:263
Scalar solve(const RhsT &rhs, ResT &x) const
Returns the solution x of the linear system M * x = rhs.
Definition: KrylovMethods.hpp:102
Trivial ( identity ) preconditioner. Does nothing.
Definition: Preconditioners.hpp:18
LinearSolverTraits< Derived >::template Result< RhsT >::Type solve(const RhsT &rhs) const
Returns the solution x of the linear system M * x = rhs.
Definition: KrylovMethods.hpp:79
LinearSolverTraits< Derived >::template Result< RhsT >::Type solve(const RhsT &rhs) const
Returns the solution x of the linear system M * x = rhs.
Definition: LinearSolverBase.hpp:32