00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef ITL_CG_INCLUDE
00013 #define ITL_CG_INCLUDE
00014
00015 #include <boost/numeric/mtl/concept/collection.hpp>
00016 #include <boost/numeric/itl/itl_fwd.hpp>
00017
00018 namespace itl {
00019
00021 template < typename LinearOperator, typename HilbertSpaceX, typename HilbertSpaceB,
00022 typename Preconditioner, typename Iteration >
00023 int cg(const LinearOperator& A, HilbertSpaceX& x, const HilbertSpaceB& b,
00024 const Preconditioner& M, Iteration& iter)
00025 {
00026 typedef HilbertSpaceX Vector;
00027 typedef typename mtl::Collection<HilbertSpaceX>::value_type Scalar;
00028
00029 Scalar rho(0), rho_1(0), alpha(0), beta(0);
00030 Vector p(size(x)), q(size(x)), r(size(x)), z(size(x));
00031
00032 r = b - A*x;
00033
00034 while (! iter.finished(r)) {
00035 z = solve(M, r);
00036 rho = dot(r, z);
00037
00038 if (iter.first())
00039 p = z;
00040 else {
00041 beta = rho / rho_1;
00042 p = z + beta * p;
00043 }
00044
00045 q = A * p;
00046 alpha = rho / dot(p, q);
00047
00048 x += alpha * p;
00049 r -= alpha * q;
00050 rho_1 = rho;
00051
00052 ++iter;
00053 }
00054 return iter;
00055 }
00056
00057
00058
00060 template < typename LinearOperator, typename HilbertSpaceX, typename HilbertSpaceB,
00061 typename Preconditioner, typename RightPreconditioner, typename Iteration >
00062 int cg(const LinearOperator& A, HilbertSpaceX& x, const HilbertSpaceB& b,
00063 const Preconditioner& M, const RightPreconditioner&, Iteration& iter)
00064 {
00065 return cg(A, x, b, M, iter);
00066 }
00067
00068 }
00069
00070 #endif // ITL_CG_INCLUDE