00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "Teuchos_CommandLineProcessor.hpp"
00030 #include "Teuchos_VerboseObject.hpp"
00031
00032 #ifndef SUN_CXX
00033
00034 #include "Thyra_DefaultSpmdVectorSpace.hpp"
00035 #include "Thyra_DefaultSpmdMultiVector.hpp"
00036 #include "Thyra_LinearOpScalarProd.hpp"
00037 #include "Thyra_EuclideanScalarProd.hpp"
00038 #include "Thyra_VectorBase.hpp"
00039 #include "Thyra_MultiVectorBase.hpp"
00040 #include "Thyra_VectorStdOps.hpp"
00041 #include "Thyra_MultiVectorStdOps.hpp"
00042 #include "Thyra_DefaultDiagonalLinearOp.hpp"
00043 #include "Thyra_DefaultSerialVectorSpaceConverter.hpp"
00044 #include "Thyra_DefaultScaledAdjointLinearOp.hpp"
00045 #include "Thyra_TestingTools.hpp"
00046 #include "Thyra_LinearOpTester.hpp"
00047
00050 template <class Scalar>
00051 bool run_scalar_product_tests(
00052 const int n
00053 ,const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &tol
00054 ,const bool dumpAll
00055 ,Teuchos::FancyOStream *out_arg
00056 )
00057 {
00058
00059 using Thyra::relErr;
00060 using Thyra::testBoolExpr;
00061 typedef Teuchos::ScalarTraits<Scalar> ST;
00062 typedef typename ST::magnitudeType ScalarMag;
00063 typedef Teuchos::ScalarTraits<ScalarMag> SMT;
00064 using Teuchos::RCP;
00065 using Teuchos::rcp;
00066 using Teuchos::rcp_implicit_cast;
00067 using Teuchos::OSTab;
00068
00069 RCP<Teuchos::FancyOStream>
00070 out = rcp(new Teuchos::FancyOStream(rcp(out_arg,false)));
00071
00072 if(out.get()) *out << "\n*** Entering run_scalar_product_tests<"<<ST::name()<<">(...) ...\n" << std::boolalpha;
00073
00074 bool success = true, result;
00075
00076 RCP<Thyra::DefaultSpmdVectorSpace<Scalar> >
00077 domain = rcp(new Thyra::DefaultSpmdVectorSpace<Scalar>(n/2)),
00078 range = rcp(new Thyra::DefaultSpmdVectorSpace<Scalar>(n));
00079
00080 RCP<Thyra::DefaultSpmdMultiVector<Scalar> >
00081 op_coeff = rcp(new Thyra::DefaultSpmdMultiVector<Scalar>(range,domain)),
00082 op = rcp(new Thyra::DefaultSpmdMultiVector<Scalar>(range,domain));
00083
00084 RCP<Thyra::DefaultDiagonalLinearOp<Scalar> >
00085 domainScalarProdOp = rcp(
00086 new Thyra::DefaultDiagonalLinearOp<Scalar>(
00087 rcp_implicit_cast<const Thyra::VectorSpaceBase<Scalar> >(domain)
00088 )
00089 ),
00090 rangeScalarProdOp = rcp(
00091 new Thyra::DefaultDiagonalLinearOp<Scalar>(
00092 rcp_implicit_cast<const Thyra::VectorSpaceBase<Scalar> >(range)
00093 )
00094 );
00095
00096 Thyra::seed_randomize<Scalar>(0);
00097 Thyra::randomize( Scalar(Scalar(-1)*ST::one()), Scalar(Scalar(+1)*ST::one()), &*op_coeff );
00098 if(out.get() && dumpAll) *out << "\nop_coeff =\n" << *op_coeff;
00099 RCP<const Thyra::VectorSpaceConverterBase<ScalarMag,Scalar> >
00100 vecSpcConverterFromMag = rcp(new Thyra::DefaultSerialVectorSpaceConverter<ScalarMag,Scalar>());
00101 RCP<const Thyra::VectorSpaceBase<ScalarMag> >
00102 magDomain = vecSpcConverterFromMag->createVectorSpaceFrom(*rcp_implicit_cast<const Thyra::VectorSpaceBase<Scalar> >(domain)),
00103 magRange = vecSpcConverterFromMag->createVectorSpaceFrom(*rcp_implicit_cast<const Thyra::VectorSpaceBase<Scalar> >(range));
00104 RCP<Thyra::VectorBase<ScalarMag> >
00105 _domainScalarProdDiag = createMember(magDomain),
00106 _rangeScalarProdDiag = createMember(*magRange);
00107 Thyra::randomize( ScalarMag(ScalarMag(+1)*SMT::one()), ScalarMag(ScalarMag(+2)*SMT::one()), &*_domainScalarProdDiag );
00108 Thyra::randomize( ScalarMag(ScalarMag(+1)*SMT::one()), ScalarMag(ScalarMag(+2)*SMT::one()), &*_rangeScalarProdDiag );
00109 vecSpcConverterFromMag->convert( *_domainScalarProdDiag, &*domainScalarProdOp->getNonconstDiag() );
00110 vecSpcConverterFromMag->convert( *_rangeScalarProdDiag, &*rangeScalarProdOp->getNonconstDiag() );
00111
00112 RCP<const Thyra::EuclideanScalarProd<Scalar> >
00113 euclideanScalarProd = rcp(new Thyra::EuclideanScalarProd<Scalar>());
00114 RCP<const Thyra::LinearOpScalarProd<Scalar> >
00115 domainScalarProd = rcp(new Thyra::LinearOpScalarProd<Scalar>(domainScalarProdOp)),
00116 rangeScalarProd = rcp(new Thyra::LinearOpScalarProd<Scalar>(rangeScalarProdOp));
00117
00118 const ScalarMag warning_tol = ScalarMag(1e-2)*tol, error_tol = tol;
00119 Thyra::LinearOpTester<Scalar> linearOpTester;
00120 linearOpTester.linear_properties_warning_tol(warning_tol);
00121 linearOpTester.linear_properties_error_tol(error_tol);
00122 linearOpTester.adjoint_warning_tol(warning_tol);
00123 linearOpTester.adjoint_error_tol(error_tol);
00124 linearOpTester.show_all_tests(true);
00125
00126 if(out.get()) *out << "\nTesting LinearOpBase with Euclidean domain and range scalar products ...\n";
00127 {
00128 OSTab tab(out);
00129 Thyra::assign( &*op, *op_coeff );
00130 if(out.get() && dumpAll) *out << "\nop =\n" << *op;
00131 if(out.get() && dumpAll) *out << "\nop' =\n" << *Thyra::adjoint(Teuchos::rcp_implicit_cast<const Thyra::LinearOpBase<Scalar> >(op));
00132 result = testBoolExpr("op->domain()->isEuclidean()",op->domain()->isEuclidean(),true,out.get());
00133 if(!result) success = false;
00134 result = testBoolExpr("op->range()->isEuclidean()",op->range()->isEuclidean(),true,out.get());
00135 if(!result) success = false;
00136 result = linearOpTester.check(*op,out.get());
00137 if(!result) success = false;
00138 }
00139
00140 if(out.get()) *out << "\nTesting LinearOpBase with non-Euclidean domain and Euclidean range scalar products ...\n";
00141 {
00142 OSTab tab(out);
00143 range->setScalarProd(euclideanScalarProd);
00144 domain->setScalarProd(domainScalarProd);
00145 op->initialize(range,domain);
00146 Thyra::assign( &*op, *op_coeff );
00147 if(out.get() && dumpAll) *out << "\nop =\n" << *op;
00148 if(out.get() && dumpAll) *out << "\nop' =\n" << *Thyra::adjoint(Teuchos::rcp_implicit_cast<const Thyra::LinearOpBase<Scalar> >(op));
00149 result = testBoolExpr("op->domain()->isEuclidean()",op->domain()->isEuclidean(),false,out.get());
00150 if(!result) success = false;
00151 result = testBoolExpr("op->range()->isEuclidean()",op->range()->isEuclidean(),true,out.get());
00152 if(!result) success = false;
00153 result = linearOpTester.check(*op,out.get());
00154 if(!result) success = false;
00155 }
00156
00157 if(out.get()) *out << "\nTesting LinearOpBase with Euclidean domain and non-Euclidean range scalar products ...\n";
00158 {
00159 OSTab tab(out);
00160 range->setScalarProd(rangeScalarProd);
00161 domain->setScalarProd(euclideanScalarProd);
00162 op->initialize(range,domain);
00163 Thyra::assign( &*op, *op_coeff );
00164 if(out.get() && dumpAll) *out << "\nop =\n" << *op;
00165 if(out.get() && dumpAll) *out << "\nop' =\n" << *Thyra::adjoint(Teuchos::rcp_implicit_cast<const Thyra::LinearOpBase<Scalar> >(op));
00166 result = testBoolExpr("op->domain()->isEuclidean()",op->domain()->isEuclidean(),true,out.get());
00167 if(!result) success = false;
00168 result = testBoolExpr("op->range()->isEuclidean()",op->range()->isEuclidean(),false,out.get());
00169 if(!result) success = false;
00170 result = linearOpTester.check(*op,out.get());
00171 if(!result) success = false;
00172 }
00173
00174 if(out.get()) *out << "\nTesting LinearOpBase with non-Euclidean domain and non-Euclidean range scalar products ...\n";
00175 {
00176 OSTab tab(out);
00177 range->setScalarProd(rangeScalarProd);
00178 domain->setScalarProd(domainScalarProd);
00179 op->initialize(range,domain);
00180 Thyra::assign( &*op, *op_coeff );
00181 if(out.get() && dumpAll) *out << "\nop =\n" << *op;
00182 if(out.get() && dumpAll) *out << "\nop' =\n" << *Thyra::adjoint(Teuchos::rcp_implicit_cast<const Thyra::LinearOpBase<Scalar> >(op));
00183 result = testBoolExpr("op->domain()->isEuclidean()",op->domain()->isEuclidean(),false,out.get());
00184 if(!result) success = false;
00185 result = testBoolExpr("op->range()->isEuclidean()",op->range()->isEuclidean(),false,out.get());
00186 if(!result) success = false;
00187 result = linearOpTester.check(*op,out.get());
00188 if(!result) success = false;
00189 }
00190
00191 if(out.get()) *out << "\n*** Leaving run_scalar_product_tests<"<<ST::name()<<">(...) ...\n";
00192
00193 return success;
00194
00195 }
00196
00197 #endif // SUN_CXX
00198
00199 int main( int argc, char* argv[] ) {
00200
00201 bool success = true;
00202 bool verbose = true;
00203
00204 using Teuchos::CommandLineProcessor;
00205
00206 Teuchos::RCP<Teuchos::FancyOStream>
00207 out = Teuchos::VerboseObjectBase::getDefaultOStream();
00208
00209 try {
00210
00211
00212
00213
00214
00215 int n = 4;
00216 bool dumpAll = false;
00217
00218 CommandLineProcessor clp;
00219 clp.throwExceptions(false);
00220 clp.addOutputSetupOptions(true);
00221 clp.setOption( "verbose", "quiet", &verbose, "Set if output is printed or not." );
00222 clp.setOption( "n", &n, "Number of elements in each constituent vector." );
00223 clp.setOption( "dump-all", "no-dump-all", &dumpAll, "Determines if vectors are printed or not." );
00224 CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
00225 if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) return parse_return;
00226
00227 #ifndef SUN_CXX
00228
00229
00230
00231
00232
00233 #ifdef HAVE_THYRA_TEUCHOS_BLASFLOAT
00234 if( !run_scalar_product_tests<float>(n,float(1e-5),dumpAll,verbose?&*out:NULL) ) success = false;
00235 #endif // HAVE_THYRA_TEUCHOS_BLASFLOAT
00236 if( !run_scalar_product_tests<double>(n,double(1e-14),dumpAll,verbose?&*out:NULL) ) success = false;
00237 #if defined(HAVE_COMPLEX) && defined(HAVE_TEUCHOS_COMPLEX)
00238 #ifdef HAVE_THYRA_TEUCHOS_BLASFLOAT
00239 if( !run_scalar_product_tests<std::complex<float> >(n,float(1e-5),dumpAll,verbose?&*out:NULL) ) success = false;
00240 #endif // HAVE_THYRA_TEUCHOS_BLASFLOAT
00241 if( !run_scalar_product_tests<std::complex<double> >(n,double(1e-14),dumpAll,verbose?&*out:NULL) ) success = false;
00242 #endif
00243 #ifdef HAVE_TEUCHOS_GNU_MP
00244 if( !run_scalar_product_tests<mpf_class>(n,mpf_class(1e-14),dumpAll,verbose?&*out:NULL) ) success = false;
00245 #endif
00246
00247 #endif // ifndef SUN_CXX
00248
00249 }
00250 catch( const std::exception &excpt ) {
00251 if(verbose)
00252 std::cerr << "*** Caught a standard exception : " << excpt.what() << std::endl;
00253 success = false;
00254 }
00255 catch( ... ) {
00256 if(verbose)
00257 std::cerr << "*** Caught an unknown exception!\n";
00258 success = false;
00259 }
00260
00261 #ifndef SUN_CXX
00262
00263 if(verbose) {
00264 if(success)
00265 *out << "\nAll of the tests seem to have run successfully!\n";
00266 else
00267 *out << "\nOh no! at least one of the test failed!\n";
00268 }
00269
00270 return success ? 0 : 1;
00271
00272 #else // ifndef SUN_CXX
00273
00274 if (verbose) {
00275 std::cout << "\nError, the test was never run since SUN_CXX was defined and this test does not build on the Sun compiler!\n";
00276 }
00277
00278 return 1;
00279
00280 #endif //ifndef SUN_CXX
00281
00282 }