Scalar.h
Go to the documentation of this file.00001 #ifndef SimTK_SIMMATRIX_SCALAR_H_
00002 #define SimTK_SIMMATRIX_SCALAR_H_
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
00041 #include "SimTKcommon/internal/common.h"
00042 #include "SimTKcommon/Constants.h"
00043 #include "SimTKcommon/internal/Exception.h"
00044 #include "SimTKcommon/internal/ExceptionMacros.h"
00045 #include "SimTKcommon/internal/String.h"
00046
00047 #include "SimTKcommon/internal/conjugate.h"
00048 #include "SimTKcommon/internal/CompositeNumericalTypes.h"
00049 #include "SimTKcommon/internal/NTraits.h"
00050 #include "SimTKcommon/internal/negator.h"
00051
00052 #include <complex>
00053
00054 namespace SimTK {
00055
00057
00059
00060 typedef conjugate<Real> Conjugate;
00061
00062
00063
00064
00065
00066
00067
00068
00069 static const Real& NaN = NTraits<Real>::getNaN();
00070 static const Real& Infinity = NTraits<Real>::getInfinity();
00071
00072
00073
00074 static const Real& Eps = NTraits<Real>::getEps();
00075 static const Real& SqrtEps = NTraits<Real>::getSqrtEps();
00076 static const Real& TinyReal = NTraits<Real>::getTiny();
00077 static const Real& SignificantReal = NTraits<Real>::getSignificant();
00078
00079 static const Real& LeastPositiveReal = NTraits<Real>::getLeastPositive();
00080 static const Real& MostPositiveReal = NTraits<Real>::getMostPositive();
00081 static const Real& LeastNegativeReal = NTraits<Real>::getLeastNegative();
00082 static const Real& MostNegativeReal = NTraits<Real>::getMostNegative();
00083
00084
00085
00086 static const int NumDigitsReal = NTraits<Real>::getNumDigits();
00087
00088
00089
00090
00091 static const int LosslessNumDigitsReal = NTraits<Real>::getLosslessNumDigits();
00092
00093
00094
00095 static const Real& Zero = NTraits<Real>::getZero();
00096 static const Real& One = NTraits<Real>::getOne();
00097 static const Real& MinusOne = NTraits<Real>::getMinusOne();
00098 static const Real& Two = NTraits<Real>::getTwo();
00099 static const Real& Three = NTraits<Real>::getThree();
00100
00101 static const Real& OneHalf = NTraits<Real>::getOneHalf();
00102 static const Real& OneThird = NTraits<Real>::getOneThird();
00103 static const Real& OneFourth = NTraits<Real>::getOneFourth();
00104 static const Real& OneFifth = NTraits<Real>::getOneFifth();
00105 static const Real& OneSixth = NTraits<Real>::getOneSixth();
00106 static const Real& OneSeventh = NTraits<Real>::getOneSeventh();
00107 static const Real& OneEighth = NTraits<Real>::getOneEighth();
00108 static const Real& OneNinth = NTraits<Real>::getOneNinth();
00109 static const Real& Pi = NTraits<Real>::getPi();
00110 static const Real& OneOverPi = NTraits<Real>::getOneOverPi();
00111 static const Real& E = NTraits<Real>::getE();
00112 static const Real& Log2E = NTraits<Real>::getLog2E();
00113 static const Real& Log10E = NTraits<Real>::getLog10E();
00114 static const Real& Sqrt2 = NTraits<Real>::getSqrt2();
00115 static const Real& OneOverSqrt2 = NTraits<Real>::getOneOverSqrt2();
00116 static const Real& Sqrt3 = NTraits<Real>::getSqrt3();
00117 static const Real& OneOverSqrt3 = NTraits<Real>::getOneOverSqrt3();
00118 static const Real& CubeRoot2 = NTraits<Real>::getCubeRoot2();
00119 static const Real& CubeRoot3 = NTraits<Real>::getCubeRoot3();
00120 static const Real& Ln2 = NTraits<Real>::getLn2();
00121 static const Real& Ln10 = NTraits<Real>::getLn10();
00122
00123
00124
00125
00126 static const Complex& I = NTraits<Complex>::getI();
00127
00128
00130
00132
00133
00134
00135 inline bool canStoreInInt(char) {return true;}
00136 inline bool canStoreInInt(unsigned char) {return true;}
00137 inline bool canStoreInInt(signed char) {return true;}
00138 inline bool canStoreInInt(short) {return true;}
00139 inline bool canStoreInInt(unsigned short) {return true;}
00140 inline bool canStoreInInt(int) {return true;}
00141 inline bool canStoreInInt(unsigned int u) {return (unsigned int)(int(u)) == u;}
00142 inline bool canStoreInInt(long i) {return long(int(i)) == i;}
00143 inline bool canStoreInInt(unsigned long u) {return (unsigned long)(int(u)) == u;}
00144
00145
00146
00147 inline bool canStoreInNonnegativeInt(char c) {return c >= 0;}
00148 inline bool canStoreInNonnegativeInt(unsigned char c) {return true;}
00149 inline bool canStoreInNonnegativeInt(signed char c) {return c >= 0;}
00150 inline bool canStoreInNonnegativeInt(short s) {return s >= 0;}
00151 inline bool canStoreInNonnegativeInt(unsigned short s) {return true;}
00152 inline bool canStoreInNonnegativeInt(int i) {return i >= 0;}
00153 inline bool canStoreInNonnegativeInt(long l) {return canStoreInInt(l) && l >= 0;}
00154 inline bool canStoreInNonnegativeInt(unsigned int u) {return canStoreInInt(u);}
00155 inline bool canStoreInNonnegativeInt(unsigned long u) {return canStoreInInt(u);}
00156
00169 inline bool isNaN(const float& x) {
00170 volatile float xx = x;
00171 return x != xx;
00172 }
00173
00174 inline bool isNaN(const double& x) {
00175 volatile double xx = x;
00176 return x != xx;
00177 }
00178
00179 inline bool isNaN(const long double& x) {
00180 volatile long double xx = x;
00181 return x != xx;
00182 }
00183
00184
00185 template <class P> inline bool
00186 isNaN(const std::complex<P>& x) {
00187 return isNaN(x.real()) || isNaN(x.imag());
00188 }
00189
00190 template <class P> inline bool
00191 isNaN(const conjugate<P>& x) {
00192 return isNaN(x.real()) || isNaN(x.negImag());
00193 }
00194
00195 inline bool isNaN(const negator<float>& x) {return isNaN(-x);}
00196 inline bool isNaN(const negator<double>& x) {return isNaN(-x);}
00197 inline bool isNaN(const negator<long double>& x) {return isNaN(-x);}
00198
00199 template <class P> inline bool
00200 isNaN(const negator< std::complex<P> >& x) {return isNaN(-x);}
00201 template <class P> inline bool
00202 isNaN(const negator< conjugate<P> >& x) {return isNaN(-x);}
00203
00212 inline unsigned int sign(unsigned char u) {return u==0 ? 0 : 1;}
00213 inline unsigned int sign(unsigned short u) {return u==0 ? 0 : 1;}
00214 inline unsigned int sign(unsigned int u) {return u==0 ? 0 : 1;}
00215 inline unsigned int sign(unsigned long u) {return u==0 ? 0 : 1;}
00216
00217
00218
00219
00220 inline int sign(signed char i) {return i>0 ? 1 : (i<0 ? -1 : 0);}
00221 inline int sign(short i) {return i>0 ? 1 : (i<0 ? -1 : 0);}
00222 inline int sign(int i) {return i>0 ? 1 : (i<0 ? -1 : 0);}
00223 inline int sign(long i) {return i>0 ? 1 : (i<0 ? -1 : 0);}
00224
00225 inline int sign(const float& x) {return x>0 ? 1 : (x<0 ? -1 : 0);}
00226 inline int sign(const double& x) {return x>0 ? 1 : (x<0 ? -1 : 0);}
00227 inline int sign(const long double& x) {return x>0 ? 1 : (x<0 ? -1 : 0);}
00228
00229 inline int sign(const negator<float>& x) {return -sign(-x);}
00230 inline int sign(const negator<double>& x) {return -sign(-x);}
00231 inline int sign(const negator<long double>& x) {return -sign(-x);}
00232
00241 inline unsigned char square(unsigned char u) {return u*u;}
00242 inline unsigned short square(unsigned short u) {return u*u;}
00243 inline unsigned int square(unsigned int u) {return u*u;}
00244 inline unsigned long square(unsigned long u) {return u*u;}
00245
00246 inline char square(char c) {return c*c;}
00247
00248 inline signed char square(signed char i) {return i*i;}
00249 inline short square(short i) {return i*i;}
00250 inline int square(int i) {return i*i;}
00251 inline long square(long i) {return i*i;}
00252
00253 inline float square(const float& x) {return x*x;}
00254 inline double square(const double& x) {return x*x;}
00255 inline long double square(const long double& x) {return x*x;}
00256
00257
00258
00259 inline float square(const negator<float>& x) {return square(-x);}
00260 inline double square(const negator<double>& x) {return square(-x);}
00261 inline long double square(const negator<long double>& x) {return square(-x);}
00262
00263
00264
00265
00266 template <class P> inline
00267 std::complex<P> square(const std::complex<P>& x) {
00268 const P re=x.real(), im=x.imag();
00269 return std::complex<P>(re*re-im*im, 2*re*im);
00270 }
00271
00272
00273
00274
00275 template <class P> inline
00276 std::complex<P> square(const conjugate<P>& x) {
00277 const P re=x.real(), nim=x.negImag();
00278 return std::complex<P>(re*re-nim*nim, -2*re*nim);
00279 }
00280
00281 template <class P> inline
00282 std::complex<P> square(const negator< std::complex<P> >& x) {
00283 return square(-x);
00284 }
00285
00286
00287
00288 template <class P> inline
00289 std::complex<P> square(const negator< conjugate<P> >& x) {
00290 return square(-x);
00291 }
00292
00302 inline unsigned char cube(unsigned char u) {return u*u*u;}
00303 inline unsigned short cube(unsigned short u) {return u*u*u;}
00304 inline unsigned int cube(unsigned int u) {return u*u*u;}
00305 inline unsigned long cube(unsigned long u) {return u*u*u;}
00306
00307 inline char cube(char c) {return c*c*c;}
00308
00309 inline signed char cube(signed char i) {return i*i*i;}
00310 inline short cube(short i) {return i*i*i;}
00311 inline int cube(int i) {return i*i*i;}
00312 inline long cube(long i) {return i*i*i;}
00313
00314 inline float cube(const float& x) {return x*x*x;}
00315 inline double cube(const double& x) {return x*x*x;}
00316 inline long double cube(const long double& x) {return x*x*x;}
00317
00318
00319
00320
00321 inline negator<float> cube(const negator<float>& x) {
00322 return negator<float>::recast(cube(-x));
00323 }
00324 inline negator<double> cube(const negator<double>& x) {
00325 return negator<double>::recast(cube(-x));
00326 }
00327 inline negator<long double> cube(const negator<long double>& x) {
00328 return negator<long double>::recast(cube(-x));
00329 }
00330
00331
00332
00333
00334 template <class P> inline
00335 std::complex<P> cube(const std::complex<P>& x) {
00336 const P re=x.real(), im=x.imag(), rr=re*re, ii=im*im;
00337 return std::complex<P>(re*(rr-3*ii), im*(3*rr-ii));
00338 }
00339
00340
00341
00342
00343
00344 template <class P> inline
00345 std::complex<P> cube(const negator< std::complex<P> >& x) {
00346 const P nre=(-x).real(), nim=(-x).imag(),
00347 rr=nre*nre, ii=nim*nim;
00348 return std::complex<P>(nre*(3*ii-rr), nim*(ii-3*rr));
00349 }
00350
00351 }
00352
00353 #endif //SimTK_SIMMATRIX_SCALAR_H_