Thyra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sillyPowerMethod.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_POWER_METHOD_HPP
11 #define THYRA_SILLY_POWER_METHOD_HPP
12 
13 #include "Thyra_LinearOpBase.hpp"
14 #include "Thyra_VectorStdOps.hpp"
15 
16 
28 template<class Scalar>
29 bool sillyPowerMethod(
31  const int maxNumIters,
32  const typename Teuchos::ScalarTraits<Scalar>::magnitudeType tolerance,
33  const Teuchos::Ptr<Scalar> &lambda,
34  std::ostream &out
35  )
36 {
37 
38  // Create some typedefs and some other stuff to make the code cleaner
39  typedef Teuchos::ScalarTraits<Scalar> ST; typedef typename ST::magnitudeType ScalarMag;
40  using Thyra::apply;
41  const Scalar one = ST::one(); using Thyra::NOTRANS;
42  //typedef Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> > VectorSpacePtr; // unused
43  typedef Teuchos::RCP<Thyra::VectorBase<Scalar> > VectorPtr;
44 
45  // Initialize
46  out << "\nStarting power method (target tolerance = "<<tolerance<<") ...\n\n";
47  VectorPtr q = createMember(A.domain()), z = createMember(A.range()), r = createMember(A.range());
48  Thyra::seed_randomize<Scalar>(0);
49  Thyra::randomize( Scalar(-one), Scalar(+one), z.ptr() );
50 
51  // Perform iterations
52  for( int iter = 0; iter < maxNumIters; ++iter ) {
53  const ScalarMag z_nrm = norm(*z); // Compute natural norm of z
54  V_StV( q.ptr(), Scalar(one/z_nrm), *z ); // q = (1/||z||)*z
55  apply<Scalar>( A, NOTRANS , *q, z.ptr() ); // z = A*q
56  *lambda = scalarProd(*q,*z); // lambda = <q,z>
57  if( iter%(maxNumIters/10) == 0 || iter+1 == maxNumIters ) {
58  V_StVpV(r.ptr(),Scalar(-*lambda),*q,*z); // r = -lambda*q + z
59  const ScalarMag r_nrm = norm(*r); // Compute natural norm of r
60  out << "Iter = " << iter << ", lambda = " << (*lambda)
61  << ", ||A*q-lambda*q|| = " << r_nrm << std::endl;
62  if( r_nrm < tolerance )
63  return true; // Success!
64  }
65  }
66 
67  out << "\nMaximum number of iterations exceeded with ||-lambda*q + z||"
68  " > tolerence = " << tolerance << "\n";
69  return false; // Failure
70 
71 } // end sillyPowerMethod
72 
73 
74 #endif // THYRA_SILLY_POWER_METHOD_HPP
virtual RCP< const VectorSpaceBase< Scalar > > range() const =0
Return a smart pointer for the range space for this operator.
Use the non-transposed operator.
RCP< VectorBase< Scalar > > createMember(const RCP< const VectorSpaceBase< Scalar > > &vs, const std::string &label="")
Create a vector member from the vector space.
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.
Teuchos::ScalarTraits< Scalar >::magnitudeType norm(const VectorBase< Scalar > &v)
Natural norm: result = sqrt(&lt;v,v&gt;).
Scalar scalarProd(const VectorBase< Scalar > &x, const VectorBase< Scalar > &y)
Scalar product result = &lt;x,y&gt;.
void V_StV(const Ptr< VectorBase< Scalar > > &y, const Scalar &alpha, const VectorBase< Scalar > &x)
Assign scaled vector: y(i) = alpha * x(i), i = 0...y-&gt;space()-&gt;dim()-1.
void V_StVpV(const Ptr< MultiVectorBase< Scalar > > &Z, const Scalar &alpha, const MultiVectorBase< Scalar > &X, const MultiVectorBase< Scalar > &Y)
Z(i,j) = alpha*X(i,j) + Y(i), i = 0...z-&gt;space()-&gt;dim()-1, , j = 0...Z-&gt;domain()-&gt;dim()-1.