Teuchos Package Browser (Single Doxygen Collection) Version of the Day
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 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 
00043 #include "Teuchos_OrdinalTraits.hpp"
00044 #include "Teuchos_ScalarTraits.hpp"
00045 #include "Teuchos_GlobalMPISession.hpp"
00046 #include "Teuchos_CommandLineProcessor.hpp"
00047 #include "Teuchos_VerboseObject.hpp"
00048 #include "Teuchos_StandardCatchMacros.hpp"
00049 #include "Teuchos_Version.hpp"
00050 
00051 
00052 namespace {
00053 
00054 
00055 //
00056 // Output of the ordinal that will avoid printing non-asci chars.
00057 //
00058 // The issue is that if you just print a raw char then if it prints non-asci
00059 // character, it can not be printed in some cases and causes trouble with
00060 // CTest/CDash.
00061 //
00062 
00063 // For general types, just print the type
00064 template <class T>
00065 T outputOrdinal(const T &t)
00066 {
00067   return t;
00068 }
00069 
00070 // For char, print the int value (avoid non-ansi chars)
00071 int outputOrdinal(const char& t)
00072 {
00073   return t;
00074 }
00075 
00076 
00077 //
00078 // Type ouptutting
00079 //
00080 
00081 template <class T>
00082 void TYPE_CHAIN_A(Teuchos::FancyOStream &out) {
00083   T b; typename Teuchos::ScalarTraits<T>::doublePrecision d;
00084   out << Teuchos::typeName(b);
00085   if (typeid(b) != typeid(d)) {
00086     out << " -> ";
00087     TYPE_CHAIN_A<typename Teuchos::ScalarTraits<T>::doublePrecision>(out);
00088   }
00089 }
00090 
00091 template <class T>
00092 void TYPE_CHAIN_D(Teuchos::FancyOStream &out) {
00093   T b; typename Teuchos::ScalarTraits<T>::halfPrecision d;
00094   out << Teuchos::typeName(b);
00095   if (typeid(b) != typeid(d)) {
00096     out << " -> ";
00097     TYPE_CHAIN_D<typename Teuchos::ScalarTraits<T>::halfPrecision>(out);
00098   }
00099 }
00100 
00101 
00102 inline std::string passfail(bool result)
00103 {
00104   return ( result ? "passed" : "failed" );
00105 }
00106 
00107 
00108 template<class Scalar>
00109 bool testScalarTraits(
00110   Teuchos::FancyOStream &out
00111   )
00112 {
00113   
00114   typedef Teuchos::ScalarTraits<Scalar> ST;
00115   
00116   bool success = true;
00117   bool result;
00118 
00119   out << "\nTesting: " << Teuchos::TypeNameTraits<ST>::name() << " ...\n";
00120 
00121   Teuchos::OSTab tab(out);
00122 
00123   const Scalar nan = ST::nan();
00124 
00125   out << "Type chain (ascending) : "; TYPE_CHAIN_A<Scalar>(out); out << "\n";
00126   out << "Type chain (descending): "; TYPE_CHAIN_D<Scalar>(out); out << "\n";
00127 
00128   out << "\nTesting that squareroot(NaN) == NaN! ...\n";
00129   {
00130     const Scalar sqrtNan = ST::squareroot(nan);
00131     result = (ST::isnaninf(sqrtNan));
00132     if (!result) success = false;
00133     out
00134       << "squareroot("<<nan<<") = " << sqrtNan << " == " << nan << " : "
00135       << passfail(result) << "\n";
00136   }
00137 
00138   out << "\nTesting that squareroot(-NaN) == NaN! ...\n";
00139   {
00140     const Scalar negNan = -nan;
00141     const Scalar sqrtNegNan = ST::squareroot(negNan);
00142     result = (ST::isnaninf(sqrtNegNan));
00143     if (!result) success = false;
00144     out
00145       << "squareroot("<<negNan<<") = " << sqrtNegNan << " == " << nan << " : "
00146       << passfail(result) << "\n";
00147   }
00148     
00149   if (ST::isComplex == false)
00150   {
00151     out << "\nTesting that squareroot(-1) == NaN! ...\n";
00152     {
00153       const Scalar negOne = -ST::one();
00154       const Scalar sqrtNegOne = ST::squareroot(negOne);
00155       result = (ST::isnaninf(sqrtNegOne));
00156       if (!result) success = false;
00157       out
00158         << "squareroot("<<negOne<<") = " << sqrtNegOne << " == " << nan << " : "
00159         << passfail(result) << "\n";
00160     }
00161   }
00162 
00163 #ifdef HAVE_NUMERIC_LIMITS
00164     
00165   out << "\nTesting that squareroot(quiet_NaN) == NaN! ...\n";
00166   {
00167     const Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
00168     const Scalar sqrtNan = ST::squareroot(nan);
00169     result = (ST::isnaninf(sqrtNan));
00170     if (!result) success = false;
00171     out
00172       << "squareroot("<<nan<<") = " << sqrtNan << " == " << nan << " : "
00173       << passfail(result) << "\n";
00174   }
00175     
00176   out << "\nTesting that squareroot(signaling_NaN) == NaN! ...\n";
00177   {
00178     const Scalar nan = std::numeric_limits<Scalar>::signaling_NaN();
00179     const Scalar sqrtNan = ST::squareroot(nan);
00180     result = (ST::isnaninf(sqrtNan));
00181     if (!result) success = false;
00182     out
00183       << "squareroot("<<nan<<") = " << sqrtNan << " == " << nan << " : "
00184       << passfail(result) << "\n";
00185   }
00186     
00187   out << "\nTesting that squareroot(inf) == NaN! ...\n";
00188   {
00189     const Scalar inf = std::numeric_limits<Scalar>::infinity();
00190     const Scalar sqrtInf = ST::squareroot(inf);
00191     result = (ST::isnaninf(sqrtInf));
00192     if (!result) success = false;
00193     out
00194       << "squareroot("<<inf<<") = " << sqrtInf << " == " << nan << " : "
00195       << passfail(result) << "\n";
00196   }
00197 
00198 #endif // HAVE_NUMERIC_LIMITS
00199     
00200   return success;
00201 
00202 }
00203 
00204 
00205 template<class Ordinal>
00206 bool testOrdinalTraits(
00207   Teuchos::FancyOStream &out
00208   )
00209 {
00210   
00211   typedef Teuchos::OrdinalTraits<Ordinal> OT;
00212   
00213   bool success = true;
00214   bool result;
00215 
00216   out << "\nTesting: " << Teuchos::TypeNameTraits<OT>::name() << " ...\n";
00217 
00218   Teuchos::OSTab tab(out);
00219 
00220   const Ordinal zero = OT::zero();
00221   const Ordinal one  = OT::one();
00222   const Ordinal max  = OT::max();
00223   const Ordinal invalid  = OT::invalid();
00224   out << "\nmax() == " << outputOrdinal(max) << "\n";
00225   out << "\ninvalid() == " << outputOrdinal(invalid) << "\n";
00226 
00227   out << "\nTesting that zero() * one() == zero() ...\n";
00228   {
00229     const Ordinal zto = zero*one;
00230     result = (zto == zero);
00231     if (!result) success = false;
00232     out
00233       << "zero*one = " << outputOrdinal(zto) << " == " << outputOrdinal(zero) << " : "
00234       << passfail(result) << "\n";
00235   }
00236 
00237   out << "\nTesting that one() * one() == one() ...\n";
00238   {
00239     const Ordinal oto = one*one;
00240     result = (oto == one);
00241     if (!result) success = false;
00242     out
00243       << "one*one = " << outputOrdinal(oto) << " == " << outputOrdinal(one) << " : "
00244       << passfail(result) << "\n";
00245   }
00246 
00247   out << "\nTesting that one() + zero() == zero() + one() == one() ...\n";
00248   {
00249     const Ordinal opz = one+zero;
00250     const Ordinal zpo = zero+one;
00251     result = (opz == one) && (zpo == one);
00252     if (!result) success = false;
00253     out
00254       << "one+zero = " << outputOrdinal(opz) << " == zero+one = "
00255       << outputOrdinal(zpo) << " == " << outputOrdinal(one) << " : "
00256       << passfail(result) << "\n";
00257   }
00258 
00259   out << "\nTesting that one() - one() == zero() ...\n";
00260   {
00261     const Ordinal omo = one-one;
00262     result = (omo == zero);
00263     if (!result) success = false;
00264     out
00265       << "one-one = " << outputOrdinal(omo) << " == " << outputOrdinal(zero) << " : "
00266       << passfail(result) << "\n";
00267   }
00268 
00269   out << "\nTesting that zero() < one() <= max() ...\n";
00270   {
00271     result = (zero < one) && (one <= max) && (zero < max);
00272     if (!result) success = false;
00273     out
00274       << "(zero < one) = " << (zero < one) << " == " 
00275       << "(one <= max) = " << (one <= max) << " == " 
00276       << "(zero < max) = " << (zero < max) << " == " 
00277       << true << " : "
00278       << passfail(result) << "\n";
00279   }
00280 
00281   out << "\nTesting that invalid() not in [zero(),max()]...\n";
00282   {
00283     result = !( (invalid > zero || invalid==zero) && (invalid <= max) );
00284     if (!result) success = false;
00285     out
00286       << "invalid in [zero,max] == false : " << passfail(result) << "\n";
00287   }
00288 
00289   return success;
00290 
00291 }
00292 
00293 
00294 } // namespace
00295 
00296 
00297 int main( int argc, char* argv[] ) {
00298 
00299   using Teuchos::CommandLineProcessor;
00300 
00301   bool success = true;
00302   bool result;
00303   
00304   Teuchos::GlobalMPISession mpiSession(&argc,&argv);
00305   //const int procRank = Teuchos::GlobalMPISession::getRank();
00306   
00307   Teuchos::RCP<Teuchos::FancyOStream>
00308     out = Teuchos::VerboseObjectBase::getDefaultOStream();
00309   
00310   try {
00311 
00312     // Read options from the commandline
00313     CommandLineProcessor  clp(false); // Don't throw exceptions
00314     CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
00315     if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) {
00316       *out << "\nEnd Result: TEST FAILED" << std::endl;
00317       return parse_return;
00318     }
00319 
00320     result = testScalarTraits<float>(*out);
00321     if(!result) success = false;
00322 
00323     result = testScalarTraits<double>(*out);
00324     if(!result) success = false;
00325 
00326     result = testOrdinalTraits<char>(*out);
00327     if(!result) success = false;
00328 
00329     result = testOrdinalTraits<short int>(*out);
00330     if(!result) success = false;
00331 
00332     result = testOrdinalTraits<int>(*out);
00333     if(!result) success = false;
00334 
00335     result = testOrdinalTraits<long int>(*out);
00336     if(!result) success = false;
00337 
00338     result = testOrdinalTraits<size_t>(*out);
00339     if(!result) success = false;
00340 
00341 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
00342     result = testOrdinalTraits<long long int>(*out);
00343     if(!result) success = false;
00344 #endif
00345 
00346 #ifdef HAVE_TEUCHOS___INT64
00347     result = testOrdinalTraits<__int64>(*out);
00348     if(!result) success = false;
00349 
00350     result = testOrdinalTraits<unsigned __int64>(*out);
00351     if(!result) success = false;
00352 #endif
00353 
00354 // #ifdef HAVE_TEUCHOS_COMPLEX
00355 //     result = testScalarTraits<std::complex<double> >(*out);
00356 //     if(!result) success = false;
00357 // #endif
00358     
00359 #ifdef HAVE_TEUCHOS_QD
00360     result = testScalarTraits<dd_real>(*out);
00361     if(!result) success = false;
00362     result = testScalarTraits<qd_real>(*out);
00363     if(!result) success = false;
00364 #endif
00365     
00366   }
00367   TEUCHOS_STANDARD_CATCH_STATEMENTS(true,std::cerr,success);
00368   
00369   if(success)
00370     *out << "\nEnd Result: TEST PASSED\n" << std::endl; 
00371   else
00372     *out << "\nEnd Result: TEST FAILED\n" << std::endl;
00373   
00374   return ( success ? 0 : 1 );
00375   
00376 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines