#include "sillyPowerMethod.hpp"
#include "SerialTridiagLinearOp.hpp"
#include "Thyra_TestingTools.hpp"
#include "Teuchos_CommandLineProcessor.hpp"
template<class Scalar>
bool runPowerMethodExample(
const int dim
,const int maxNumIters
,const bool verbose
,const bool dumpAll
)
{
typedef Teuchos::ScalarTraits<Scalar> ST;
typedef typename ST::magnitudeType ScalarMag;
bool success = true;
bool result;
if(verbose)
std::cout << "\n***\n*** Running power method example using scalar type = \'" << ST::name() << "\' ...\n***\n" << std::scientific;
if(verbose) std::cout << "\n(1) Constructing tridiagonal matrix A of dimension = " << dim << " ...\n";
std::vector<Scalar> lower(dim-1), diag(dim), upper(dim-1);
const Scalar one = ST::one(), two = Scalar(2)*one;
int k = 0;
diag[k] = two; upper[k] = -one;
for( k = 1; k < dim - 1; ++k ) {
lower[k-1] = -one; diag[k] = two; upper[k] = -one;
}
lower[k-1] = -one; diag[k] = two;
Teuchos::RefCountPtr<SerialTridiagLinearOp<Scalar> >
A = Teuchos::rcp( new SerialTridiagLinearOp<Scalar>(dim,&lower[0],&diag[0],&upper[0]) );
if( verbose && dumpAll ) std::cout << "\nA =\n" << *A;
if(verbose) std::cout << "\n(2) Running the power method on matrix A ...\n";
Scalar lambda = ST::zero();
ScalarMag tolerance = ScalarMag(1e-3)*Teuchos::ScalarTraits<ScalarMag>::one();
result = sillyPowerMethod(*A,maxNumIters,tolerance,&lambda,(verbose?&std::cout:NULL));
if(!result) success = false;
if(verbose) std::cout << "\n Estimate of dominate eigenvalue lambda = " << lambda << std::endl;
if(verbose) std::cout << "\n(3) Increasing first diagonal entry by factor of 10 ...\n";
diag[0] *= 10;
A->initialize(dim,&lower[0],&diag[0],&upper[0]);
if( verbose && dumpAll ) std::cout << "A =\n" << *A;
if(verbose) std::cout << "\n(4) Running the power method again on matrix A ...\n";
result = sillyPowerMethod(*A,maxNumIters,tolerance,&lambda,(verbose?&std::cout:NULL));
if(!result) success = false;
if(verbose) std::cout << "\n Estimate of dominate eigenvalue lambda = " << lambda << std::endl;
return success;
}
int main(int argc, char *argv[])
{
using Teuchos::CommandLineProcessor;
bool success = true;
bool verbose = true;
bool result;
try {
int dim = 4;
bool dumpAll = false;
CommandLineProcessor clp(false);
clp.setOption( "verbose", "quiet", &verbose, "Determines if any output is printed or not." );
clp.setOption( "dim", &dim, "Dimension of the linear system." );
clp.setOption( "dump-all", "no-dump", &dumpAll, "Determines if quantities are dumped or not." );
CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) return parse_return;
TEST_FOR_EXCEPTION( dim < 2, std::logic_error, "Error, dim=" << dim << " < 2 is not allowed!" );
int maxNumIters = 10*dim;
result = runPowerMethodExample<float>(dim,maxNumIters,verbose,dumpAll);
if(!result) success = false;
result = runPowerMethodExample<double>(dim,maxNumIters,verbose,dumpAll);
if(!result) success = false;
#if defined(HAVE_COMPLEX) && defined(HAVE_TEUCHOS_COMPLEX)
result = runPowerMethodExample<std::complex<float> >(dim,maxNumIters,verbose,dumpAll);
if(!result) success = false;
result = runPowerMethodExample<std::complex<double> >(dim,maxNumIters,verbose,dumpAll);
if(!result) success = false;
#endif
#ifdef HAVE_TEUCHOS_GNU_MP
result = runPowerMethodExample<mpf_class >(dim,maxNumIters,verbose,dumpAll);
if(!result) success = false;
#if defined(HAVE_COMPLEX) && defined(HAVE_TEUCHOS_COMPLEX)
#endif
#endif
}
catch( const std::exception &excpt ) {
std::cerr << "*** Caught standard exception : " << excpt.what() << std::endl;
success = false;
}
catch( ... ) {
std::cerr << "*** Caught an unknown exception\n";
success = false;
}
if (verbose) {
if(success) std::cout << "\nCongratulations! All of the tests checked out!\n";
else std::cout << "\nOh no! At least one of the tests failed!\n";
}
return success ? 0 : 1;
}