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
00025 #ifndef _H_PCG_HPP_
00026 #define _H_PCG_HPP_
00027
00028 #include <cassert>
00029 #include <iostream>
00030
00031 #include <boost/numeric/ublas/vector.hpp>
00032 #include <boost/numeric/ublas/vector_proxy.hpp>
00033
00034 #include <boost/numeric/ublas/matrix.hpp>
00035 #include <boost/numeric/ublas/matrix_proxy.hpp>
00036
00037 #include <boost/numeric/ublas/operation.hpp>
00038
00039 #include "jmath/precond.hpp"
00040
00041 namespace ublas = boost::numeric::ublas;
00042
00043
00044 template <class MAT, class VEC, class Precond>
00045 size_t pcg_solve(const MAT& A, VEC& x, const VEC& b,
00046 const Precond& B = IdentityPreconditioner<MAT>(),
00047 const size_t maxiter = 10,
00048 const double rTOL = 1e-6,
00049 const double aTOL = 1e-14)
00050 {
00051 typedef typename VEC::value_type value_type;
00052
00053 const size_t size = x.size();
00054 size_t iteration = 0;
00055
00056 VEC resid(size);
00057 VEC g(size);
00058 VEC d1(size);
00059 value_type alpha, beta, norm, h1, h2, norm_0;
00060
00061 resid = b - prod(A, x);
00062
00063 B.apply(resid, g);
00064
00065 norm = inner_prod(resid, resid);
00066 norm_0 = norm;
00067 ++iteration;
00068
00069 B.apply(resid, d1);
00070 h2 = inner_prod(resid, d1);
00071
00072 while ((iteration < maxiter) && (norm > (aTOL*aTOL)) && ((norm/norm_0) > (rTOL * rTOL)) ) {
00073 h1 = h2;
00074
00075 axpy_prod(A, g, d1, true);
00076
00077 h2 = inner_prod(g, d1);
00078
00079 alpha = h1/h2;
00080
00081 x += alpha*g;
00082 resid -= alpha*d1;
00083
00084 B.apply(resid, d1);
00085 h2 = inner_prod(resid, d1);
00086
00087 beta = h2/h1;
00088 g = beta*g + d1;
00089
00090 norm = inner_prod(resid, resid);
00091
00092 ++iteration;
00093 }
00094 return iteration;
00095 }
00096
00097
00098 #endif