Thyra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sillyCgSolve.hpp
1 // @HEADER
2 // *****************************************************************************
3 // Thyra: Interfaces and Support for Abstract Numerical Algorithms
4 //
5 // Copyright 2004 NTESS and the Thyra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef THYRA_SILLY_CG_SOLVE_HPP
11 #define THYRA_SILLY_CG_SOLVE_HPP
12 
13 #include "Thyra_LinearOpBase.hpp"
14 #include "Thyra_VectorStdOps.hpp"
15 #include "Thyra_AssertOp.hpp"
16 
17 
29 template<class Scalar>
30 bool sillyCgSolve(
33  const int maxNumIters,
34  const typename Teuchos::ScalarTraits<Scalar>::magnitudeType tolerance,
36  std::ostream &out
37  )
38 {
39 
40  // Create some typedefs and some other stuff to make the code cleaner
41  typedef Teuchos::ScalarTraits<Scalar> ST; typedef typename ST::magnitudeType ScalarMag;
42  const Scalar one = ST::one(), zero = ST::zero(); using Teuchos::as;
44  using Thyra::NOTRANS; using Thyra::V_V; using Thyra::apply;
45 
46 
47  // Validate input
48  THYRA_ASSERT_LINEAR_OP_VEC_APPLY_SPACES("sillyCgSolve()", A, Thyra::NOTRANS, *x, &b);
50 
51  std::ios::fmtflags fmt(out.flags());
52 
53  out << "\nStarting CG solver ...\n" << std::scientific << "\ndescribe A:\n"<<describe(A, vl)
54  << "\ndescribe b:\n"<<describe(b, vl)<<"\ndescribe x:\n"<<describe(*x, vl)<<"\n";
55 
56  // Initialization
57  const RCP<const VectorSpaceBase<Scalar> > space = A.domain();
58  const RCP<VectorBase<Scalar> > r = createMember(space);
59  // r = -A*x + b
60  V_V(r.ptr(), b); apply<Scalar>(A, NOTRANS, *x, r.ptr(), -one, one);
61  const ScalarMag r0_nrm = norm(*r);
62  if (r0_nrm==zero) return true;
63  const RCP<VectorBase<Scalar> > p = createMember(space), q = createMember(space);
64  Scalar rho_old = -one;
65 
66  // Perform the iterations
67  for( int iter = 0; iter <= maxNumIters; ++iter ) {
68 
69  // Check convergence and output iteration
70  const ScalarMag r_nrm = norm(*r);
71  const bool isConverged = r_nrm/r0_nrm <= tolerance;
72  if( iter%(maxNumIters/10+1) == 0 || iter == maxNumIters || isConverged ) {
73  out << "Iter = " << iter << ", ||b-A*x||/||b-A*x0|| = " << (r_nrm/r0_nrm) << std::endl;
74  if( r_nrm/r0_nrm < tolerance ) {
75  out.flags(fmt);
76  return true; // Success!
77  }
78  }
79 
80  // Compute iteration
81  const Scalar rho = inner(*r, *r); // <r,r> -> rho
82  if (iter==0) V_V(p.ptr(), *r); // r -> p (iter == 0)
83  else Vp_V( p.ptr(), *r, rho/rho_old ); // r+(rho/rho_old)*p -> p (iter > 0)
84  apply<Scalar>(A, NOTRANS, *p, q.ptr()); // A*p -> q
85  const Scalar alpha = rho/inner(*p, *q); // rho/<p,q> -> alpha
86  Vp_StV( x, +alpha, *p ); // +alpha*p + x -> x
87  Vp_StV( r.ptr(), -alpha, *q ); // -alpha*q + r -> r
88  rho_old = rho; // rho -> rho_old (for next iter)
89 
90  }
91 
92  out.flags(fmt);
93  return false; // Failure
94 } // end sillyCgSolve
95 
96 #endif // THYRA_SILLY_CG_SOLVE_HPP
void Vp_V(const Ptr< MultiVectorBase< Scalar > > &Z, const MultiVectorBase< Scalar > &X)
Z(i,j) += X(i,j), i = 0...Z-&gt;range()-&gt;dim()-1, j = 0...Z-&gt;domain()-&gt;dim()-1.
Use the non-transposed operator.
RCP< const LinearOpBase< Scalar > > zero(const RCP< const VectorSpaceBase< Scalar > > &range, const RCP< const VectorSpaceBase< Scalar > > &domain)
Create a zero linear operator with given range and domain spaces.
Abstract interface for objects that represent a space for vectors.
void V_V(const Ptr< VectorBase< Scalar > > &y, const VectorBase< Scalar > &x)
y(i) = x(i), i = 0...y-&gt;space()-&gt;dim()-1.
RCP< VectorBase< Scalar > > createMember(const RCP< const VectorSpaceBase< Scalar > > &vs, const std::string &label="")
Create a vector member from the vector space.
Abstract interface for finite-dimensional dense vectors.
Base class for all linear operators.
virtual RCP< const VectorSpaceBase< Scalar > > domain() const =0
Return a smart pointer for the domain space for this operator.
TypeTo as(const TypeFrom &t)
#define THYRA_ASSERT_LINEAR_OP_VEC_APPLY_SPACES(FUNC_NAME, M, M_T, X, Y)
This is a very useful macro that should be used to validate that the spaces for the vector version of...
void Vp_StV(const Ptr< VectorBase< Scalar > > &y, const Scalar &alpha, const VectorBase< Scalar > &x)
AXPY: y(i) = alpha * x(i) + y(i), i = 0...y-&gt;space()-&gt;dim()-1.
Teuchos::ScalarTraits< Scalar >::magnitudeType norm(const VectorBase< Scalar > &v)
Natural norm: result = sqrt(&lt;v,v&gt;).
Scalar inner(const VectorBase< Scalar > &x, const VectorBase< Scalar > &y)
Inner/Scalar product result = &lt;x,y&gt;.