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());
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
Base class for all linear operators.
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.
@ NOTRANS
Use the non-transposed operator.