Teuchos_ScalarTraits.hpp

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 // Kris
00030 // 06.18.03 -- Minor formatting changes
00031 //          -- Changed calls to LAPACK objects to use new <OType, SType> templates
00032 // 07.08.03 -- Move into Teuchos package/namespace
00033 // 07.11.03 -- Added ScalarTraits for ARPREC::mp_real
00034 // 07.14.03 -- Fixed int rand() function (was set up to return a floating-point style random number)
00035 // 07.17.03 -- Added squareroot() function
00036 
00037 #ifndef _TEUCHOS_SCALARTRAITS_HPP_
00038 #define _TEUCHOS_SCALARTRAITS_HPP_
00039 
00044 #include "Teuchos_LAPACK.hpp"
00045 
00046 #ifdef HAVE_TEUCHOS_ARPREC
00047 #include "mp/mpreal.h"
00048 #endif
00049 
00077 namespace Teuchos {
00078 
00079   template<class T>
00080   struct UndefinedScalarTraits
00081   {
00083     static inline T notDefined() { return T::this_type_is_missing_a_specialization(); };
00084   };
00085 
00086   template<class T>
00087   struct ScalarTraits
00088   {
00090     typedef T magnitudeType;
00092     static inline bool haveMachineParameters() { return false; };
00094     static inline magnitudeType eps()   { return UndefinedScalarTraits<T>::notDefined(); };
00096     static inline magnitudeType sfmin() { return UndefinedScalarTraits<T>::notDefined(); };
00098     static inline magnitudeType base()  { return UndefinedScalarTraits<T>::notDefined(); };
00100     static inline magnitudeType prec()  { return UndefinedScalarTraits<T>::notDefined(); };
00102     static inline magnitudeType t()     { return UndefinedScalarTraits<T>::notDefined(); };
00104     static inline magnitudeType rnd()   { return UndefinedScalarTraits<T>::notDefined(); };
00106     static inline magnitudeType emin()  { return UndefinedScalarTraits<T>::notDefined(); };
00108     static inline magnitudeType rmin()  { return UndefinedScalarTraits<T>::notDefined(); };
00110     static inline magnitudeType emax()  { return UndefinedScalarTraits<T>::notDefined(); };
00112     static inline magnitudeType rmax()  { return UndefinedScalarTraits<T>::notDefined(); };
00114     static inline magnitudeType magnitude(T a) { return UndefinedScalarTraits<T>::notDefined(); };
00116     static inline T zero()                     { return UndefinedScalarTraits<T>::notDefined(); };
00118     static inline T one()                      { return UndefinedScalarTraits<T>::notDefined(); };
00120     static inline void seedrandom(unsigned int s) { int i; T t = &i; };
00122     static inline T random()                   { return UndefinedScalarTraits<T>::notDefined(); };
00124     static inline std::string name()           { (void)UndefinedScalarTraits<T>::notDefined(); return 0; };
00126     static inline magnitudeType squareroot(T x) { return UndefinedScalarTraits<T>::notDefined(); };
00127   };
00128   
00129 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00130 
00131   template<>
00132   struct ScalarTraits<int>
00133   {
00134     typedef int magnitudeType;
00135     static inline bool haveMachineParameters() { return false; };
00136     // Not defined: eps(), sfmin(), base(), prec(), t(), rnd(), emin(), rmin(), emax(), rmax()
00137     static inline magnitudeType magnitude(int a) { return abs(a); };
00138     static inline int zero()  { return 0; };
00139     static inline int one()   { return 1; };
00140     static inline void seedrandom(unsigned int s) { srand(s); };
00141     //static inline int random() { return (-1 + 2*rand()); };  // RAB: This version should be used to be consistent with others
00142     static inline int random() { return rand(); };             // RAB: This version should be used for an unsigned int, not int
00143     static inline std::string name() { return "int"; };
00144     static inline int squareroot(int x) { return (int) sqrt((double) x); };
00145   };
00146   
00147   template<>
00148   struct ScalarTraits<float>
00149   {
00150     typedef float magnitudeType;
00151     static inline bool haveMachineParameters() { return true; };
00152     static inline float eps()   { LAPACK<int, float> lp; return lp.LAMCH('E'); };
00153     static inline float sfmin() { LAPACK<int, float> lp; return lp.LAMCH('S'); };
00154     static inline float base()  { LAPACK<int, float> lp; return lp.LAMCH('B'); };
00155     static inline float prec()  { LAPACK<int, float> lp; return lp.LAMCH('P'); };
00156     static inline float t()     { LAPACK<int, float> lp; return lp.LAMCH('N'); };
00157     static inline float rnd()   { LAPACK<int, float> lp; return lp.LAMCH('R'); };
00158     static inline float emin()  { LAPACK<int, float> lp; return lp.LAMCH('M'); };
00159     static inline float rmin()  { LAPACK<int, float> lp; return lp.LAMCH('U'); };
00160     static inline float emax()  { LAPACK<int, float> lp; return lp.LAMCH('L'); };
00161     static inline float rmax()  { LAPACK<int, float> lp; return lp.LAMCH('O'); };
00162     static inline magnitudeType magnitude(float a) { return fabs(a); };    
00163     static inline float zero()  { return(0.0); };
00164     static inline float one()   { return(1.0); };    
00165     static inline void seedrandom(unsigned int s) { srand(s); };
00166     static inline float random() { float rnd = (float) rand() / RAND_MAX; return (float)(-1.0 + 2.0 * rnd); };
00167     static inline std::string name() { return "float"; };
00168     static inline float squareroot(float x) { return sqrt(x); };
00169   };
00170   
00171   template<>
00172   struct ScalarTraits<double>
00173   {
00174     typedef double magnitudeType;
00175     static inline bool haveMachineParameters() { return true; };
00176     static inline magnitudeType magnitude(double a) { return fabs(a); };
00177     static inline double zero()  { return 0.0; };
00178     static inline double one()   { return 1.0; };
00179     static inline double eps()   { LAPACK<int, double> lp; return lp.LAMCH('E'); };
00180     static inline double sfmin() { LAPACK<int, double> lp; return lp.LAMCH('S'); };
00181     static inline double base()  { LAPACK<int, double> lp; return lp.LAMCH('B'); };
00182     static inline double prec()  { LAPACK<int, double> lp; return lp.LAMCH('P'); };
00183     static inline double t()     { LAPACK<int, double> lp; return lp.LAMCH('N'); };
00184     static inline double rnd()   { LAPACK<int, double> lp; return lp.LAMCH('R'); };
00185     static inline double emin()  { LAPACK<int, double> lp; return lp.LAMCH('M'); };
00186     static inline double rmin()  { LAPACK<int, double> lp; return lp.LAMCH('U'); };
00187     static inline double emax()  { LAPACK<int, double> lp; return lp.LAMCH('L'); };
00188     static inline double rmax()  { LAPACK<int, double> lp; return lp.LAMCH('O'); };
00189     static inline void seedrandom(unsigned int s) { srand(s); };
00190     static inline double random() { double rnd = (double) rand() / RAND_MAX; return (double)(-1.0 + 2.0 * rnd); };
00191     static inline std::string name() { return "double"; };
00192     static inline double squareroot(double x) { return sqrt(x); };
00193   };
00194 
00195 #ifdef HAVE_TEUCHOS_ARPREC
00196 
00197   template<>
00198   struct ScalarTraits<mp_real>
00199   {
00200     typedef mp_real magnitudeType;
00201     static inline bool haveMachineParameters() { return false; };
00202     // Not defined: eps(), sfmin(), base(), prec(), t(), rnd(), emin(), rmin(), emax(), rmax()
00203     static magnitudeType magnitude(mp_real a) { return abs(a); };
00204     static inline mp_real zero() { mp_real zero = 0.0; return zero; };
00205     static inline mp_real one() { mp_real one = 1.0; return one; };    
00206     static inline void seedrandom(unsigned int s) { 
00207       long int seedVal = static_cast<long int>(s);
00208       srand48(seedVal);
00209     };
00210     static inline mp_real random() { return mp_rand(); };
00211     static inline std::string name() { return "mp_real"; };
00212     static inline mp_real squareroot(mp_real x) { return sqrt(x); };
00213   };
00214   
00215 #endif // HAVE_TEUCHOS_ARPREC
00216  
00217 #if ( defined(HAVE_COMPLEX) || defined(HAVE_COMPLEX_H) ) && defined(HAVE_TEUCHOS_COMPLEX)
00218 
00219   // Partial specialization for complex numbers templated on real type T
00220   template<class T> 
00221   struct ScalarTraits<
00222 #if defined(HAVE_COMPLEX)
00223     std::complex<T>
00224 #elif  defined(HAVE_COMPLEX_H)
00225     ::complex<T>
00226 #endif
00227     >
00228   {
00229 #if defined(HAVE_COMPLEX)
00230     typedef std::complex<T>  ComplexT;
00231 #elif  defined(HAVE_COMPLEX_H)
00232     typedef ::complex<T>     ComplexT;
00233 #endif
00234     typedef typename ScalarTraits<T>::magnitudeType magnitudeType;
00235     static inline bool haveMachineParameters() { return true; };
00236     static inline magnitudeType eps()          { return ScalarTraits<magnitudeType>::eps(); };
00237     static inline magnitudeType sfmin()        { return ScalarTraits<magnitudeType>::sfmin(); };
00238     static inline magnitudeType base()         { return ScalarTraits<magnitudeType>::base(); };
00239     static inline magnitudeType prec()         { return ScalarTraits<magnitudeType>::prec(); };
00240     static inline magnitudeType t()            { return ScalarTraits<magnitudeType>::t(); };
00241     static inline magnitudeType rnd()          { return ScalarTraits<magnitudeType>::rnd(); };
00242     static inline magnitudeType emin()         { return ScalarTraits<magnitudeType>::emin(); };
00243     static inline magnitudeType rmin()         { return ScalarTraits<magnitudeType>::rmin(); };
00244     static inline magnitudeType emax()         { return ScalarTraits<magnitudeType>::emax(); };
00245     static inline magnitudeType rmax()         { return ScalarTraits<magnitudeType>::rmax(); };
00246     static magnitudeType magnitude(ComplexT a) { return std::fabs(a); };
00247     static inline ComplexT zero()              { return ComplexT(ScalarTraits<magnitudeType>::zero(),ScalarTraits<magnitudeType>::zero()); };
00248     static inline ComplexT one()               { return ComplexT(ScalarTraits<magnitudeType>::one(),ScalarTraits<magnitudeType>::zero());; };
00249     static inline void seedrandom(unsigned int s) { ScalarTraits<magnitudeType>::seedrandom(s); };
00250     static inline ComplexT random()
00251     {
00252       const T rnd1 = ScalarTraits<magnitudeType>::random();
00253       const T rnd2 = ScalarTraits<magnitudeType>::random();
00254       return ComplexT(rnd1,rnd2);
00255     };
00256     static inline std::string name() { return std::string("std::complex<")+std::string(ScalarTraits<magnitudeType>::name())+std::string(">"); };
00257     // This will only return one of the square roots of x, the other can be obtained by taking its conjugate
00258     static inline ComplexT squareroot(ComplexT x)
00259     {
00260       typedef ScalarTraits<magnitudeType>  STMT;
00261       const T r  = x.real(), i = x.imag();
00262       const T a  = STMT::squareroot((r*r)+(i*i));
00263       const T nr = STMT::squareroot((a+r)/2);
00264       const T ni = STMT::squareroot((a-r)/2);
00265       return ComplexT(nr,ni);
00266     };
00267   };
00268 
00269 #endif //  HAVE_COMPLEX || HAVE_COMPLEX_H
00270 
00271 #endif // DOXYGEN_SHOULD_SKIP_THIS
00272 
00273 } // Teuchos namespace
00274 
00275 #endif // _TEUCHOS_SCALARTRAITS_HPP_

Generated on Thu Sep 18 12:42:50 2008 for Teuchos - Trilinos Tools Package by doxygen 1.3.9.1