00001 #ifndef SimTK_SIMMATRIX_NTRAITS_H_
00002 #define SimTK_SIMMATRIX_NTRAITS_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
00058 #include <cstddef>
00059 #include <cassert>
00060 #include <complex>
00061 #include <iostream>
00062 #include <limits>
00063
00064 using std::complex;
00065
00066 namespace SimTK {
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 template <class R> class conjugate;
00077
00078
00079
00080
00081 template <class T> class CNT;
00082
00083
00084 template <class N> class NTraits;
00085 template <class R> class NTraits< complex<R> >;
00086 template <class R> class NTraits< conjugate<R> >;
00087 template <> class NTraits<float>;
00088 template <> class NTraits<double>;
00089 template <> class NTraits<long double>;
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 template <class N> class negator;
00100
00101
00102
00103
00104
00105
00106 static const complex<long double> zeroes(0);
00107
00108
00109
00110
00111
00112
00113
00114 template <class R1, class R2> struct Widest {};
00115 template <> struct Widest<float,float> {typedef float Type;};
00116 template <> struct Widest<float,double> {typedef double Type;};
00117 template <> struct Widest<float,long double> {typedef long double Type;};
00118 template <> struct Widest<double,float> {typedef double Type;};
00119 template <> struct Widest<double,double> {typedef double Type;};
00120 template <> struct Widest<double,long double> {typedef long double Type;};
00121 template <> struct Widest<long double,float> {typedef long double Type;};
00122 template <> struct Widest<long double,double> {typedef long double Type;};
00123 template <> struct Widest<long double,long double> {typedef long double Type;};
00124 template <class R1, class R2> struct Widest< complex<R1>,complex<R2> >
00125 { typedef complex< typename Widest<R1,R2>::Type > Type; };
00126 template <class R1, class R2> struct Widest< complex<R1>,R2 >
00127 { typedef complex< typename Widest<R1,R2>::Type > Type; };
00128 template <class R1, class R2> struct Widest< R1,complex<R2> >
00129 { typedef complex< typename Widest<R1,R2>::Type > Type; };
00130
00131 template <class N> class NTraits {
00132
00133 };
00134
00137 template <class R> class NTraits< complex<R> > {
00138 typedef complex<R> C;
00139 public:
00140 typedef C T;
00141 typedef negator<C> TNeg;
00142 typedef C TWithoutNegator;
00143
00144 typedef R TReal;
00145 typedef R TImag;
00146 typedef C TComplex;
00147 typedef conjugate<R> THerm;
00148 typedef C TPosTrans;
00149 typedef R TSqHermT;
00150 typedef R TSqTHerm;
00151 typedef C TElement;
00152 typedef C TRow;
00153 typedef C TCol;
00154
00155 typedef R TAbs;
00156 typedef C TStandard;
00157 typedef C TInvert;
00158 typedef C TNormalize;
00159
00160 typedef C Scalar;
00161 typedef C Number;
00162 typedef C StdNumber;
00163 typedef R Precision;
00164 typedef R ScalarSq;
00165
00166
00167
00168
00169
00170
00171
00172 template <class P> struct Result {
00173 typedef typename CNT<P>::template Result<C>::Mul Mul;
00174 typedef typename CNT< typename CNT<P>::THerm >::template Result<C>::Mul Dvd;
00175 typedef typename CNT<P>::template Result<C>::Add Add;
00176 typedef typename CNT< typename CNT<P>::TNeg >::template Result<C>::Add Sub;
00177 };
00178
00179
00180 template <class P> struct Substitute {
00181 typedef P Type;
00182 };
00183
00184 enum {
00185 NRows = 1,
00186 NCols = 1,
00187 RowSpacing = 1,
00188 ColSpacing = 1,
00189 NPackedElements = 1,
00190 NActualElements = 1,
00191 NActualScalars = 1,
00192 ImagOffset = 1,
00193 RealStrideFactor = 2,
00194 ArgDepth = SCALAR_DEPTH,
00195 IsScalar = 1,
00196 IsNumber = 1,
00197 IsStdNumber = 1,
00198 IsPrecision = 0,
00199 SignInterpretation = 1
00200 };
00201 static const T* getData(const T& t) { return &t; }
00202 static T* updData(T& t) { return &t; }
00203 static const R& real(const T& t) { return (reinterpret_cast<const R*>(&t))[0]; }
00204 static R& real(T& t) { return (reinterpret_cast<R*>(&t))[0]; }
00205 static const R& imag(const T& t) { return (reinterpret_cast<const R*>(&t))[1]; }
00206 static R& imag(T& t) { return (reinterpret_cast<R*>(&t))[1]; }
00207
00208 static const TNeg& negate(const T& t) {return reinterpret_cast<const TNeg&>(t);}
00209 static TNeg& negate(T& t) {return reinterpret_cast<TNeg&>(t);}
00210
00211 static const THerm& transpose(const T& t) {return reinterpret_cast<const THerm&>(t);}
00212 static THerm& transpose(T& t) {return reinterpret_cast<THerm&>(t);}
00213
00214 static const TPosTrans& positionalTranspose(const T& t)
00215 {return reinterpret_cast<const TPosTrans&>(t);}
00216 static TPosTrans& positionalTranspose(T& t)
00217 {return reinterpret_cast<TPosTrans&>(t);}
00218
00219 static const TWithoutNegator& castAwayNegatorIfAny(const T& t)
00220 {return reinterpret_cast<const TWithoutNegator&>(t);}
00221 static TWithoutNegator& updCastAwayNegatorIfAny(const T& t)
00222 {return reinterpret_cast<TWithoutNegator&>(t);}
00223
00224 static ScalarSq scalarNormSqr(const T& t)
00225 { return t.real()*t.real() + t.imag()*t.imag(); }
00226 static TAbs abs(const T& t)
00227 { return std::abs(t); }
00228 static const TStandard& standardize(const T& t) {return t;}
00229 static TNormalize normalize(const T& t) {return t/abs(t);}
00230 static TInvert invert(const T& t) {return TReal(1)/t;}
00231
00232 static const T& getNaN() {
00233 static const T c=T(NTraits<R>::getNaN(), NTraits<R>::getNaN());
00234 return c;
00235 }
00236 static const T& getInfinity() {
00237 static const T c=T(NTraits<R>::getInfinity(),NTraits<R>::getInfinity());
00238 return c;
00239 }
00240 static const T& getI() {
00241 static const T c = T(0,1);
00242 return c;
00243 }
00244
00245
00246 static const T& getZero() {static const T c(NTraits<R>::getZero()); return c;}
00247 static const T& getOne() {static const T c(NTraits<R>::getOne()); return c;}
00248 static const T& getMinusOne() {static const T c(NTraits<R>::getMinusOne()); return c;}
00249 static const T& getTwo() {static const T c(NTraits<R>::getTwo()); return c;}
00250 static const T& getThree() {static const T c(NTraits<R>::getThree()); return c;}
00251 static const T& getOneHalf() {static const T c(NTraits<R>::getOneHalf()); return c;}
00252 static const T& getOneThird() {static const T c(NTraits<R>::getOneThird()); return c;}
00253 static const T& getOneFourth() {static const T c(NTraits<R>::getOneFourth()); return c;}
00254 static const T& getOneFifth() {static const T c(NTraits<R>::getOneFifth()); return c;}
00255 static const T& getOneSixth() {static const T c(NTraits<R>::getOneSixth()); return c;}
00256 static const T& getOneSeventh() {static const T c(NTraits<R>::getOneSeventh()); return c;}
00257 static const T& getOneEighth() {static const T c(NTraits<R>::getOneEighth()); return c;}
00258 static const T& getOneNinth() {static const T c(NTraits<R>::getOneNinth()); return c;}
00259 static const T& getPi() {static const T c(NTraits<R>::getPi()); return c;}
00260 static const T& getOneOverPi() {static const T c(NTraits<R>::getOneOverPi()); return c;}
00261 static const T& getE() {static const T c(NTraits<R>::getE()); return c;}
00262 static const T& getLog2E() {static const T c(NTraits<R>::getLog2E()); return c;}
00263 static const T& getLog10E() {static const T c(NTraits<R>::getLog10E()); return c;}
00264 static const T& getSqrt2() {static const T c(NTraits<R>::getSqrt2()); return c;}
00265 static const T& getOneOverSqrt2() {static const T c(NTraits<R>::getOneOverSqrt2()); return c;}
00266 static const T& getSqrt3() {static const T c(NTraits<R>::getSqrt3()); return c;}
00267 static const T& getOneOverSqrt3() {static const T c(NTraits<R>::getOneOverSqrt3()); return c;}
00268 static const T& getCubeRoot2() {static const T c(NTraits<R>::getCubeRoot2()); return c;}
00269 static const T& getCubeRoot3() {static const T c(NTraits<R>::getCubeRoot3()); return c;}
00270 static const T& getLn2() {static const T c(NTraits<R>::getLn2()); return c;}
00271 static const T& getLn10() {static const T c(NTraits<R>::getLn10()); return c;}
00272 };
00273
00274
00275
00276
00277 #define SimTK_BNTCMPLX_SPEC(T1,T2) \
00278 template<> template<> struct NTraits< complex<T1> >::Result<T2> { \
00279 typedef Widest< complex<T1>,T2 >::Type W; \
00280 typedef W Mul; typedef W Dvd; typedef W Add; typedef W Sub; \
00281 }; \
00282 template<> template<> struct NTraits< complex<T1> >::Result< complex<T2> > { \
00283 typedef Widest< complex<T1>,complex<T2> >::Type W; \
00284 typedef W Mul; typedef W Dvd; typedef W Add; typedef W Sub; \
00285 }; \
00286 template<> template<> struct NTraits< complex<T1> >::Result< conjugate<T2> > { \
00287 typedef Widest< complex<T1>,complex<T2> >::Type W; \
00288 typedef W Mul; typedef W Dvd; typedef W Add; typedef W Sub; \
00289 }
00290 SimTK_BNTCMPLX_SPEC(float,float);SimTK_BNTCMPLX_SPEC(float,double);SimTK_BNTCMPLX_SPEC(float,long double);
00291 SimTK_BNTCMPLX_SPEC(double,float);SimTK_BNTCMPLX_SPEC(double,double);SimTK_BNTCMPLX_SPEC(double,long double);
00292 SimTK_BNTCMPLX_SPEC(long double,float);SimTK_BNTCMPLX_SPEC(long double,double);SimTK_BNTCMPLX_SPEC(long double,long double);
00293 #undef SimTK_BNTCMPLX_SPEC
00294
00295
00296
00297 template <class R> class NTraits< conjugate<R> > {
00298 typedef complex<R> C;
00299 public:
00300 typedef conjugate<R> T;
00301 typedef negator<T> TNeg;
00302 typedef T TWithoutNegator;
00303 typedef R TReal;
00304 typedef negator<R> TImag;
00305 typedef conjugate<R> TComplex;
00306 typedef complex<R> THerm;
00307 typedef conjugate<R> TPosTrans;
00308 typedef R TSqHermT;
00309 typedef R TSqTHerm;
00310 typedef conjugate<R> TElement;
00311 typedef conjugate<R> TRow;
00312 typedef conjugate<R> TCol;
00313
00314 typedef R TAbs;
00315 typedef C TStandard;
00316 typedef complex<R> TInvert;
00317 typedef T TNormalize;
00318
00319 typedef conjugate<R> Scalar;
00320 typedef conjugate<R> Number;
00321 typedef C StdNumber;
00322 typedef R Precision;
00323 typedef R ScalarSq;
00324
00325
00326
00327
00328
00329
00330 template <class P> struct Result {
00331 typedef typename CNT<P>::template Result<T>::Mul Mul;
00332 typedef typename CNT<typename CNT<P>::THerm>::template Result<T>::Mul Dvd;
00333 typedef typename CNT<P>::template Result<T>::Add Add;
00334 typedef typename CNT<typename CNT<P>::TNeg>::template Result<T>::Add Sub;
00335 };
00336
00337
00338 template <class P> struct Substitute {
00339 typedef P Type;
00340 };
00341
00342 enum {
00343 NRows = 1,
00344 NCols = 1,
00345 RowSpacing = 1,
00346 ColSpacing = 1,
00347 NPackedElements = 1,
00348 NActualElements = 1,
00349 NActualScalars = 1,
00350 ImagOffset = 1,
00351 RealStrideFactor = 2,
00352 ArgDepth = SCALAR_DEPTH,
00353 IsScalar = 1,
00354 IsNumber = 1,
00355 IsStdNumber = 0,
00356 IsPrecision = 0,
00357 SignInterpretation = 1
00358 };
00359
00360 static const T* getData(const T& t) { return &t; }
00361 static T* updData(T& t) { return &t; }
00362 static const TReal& real(const T& t) { return t.real(); }
00363 static TReal& real(T& t) { return t.real(); }
00364 static const TImag& imag(const T& t) { return t.imag(); }
00365 static TImag& imag(T& t) { return t.imag(); }
00366
00367 static const TNeg& negate(const T& t) {return reinterpret_cast<const TNeg&>(t);}
00368 static TNeg& negate(T& t) {return reinterpret_cast<TNeg&>(t);}
00369
00370 static const THerm& transpose(const T& t) {return reinterpret_cast<const THerm&>(t);}
00371 static THerm& transpose(T& t) {return reinterpret_cast<THerm&>(t);}
00372
00373 static const TPosTrans& positionalTranspose(const T& t)
00374 {return reinterpret_cast<const TPosTrans&>(t);}
00375 static TPosTrans& positionalTranspose(T& t)
00376 {return reinterpret_cast<TPosTrans&>(t);}
00377
00378 static const TWithoutNegator& castAwayNegatorIfAny(const T& t)
00379 {return reinterpret_cast<const TWithoutNegator&>(t);}
00380 static TWithoutNegator& updCastAwayNegatorIfAny(const T& t)
00381 {return reinterpret_cast<TWithoutNegator&>(t);}
00382
00383 static ScalarSq scalarNormSqr(const T& t)
00384 { return t.real()*t.real() + t.negImag()*t.negImag(); }
00385 static TAbs abs(const T& t)
00386 { return std::abs(t.conj()); }
00387 static TStandard standardize(const T& t)
00388 { return TStandard(t); }
00389 static TNormalize normalize(const T& t) {return TNormalize(t/abs(t));}
00390 static TInvert invert(const T& t) {return TReal(1)/t;}
00391
00392
00393
00394 static const T& getNaN() {
00395 static const T c=T(NTraits<R>::getNaN(),NTraits<R>::getNaN());
00396 return c;
00397 }
00398
00399
00400 static const T& getInfinity() {
00401 static const T c=T(NTraits<R>::getInfinity(),NTraits<R>::getInfinity());
00402 return c;
00403 }
00404
00405
00406 static const T& getI() {
00407 static const T c = T(0,-1);
00408 return c;
00409 }
00410
00411
00412 static const T& getZero() {static const T c(NTraits<R>::getZero()); return c;}
00413 static const T& getOne() {static const T c(NTraits<R>::getOne()); return c;}
00414 static const T& getMinusOne() {static const T c(NTraits<R>::getMinusOne()); return c;}
00415 static const T& getTwo() {static const T c(NTraits<R>::getTwo()); return c;}
00416 static const T& getThree() {static const T c(NTraits<R>::getThree()); return c;}
00417 static const T& getOneHalf() {static const T c(NTraits<R>::getOneHalf()); return c;}
00418 static const T& getOneThird() {static const T c(NTraits<R>::getOneThird()); return c;}
00419 static const T& getOneFourth() {static const T c(NTraits<R>::getOneFourth()); return c;}
00420 static const T& getOneFifth() {static const T c(NTraits<R>::getOneFifth()); return c;}
00421 static const T& getOneSixth() {static const T c(NTraits<R>::getOneSixth()); return c;}
00422 static const T& getOneSeventh() {static const T c(NTraits<R>::getOneSeventh()); return c;}
00423 static const T& getOneEighth() {static const T c(NTraits<R>::getOneEighth()); return c;}
00424 static const T& getOneNinth() {static const T c(NTraits<R>::getOneNinth()); return c;}
00425 static const T& getPi() {static const T c(NTraits<R>::getPi()); return c;}
00426 static const T& getOneOverPi() {static const T c(NTraits<R>::getOneOverPi()); return c;}
00427 static const T& getE() {static const T c(NTraits<R>::getE()); return c;}
00428 static const T& getLog2E() {static const T c(NTraits<R>::getLog2E()); return c;}
00429 static const T& getLog10E() {static const T c(NTraits<R>::getLog10E()); return c;}
00430 static const T& getSqrt2() {static const T c(NTraits<R>::getSqrt2()); return c;}
00431 static const T& getOneOverSqrt2() {static const T c(NTraits<R>::getOneOverSqrt2()); return c;}
00432 static const T& getSqrt3() {static const T c(NTraits<R>::getSqrt3()); return c;}
00433 static const T& getOneOverSqrt3() {static const T c(NTraits<R>::getOneOverSqrt3()); return c;}
00434 static const T& getCubeRoot2() {static const T c(NTraits<R>::getCubeRoot2()); return c;}
00435 static const T& getCubeRoot3() {static const T c(NTraits<R>::getCubeRoot3()); return c;}
00436 static const T& getLn2() {static const T c(NTraits<R>::getLn2()); return c;}
00437 static const T& getLn10() {static const T c(NTraits<R>::getLn10()); return c;}
00438 };
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456 #define SimTK_NTRAITS_CONJ_SPEC(T1,T2) \
00457 template<> template<> struct NTraits< conjugate<T1> >::Result<T2> { \
00458 typedef conjugate<Widest<T1,T2>::Type> W; \
00459 typedef W Mul; typedef W Dvd; typedef W Add; typedef W Sub; \
00460 }; \
00461 template<> template<> struct NTraits< conjugate<T1> >::Result<complex<T2> >{\
00462 typedef Widest<complex<T1>,complex<T2> >::Type W; \
00463 typedef W Mul; typedef W Dvd; typedef W Add; typedef negator<W> Sub; \
00464 }; \
00465 template<> template<> struct NTraits< conjugate<T1> >::Result<conjugate<T2> >{\
00466 typedef Widest<T1,T2>::Type W; typedef complex<W> WC; \
00467 typedef negator<WC> Mul; typedef WC Dvd; typedef conjugate<W> Add; typedef WC Sub;\
00468 }
00469 SimTK_NTRAITS_CONJ_SPEC(float,float);SimTK_NTRAITS_CONJ_SPEC(float,double);
00470 SimTK_NTRAITS_CONJ_SPEC(float,long double);
00471 SimTK_NTRAITS_CONJ_SPEC(double,float);SimTK_NTRAITS_CONJ_SPEC(double,double);
00472 SimTK_NTRAITS_CONJ_SPEC(double,long double);
00473 SimTK_NTRAITS_CONJ_SPEC(long double,float);SimTK_NTRAITS_CONJ_SPEC(long double,double);
00474 SimTK_NTRAITS_CONJ_SPEC(long double,long double);
00475 #undef SimTK_NTRAITS_CONJ_SPEC
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 #define SimTK_DEFINE_REAL_NTRAITS(R) \
00486 template <> class NTraits<R> { \
00487 public: \
00488 typedef R T; \
00489 typedef negator<T> TNeg; \
00490 typedef T TWithoutNegator; \
00491 typedef T TReal; \
00492 typedef T TImag; \
00493 typedef complex<T> TComplex; \
00494 typedef T THerm; \
00495 typedef T TPosTrans; \
00496 typedef T TSqHermT; \
00497 typedef T TSqTHerm; \
00498 typedef T TElement; \
00499 typedef T TRow; \
00500 typedef T TCol; \
00501 typedef T TAbs; \
00502 typedef T TStandard; \
00503 typedef T TInvert; \
00504 typedef T TNormalize; \
00505 typedef T Scalar; \
00506 typedef T Number; \
00507 typedef T StdNumber; \
00508 typedef T Precision; \
00509 typedef T ScalarSq; \
00510 template <class P> struct Result { \
00511 typedef typename CNT<P>::template Result<R>::Mul Mul; \
00512 typedef typename CNT< typename CNT<P>::THerm >::template Result<R>::Mul Dvd; \
00513 typedef typename CNT<P>::template Result<R>::Add Add; \
00514 typedef typename CNT< typename CNT<P>::TNeg >::template Result<R>::Add Sub; \
00515 }; \
00516 template <class P> struct Substitute { \
00517 typedef P Type; \
00518 }; \
00519 enum { \
00520 NRows = 1, \
00521 NCols = 1, \
00522 RowSpacing = 1, \
00523 ColSpacing = 1, \
00524 NPackedElements = 1, \
00525 NActualElements = 1, \
00526 NActualScalars = 1, \
00527 ImagOffset = 0, \
00528 RealStrideFactor = 1, \
00529 ArgDepth = SCALAR_DEPTH, \
00530 IsScalar = 1, \
00531 IsNumber = 1, \
00532 IsStdNumber = 1, \
00533 IsPrecision = 1, \
00534 SignInterpretation = 1 \
00535 }; \
00536 static const T* getData(const T& t) { return &t; } \
00537 static T* updData(T& t) { return &t; } \
00538 static const T& real(const T& t) { return t; } \
00539 static T& real(T& t) { return t; } \
00540 static const T& imag(const T&) { return reinterpret_cast<const T&>(zeroes); } \
00541 static T& imag(T&) { assert(false); return *reinterpret_cast<T*>(0); } \
00542 static const TNeg& negate(const T& t) {return reinterpret_cast<const TNeg&>(t);} \
00543 static TNeg& negate(T& t) {return reinterpret_cast<TNeg&>(t);} \
00544 static const THerm& transpose(const T& t) {return reinterpret_cast<const THerm&>(t);} \
00545 static THerm& transpose(T& t) {return reinterpret_cast<THerm&>(t);} \
00546 static const TPosTrans& positionalTranspose(const T& t) \
00547 {return reinterpret_cast<const TPosTrans&>(t);} \
00548 static TPosTrans& positionalTranspose(T& t) \
00549 {return reinterpret_cast<TPosTrans&>(t);} \
00550 static const TWithoutNegator& castAwayNegatorIfAny(const T& t) \
00551 {return reinterpret_cast<const TWithoutNegator&>(t);} \
00552 static TWithoutNegator& updCastAwayNegatorIfAny(T& t) \
00553 {return reinterpret_cast<TWithoutNegator&>(t);} \
00554 static ScalarSq scalarNormSqr(const T& t) {return t*t;} \
00555 static TAbs abs(const T& t) {return std::abs(t);} \
00556 static const TStandard& standardize(const T& t) {return t;} \
00557 static TNormalize normalize(const T& t) {return (t>0?T(1):(t<0?T(-1):getNaN()));} \
00558 static TInvert invert(const T& t) {return T(1)/t;} \
00559 \
00560 static const T& getNaN() {static const T c=std::numeric_limits<T>::quiet_NaN(); return c;} \
00561 static const T& getInfinity() {static const T c=std::numeric_limits<T>::infinity(); return c;} \
00562 static const T& getEps() {static const T c=std::numeric_limits<T>::epsilon(); return c;} \
00563 static const T& getLeastPositive(){static const T c=std::numeric_limits<T>::min(); return c;} \
00564 static const T& getMostPositive() {static const T c=std::numeric_limits<T>::max(); return c;} \
00565 static const T& getLeastNegative(){static const T c=-std::numeric_limits<T>::min(); return c;} \
00566 static const T& getMostNegative() {static const T c=-std::numeric_limits<T>::max(); return c;} \
00567 static const T& getSqrtEps() {static const T c=std::sqrt(getEps()); return c;} \
00568 static const T& getTiny() {static const T c=std::pow(getEps(), (T)1.25L); return c;} \
00569 static const T& getSignificant() {static const T c=std::pow(getEps(), (T)0.875L); return c;} \
00570 \
00571 static const T& getZero() {static const T c=(T)(0); return c;} \
00572 static const T& getOne() {static const T c=(T)(1); return c;} \
00573 static const T& getMinusOne() {static const T c=(T)(-1); return c;} \
00574 static const T& getTwo() {static const T c=(T)(2); return c;} \
00575 static const T& getThree() {static const T c=(T)(3); return c;} \
00576 static const T& getOneHalf() {static const T c=(T)(0.5L); return c;} \
00577 static const T& getOneThird() {static const T c=(T)(1.L/3.L); return c;} \
00578 static const T& getOneFourth() {static const T c=(T)(0.25L); return c;} \
00579 static const T& getOneFifth() {static const T c=(T)(0.2L); return c;} \
00580 static const T& getOneSixth() {static const T c=(T)(1.L/6.L); return c;} \
00581 static const T& getOneSeventh() {static const T c=(T)(1.L/7.L); return c;} \
00582 static const T& getOneEighth() {static const T c=(T)(0.125L); return c;} \
00583 static const T& getOneNinth() {static const T c=(T)(1.L/9.L); return c;} \
00584 static const T& getPi() {static const T c=(T)(SimTK_PI); return c;} \
00585 static const T& getOneOverPi() {static const T c=(T)(1.L/SimTK_PI); return c;} \
00586 static const T& getE() {static const T c=(T)(SimTK_E); return c;} \
00587 static const T& getLog2E() {static const T c=(T)(SimTK_LOG2E); return c;} \
00588 static const T& getLog10E() {static const T c=(T)(SimTK_LOG10E); return c;} \
00589 static const T& getSqrt2() {static const T c=(T)(SimTK_SQRT2); return c;} \
00590 static const T& getOneOverSqrt2() {static const T c=(T)(1.L/SimTK_SQRT2); return c;} \
00591 static const T& getSqrt3() {static const T c=(T)(SimTK_SQRT3); return c;} \
00592 static const T& getOneOverSqrt3() {static const T c=(T)(1.L/SimTK_SQRT3); return c;} \
00593 static const T& getCubeRoot2() {static const T c=(T)(SimTK_CBRT2); return c;} \
00594 static const T& getCubeRoot3() {static const T c=(T)(SimTK_CBRT3); return c;} \
00595 static const T& getLn2() {static const T c=(T)(SimTK_LN2); return c;} \
00596 static const T& getLn10() {static const T c=(T)(SimTK_LN10); return c;} \
00597 \
00598 static const int getNumDigits() {static const int c=(int)(std::log10(1/getEps()) -0.5); return c;} \
00599 static const int getLosslessNumDigits() {static const int c=(int)(std::log10(1/getTiny())+0.5); return c;} \
00600 }; \
00601 template<> struct NTraits<R>::Result<float> \
00602 {typedef Widest<R,float>::Type Mul;typedef Mul Dvd;typedef Mul Add;typedef Mul Sub;}; \
00603 template<> struct NTraits<R>::Result<double> \
00604 {typedef Widest<R,double>::Type Mul;typedef Mul Dvd;typedef Mul Add;typedef Mul Sub;}; \
00605 template<> struct NTraits<R>::Result<long double> \
00606 {typedef Widest<R,long double>::Type Mul;typedef Mul Dvd;typedef Mul Add;typedef Mul Sub;}; \
00607 template<> struct NTraits<R>::Result<complex<float> > \
00608 {typedef Widest<R,complex<float> >::Type Mul;typedef Mul Dvd;typedef Mul Add;typedef Mul Sub;}; \
00609 template<> struct NTraits<R>::Result<complex<double> > \
00610 {typedef Widest<R,complex<double> >::Type Mul;typedef Mul Dvd;typedef Mul Add;typedef Mul Sub;}; \
00611 template<> struct NTraits<R>::Result<complex<long double> > \
00612 {typedef Widest<R,complex<long double> >::Type Mul;typedef Mul Dvd;typedef Mul Add;typedef Mul Sub;}; \
00613 template<> struct NTraits<R>::Result<conjugate<float> > \
00614 {typedef conjugate<Widest<R,float>::Type> Mul;typedef Mul Dvd;typedef Mul Add;typedef Mul Sub;}; \
00615 template<> struct NTraits<R>::Result<conjugate<double> > \
00616 {typedef conjugate<Widest<R,double>::Type> Mul;typedef Mul Dvd;typedef Mul Add;typedef Mul Sub;}; \
00617 template<> struct NTraits<R>::Result<conjugate<long double> > \
00618 {typedef conjugate<Widest<R,long double>::Type> Mul;typedef Mul Dvd;typedef Mul Add;typedef Mul Sub;}
00619 SimTK_DEFINE_REAL_NTRAITS(float);
00620 SimTK_DEFINE_REAL_NTRAITS(double);
00621 SimTK_DEFINE_REAL_NTRAITS(long double);
00622 #undef SimTK_DEFINE_REAL_NTRAITS
00623
00625 template <class R> class CNT< complex<R> > : public NTraits< complex<R> > { };
00626 template <class R> class CNT< conjugate<R> > : public NTraits< conjugate<R> > { };
00627 template <> class CNT<float> : public NTraits<float> { };
00628 template <> class CNT<double> : public NTraits<double> { };
00629 template <> class CNT<long double> : public NTraits<long double> { };
00630
00631
00632 }
00633
00634 #endif //SimTK_SIMMATRIX_NTRAITS_H_