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
00030
00031
00032
00033
00034
00035
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
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
00142 static inline int random() { return rand(); };
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
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
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
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 }
00274
00275 #endif // _TEUCHOS_SCALARTRAITS_HPP_