Thyra Version of the Day
Loading...
Searching...
No Matches
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
28template<class Scalar>
29bool 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
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());
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
Base class for all linear operators.
void apply(const LinearOpBase< Scalar > &M, const EOpTransp M_trans, const MultiVectorBase< Scalar > &X, const Ptr< MultiVectorBase< Scalar > > &Y, const Scalar alpha=static_cast< Scalar >(1.0), const Scalar beta=static_cast< Scalar >(0.0))
Non-member function call for M.apply(...).
virtual RCP< const VectorSpaceBase< Scalar > > range() const =0
Return a smart pointer for the range space for this operator.
virtual RCP< const VectorSpaceBase< Scalar > > domain() const =0
Return a smart pointer for the domain space for this operator.
void randomize(Scalar l, Scalar u, const Ptr< MultiVectorBase< Scalar > > &V)
Generate a random multi-vector with elements uniformly distributed elements.
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->space()->dim()-1, , j = 0...Z->domain()->dim()-1.
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->space()->dim()-1.
void seed_randomize(unsigned int s)
Seed the random number generator used in randomize().
Scalar scalarProd(const VectorBase< Scalar > &x, const VectorBase< Scalar > &y)
Scalar product result = <x,y>.
Teuchos::ScalarTraits< Scalar >::magnitudeType norm(const VectorBase< Scalar > &v)
Natural norm: result = sqrt(<v,v>).
RCP< VectorBase< Scalar > > createMember(const RCP< const VectorSpaceBase< Scalar > > &vs, const std::string &label="")
Create a vector member from the vector space.
NOTRANS
Type for the dimension of a vector space. `**/ typedef Teuchos::Ordinal Ordinal;.