00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef THYRA_SILLIEST_CG_SOLVE_HPP
00030 #define THYRA_SILLIEST_CG_SOLVE_HPP
00031
00032 #include "Thyra_LinearOperator.hpp"
00033 #include "Thyra_VectorSpace.hpp"
00034 #include "Thyra_Vector.hpp"
00035 #include "Thyra_AssertOp.hpp"
00036
00037
00050 template<class Scalar>
00051 bool silliestCgSolve(
00052 Thyra::ConstLinearOperator<Scalar> const& A,
00053 Thyra::ConstVector<Scalar> const& b,
00054 const int maxNumIters,
00055 const typename Teuchos::ScalarTraits<Scalar>::magnitudeType tolerance,
00056 Thyra::Vector<Scalar> &x,
00057 std::ostream &out
00058 )
00059 {
00060
00061
00062 typedef Teuchos::ScalarTraits<Scalar> ST;
00063 typedef typename ST::magnitudeType ScalarMag;
00064 const Scalar one = ST::one(), zero = ST::zero();
00065 using Thyra::VectorSpace; using Thyra::Vector;
00066
00067
00068 const VectorSpace<Scalar> space = A.domain();
00069 Vector<Scalar> r = b - A*x;
00070 ScalarMag r0_nrm = norm(r);
00071 if(r0_nrm==zero) return true;
00072 Vector<Scalar> p(space), q(space);
00073 Scalar rho_old = -one;
00074
00075
00076 for( int iter = 0; iter <= maxNumIters; ++iter ) {
00077
00078
00079 const ScalarMag r_nrm = norm(r);
00080 const bool isConverged = ( (r_nrm/r0_nrm) <= tolerance );
00081 if( ( iter%(maxNumIters/10+1) == 0 || iter == maxNumIters || isConverged ) )
00082 out<<"Iter = "<<iter<<", ||b-A*x||/||b-A*x0|| = "<<(r_nrm/r0_nrm)<<std::endl;
00083 if( r_nrm/r0_nrm < tolerance ) return true;
00084
00085
00086 const Scalar rho = inner(r, r);
00087 if(iter==0) copyInto(r,p);
00088 else p = Scalar(rho/rho_old)*p + r;
00089 q = A*p;
00090 const Scalar alpha = rho/inner(p,q);
00091 x += Scalar(+alpha)*p;
00092 r += Scalar(-alpha)*q;
00093 rho_old = rho;
00094
00095 }
00096
00097 return false;
00098
00099 }
00100
00101
00102 #endif // THYRA_SILLIEST_CG_SOLVE_HPP