ScalarTraits_test.cpp

Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //                    Teuchos: Common Tools Package
00005 //                 Copyright (2004) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 
00030 #include "Teuchos_OrdinalTraits.hpp"
00031 #include "Teuchos_ScalarTraits.hpp"
00032 #include "Teuchos_GlobalMPISession.hpp"
00033 #include "Teuchos_CommandLineProcessor.hpp"
00034 #include "Teuchos_VerboseObject.hpp"
00035 #include "Teuchos_StandardCatchMacros.hpp"
00036 #include "Teuchos_Version.hpp"
00037 
00038 
00039 namespace {
00040 
00041 
00042 //
00043 // Output of the ordinal that will avoid printing non-asci chars.
00044 //
00045 // The issue is that if you just print a raw char then if it prints non-asci
00046 // character, it can not be printed in some cases and causes trouble with
00047 // CTest/CDash.
00048 //
00049 
00050 // For general types, just print the type
00051 template <class T>
00052 T outputOrdinal(const T &t)
00053 {
00054   return t;
00055 }
00056 
00057 // For char, print the int value (avoid non-ansi chars)
00058 int outputOrdinal(const char& t)
00059 {
00060   return t;
00061 }
00062 
00063 
00064 //
00065 // Type ouptutting
00066 //
00067 
00068 template <class T>
00069 void TYPE_CHAIN_A(Teuchos::FancyOStream &out) {
00070   T b; typename Teuchos::ScalarTraits<T>::doublePrecision d;
00071   out << Teuchos::typeName(b);
00072   if (typeid(b) != typeid(d)) {
00073     out << " -> ";
00074     TYPE_CHAIN_A<typename Teuchos::ScalarTraits<T>::doublePrecision>(out);
00075   }
00076 }
00077 
00078 template <class T>
00079 void TYPE_CHAIN_D(Teuchos::FancyOStream &out) {
00080   T b; typename Teuchos::ScalarTraits<T>::halfPrecision d;
00081   out << Teuchos::typeName(b);
00082   if (typeid(b) != typeid(d)) {
00083     out << " -> ";
00084     TYPE_CHAIN_D<typename Teuchos::ScalarTraits<T>::halfPrecision>(out);
00085   }
00086 }
00087 
00088 
00089 inline std::string passfail(bool result)
00090 {
00091   return ( result ? "passed" : "failed" );
00092 }
00093 
00094 
00095 template<class Scalar>
00096 bool testScalarTraits(
00097   Teuchos::FancyOStream &out
00098   )
00099 {
00100   
00101   typedef Teuchos::ScalarTraits<Scalar> ST;
00102   
00103   bool success = true;
00104   bool result;
00105 
00106   out << "\nTesting: " << Teuchos::TypeNameTraits<ST>::name() << " ...\n";
00107 
00108   Teuchos::OSTab tab(out);
00109 
00110   const Scalar nan = ST::nan();
00111 
00112   out << "Type chain (ascending) : "; TYPE_CHAIN_A<Scalar>(out); out << "\n";
00113   out << "Type chain (descending): "; TYPE_CHAIN_D<Scalar>(out); out << "\n";
00114 
00115   out << "\nTesting that squareroot(NaN) == NaN! ...\n";
00116   {
00117     const Scalar sqrtNan = ST::squareroot(nan);
00118     result = (ST::isnaninf(sqrtNan));
00119     if (!result) success = false;
00120     out
00121       << "squareroot("<<nan<<") = " << sqrtNan << " == " << nan << " : "
00122       << passfail(result) << "\n";
00123   }
00124 
00125   out << "\nTesting that squareroot(-NaN) == NaN! ...\n";
00126   {
00127     const Scalar negNan = -nan;
00128     const Scalar sqrtNegNan = ST::squareroot(negNan);
00129     result = (ST::isnaninf(sqrtNegNan));
00130     if (!result) success = false;
00131     out
00132       << "squareroot("<<negNan<<") = " << sqrtNegNan << " == " << nan << " : "
00133       << passfail(result) << "\n";
00134   }
00135     
00136   if (ST::isComplex == false)
00137   {
00138     out << "\nTesting that squareroot(-1) == NaN! ...\n";
00139     {
00140       const Scalar negOne = -ST::one();
00141       const Scalar sqrtNegOne = ST::squareroot(negOne);
00142       result = (ST::isnaninf(sqrtNegOne));
00143       if (!result) success = false;
00144       out
00145         << "squareroot("<<negOne<<") = " << sqrtNegOne << " == " << nan << " : "
00146         << passfail(result) << "\n";
00147     }
00148   }
00149 
00150 #ifdef HAVE_NUMERIC_LIMITS
00151     
00152   out << "\nTesting that squareroot(quiet_NaN) == NaN! ...\n";
00153   {
00154     const Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
00155     const Scalar sqrtNan = ST::squareroot(nan);
00156     result = (ST::isnaninf(sqrtNan));
00157     if (!result) success = false;
00158     out
00159       << "squareroot("<<nan<<") = " << sqrtNan << " == " << nan << " : "
00160       << passfail(result) << "\n";
00161   }
00162     
00163   out << "\nTesting that squareroot(signaling_NaN) == NaN! ...\n";
00164   {
00165     const Scalar nan = std::numeric_limits<Scalar>::signaling_NaN();
00166     const Scalar sqrtNan = ST::squareroot(nan);
00167     result = (ST::isnaninf(sqrtNan));
00168     if (!result) success = false;
00169     out
00170       << "squareroot("<<nan<<") = " << sqrtNan << " == " << nan << " : "
00171       << passfail(result) << "\n";
00172   }
00173     
00174   out << "\nTesting that squareroot(inf) == NaN! ...\n";
00175   {
00176     const Scalar inf = std::numeric_limits<Scalar>::infinity();
00177     const Scalar sqrtInf = ST::squareroot(inf);
00178     result = (ST::isnaninf(sqrtInf));
00179     if (!result) success = false;
00180     out
00181       << "squareroot("<<inf<<") = " << sqrtInf << " == " << nan << " : "
00182       << passfail(result) << "\n";
00183   }
00184 
00185 #endif // HAVE_NUMERIC_LIMITS
00186     
00187   return success;
00188 
00189 }
00190 
00191 
00192 template<class Ordinal>
00193 bool testOrdinalTraits(
00194   Teuchos::FancyOStream &out
00195   )
00196 {
00197   
00198   typedef Teuchos::OrdinalTraits<Ordinal> OT;
00199   
00200   bool success = true;
00201   bool result;
00202 
00203   out << "\nTesting: " << Teuchos::TypeNameTraits<OT>::name() << " ...\n";
00204 
00205   Teuchos::OSTab tab(out);
00206 
00207   const Ordinal zero = OT::zero();
00208   const Ordinal one  = OT::one();
00209   const Ordinal max  = OT::max();
00210   const Ordinal invalid  = OT::invalid();
00211   out << "\nmax() == " << outputOrdinal(max) << "\n";
00212   out << "\ninvalid() == " << outputOrdinal(invalid) << "\n";
00213 
00214   out << "\nTesting that zero() * one() == zero() ...\n";
00215   {
00216     const Ordinal zto = zero*one;
00217     result = (zto == zero);
00218     if (!result) success = false;
00219     out
00220       << "zero*one = " << outputOrdinal(zto) << " == " << outputOrdinal(zero) << " : "
00221       << passfail(result) << "\n";
00222   }
00223 
00224   out << "\nTesting that one() * one() == one() ...\n";
00225   {
00226     const Ordinal oto = one*one;
00227     result = (oto == one);
00228     if (!result) success = false;
00229     out
00230       << "one*one = " << outputOrdinal(oto) << " == " << outputOrdinal(one) << " : "
00231       << passfail(result) << "\n";
00232   }
00233 
00234   out << "\nTesting that one() + zero() == zero() + one() == one() ...\n";
00235   {
00236     const Ordinal opz = one+zero;
00237     const Ordinal zpo = zero+one;
00238     result = (opz == one) && (zpo == one);
00239     if (!result) success = false;
00240     out
00241       << "one+zero = " << outputOrdinal(opz) << " == zero+one = "
00242       << outputOrdinal(zpo) << " == " << outputOrdinal(one) << " : "
00243       << passfail(result) << "\n";
00244   }
00245 
00246   out << "\nTesting that one() - one() == zero() ...\n";
00247   {
00248     const Ordinal omo = one-one;
00249     result = (omo == zero);
00250     if (!result) success = false;
00251     out
00252       << "one-one = " << outputOrdinal(omo) << " == " << outputOrdinal(zero) << " : "
00253       << passfail(result) << "\n";
00254   }
00255 
00256   out << "\nTesting that zero() < one() <= max() ...\n";
00257   {
00258     result = (zero < one) && (one <= max) && (zero < max);
00259     if (!result) success = false;
00260     out
00261       << "(zero < one) = " << (zero < one) << " == " 
00262       << "(one <= max) = " << (one <= max) << " == " 
00263       << "(zero < max) = " << (zero < max) << " == " 
00264       << true << " : "
00265       << passfail(result) << "\n";
00266   }
00267 
00268   out << "\nTesting that invalid() not in [zero(),max()]...\n";
00269   {
00270     result = !( (invalid > zero || invalid==zero) && (invalid <= max) );
00271     if (!result) success = false;
00272     out
00273       << "invalid in [zero,max] == false : " << passfail(result) << "\n";
00274   }
00275 
00276   return success;
00277 
00278 }
00279 
00280 
00281 } // namespace
00282 
00283 
00284 int main( int argc, char* argv[] ) {
00285 
00286   using Teuchos::CommandLineProcessor;
00287 
00288   bool success = true;
00289   bool result;
00290   
00291   Teuchos::GlobalMPISession mpiSession(&argc,&argv);
00292   //const int procRank = Teuchos::GlobalMPISession::getRank();
00293   
00294   Teuchos::RCP<Teuchos::FancyOStream>
00295     out = Teuchos::VerboseObjectBase::getDefaultOStream();
00296   
00297   try {
00298 
00299     // Read options from the commandline
00300     CommandLineProcessor  clp(false); // Don't throw exceptions
00301     CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
00302     if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) {
00303       *out << "\nEnd Result: TEST FAILED" << std::endl;
00304       return parse_return;
00305     }
00306 
00307     result = testScalarTraits<float>(*out);
00308     if(!result) success = false;
00309 
00310     result = testScalarTraits<double>(*out);
00311     if(!result) success = false;
00312 
00313     result = testOrdinalTraits<char>(*out);
00314     if(!result) success = false;
00315 
00316     result = testOrdinalTraits<short int>(*out);
00317     if(!result) success = false;
00318 
00319     result = testOrdinalTraits<int>(*out);
00320     if(!result) success = false;
00321 
00322     result = testOrdinalTraits<long int>(*out);
00323     if(!result) success = false;
00324 
00325     result = testOrdinalTraits<size_t>(*out);
00326     if(!result) success = false;
00327 
00328 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
00329     result = testOrdinalTraits<long long int>(*out);
00330     if(!result) success = false;
00331 #endif
00332 
00333 
00334 // #ifdef HAVE_TEUCHOS_COMPLEX
00335 //     result = testScalarTraits<std::complex<double> >(*out);
00336 //     if(!result) success = false;
00337 // #endif
00338     
00339 #ifdef HAVE_TEUCHOS_QD
00340     result = testScalarTraits<dd_real>(*out);
00341     if(!result) success = false;
00342     result = testScalarTraits<qd_real>(*out);
00343     if(!result) success = false;
00344 #endif
00345     
00346   }
00347   TEUCHOS_STANDARD_CATCH_STATEMENTS(true,std::cerr,success);
00348   
00349   if(success)
00350     *out << "\nEnd Result: TEST PASSED\n" << std::endl; 
00351   else
00352     *out << "\nEnd Result: TEST FAILED\n" << std::endl;
00353   
00354   return ( success ? 0 : 1 );
00355   
00356 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Tue Oct 20 10:13:59 2009 for Teuchos Package Browser (Single Doxygen Collection) by  doxygen 1.6.1