Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef _H_PRECOND_HPP_
00024 #define _H_PRECOND_HPP_
00025
00026 #include <iostream>
00027
00028 #include <boost/numeric/ublas/vector_expression.hpp>
00029
00030 #include "jmath/cholesky.hpp"
00031
00032 namespace ublas = boost::numeric::ublas;
00033
00036 template < class MATRIX = int >
00037 class IdentityPreconditioner {
00038
00039 public:
00040 IdentityPreconditioner(const MATRIX& A) { }
00041
00042 template<class Vector>
00043 void apply(const Vector& b, Vector& x) const
00044 {
00045 x = b;
00046 }
00047 private:
00048 IdentityPreconditioner() { }
00049 };
00050
00053 template<class Matrix>
00054 class DiagonalPreconditioner {
00055
00056 public:
00057 typedef typename Matrix::value_type value_type;
00058 typedef typename Matrix::size_type size_type;
00059
00060 DiagonalPreconditioner(const Matrix & A, const double eps = 1.0e-14)
00061 : diag(A.size1()), EPS(eps)
00062 {
00063 for (size_type i=0; i<A.size1(); ++i) {
00064 if ( fabs( A(i,i) ) > EPS ) {
00065 diag(i) = 1.0 / A(i,i);
00066 } else {
00067 diag(i) = 0;
00068 }
00069 }
00070 }
00071
00072 template<class Vector>
00073 void apply(const Vector& b, Vector& x) const
00074 {
00075 x = element_prod( diag, b );
00076 }
00077
00078 private:
00079 DiagonalPreconditioner() { };
00080 ublas::vector< value_type > diag;
00081 const double EPS;
00082
00083 };
00084
00085 template <class Matrix>
00086 DiagonalPreconditioner<Matrix>
00087 make_DiagonalPreconditioner(const Matrix & A, const double eps = 1.0e-14)
00088 {
00089 return DiagonalPreconditioner<Matrix>(A, eps);
00090 }
00091
00092
00097 template<class Matrix> class CholeskyPreconditioner {
00098
00099 public:
00100 CholeskyPreconditioner(const Matrix & A) : L(A)
00101 {
00102 cholesky_decompose(L);
00103 }
00104
00105 template<class Vector>
00106 void apply(const Vector& b, Vector& x) const
00107 {
00108 x = b;
00109 cholesky_solve(L, x, ublas::lower());
00110 }
00111
00112 private:
00113 CholeskyPreconditioner() { }
00114 Matrix L;
00115 };
00116
00117
00118 template <class Matrix>
00119 CholeskyPreconditioner<Matrix>
00120 make_CholeskyPreconditioner(const Matrix & A)
00121 {
00122 return CholeskyPreconditioner<Matrix>(A);
00123 }
00124
00125
00126
00133 template<class Matrix> class IncompleteCholeskyPreconditioner {
00134
00135 public:
00136 IncompleteCholeskyPreconditioner(const Matrix & A) : L(A)
00137 {
00138 incomplete_cholesky_decompose(L);
00139 }
00140
00141 template<class Vector>
00142 void apply(const Vector& b, Vector& x) const
00143 {
00144 x = b;
00145 cholesky_solve(L, x, ublas::lower());
00146 }
00147
00148 private:
00149 IncompleteCholeskyPreconditioner() { }
00150 Matrix L;
00151 };
00152
00153
00154 template <class Matrix>
00155 IncompleteCholeskyPreconditioner<Matrix>
00156 make_IncompleteCholeskyPreconditioner(const Matrix & A)
00157 {
00158 return IncompleteCholeskyPreconditioner<Matrix>(A);
00159 }
00160
00161
00162 #endif