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 #include "SimTKcommon/internal/Array.h"
00047
00048 #include "SimTKcommon/internal/conjugate.h"
00049 #include "SimTKcommon/internal/CompositeNumericalTypes.h"
00050 #include "SimTKcommon/internal/NTraits.h"
00051 #include "SimTKcommon/internal/negator.h"
00052
00053 #include <complex>
00054 #include <cmath>
00055 #include <climits>
00056 #include <cassert>
00057
00058 namespace SimTK {
00059
00061
00063
00064 typedef conjugate<Real> Conjugate;
00065
00066
00067
00068
00069
00070
00071
00072
00073 static const Real& NaN = NTraits<Real>::getNaN();
00074 static const Real& Infinity = NTraits<Real>::getInfinity();
00075
00076
00077
00078 static const Real& Eps = NTraits<Real>::getEps();
00079 static const Real& SqrtEps = NTraits<Real>::getSqrtEps();
00080 static const Real& TinyReal = NTraits<Real>::getTiny();
00081 static const Real& SignificantReal = NTraits<Real>::getSignificant();
00082
00083 static const Real& LeastPositiveReal = NTraits<Real>::getLeastPositive();
00084 static const Real& MostPositiveReal = NTraits<Real>::getMostPositive();
00085 static const Real& LeastNegativeReal = NTraits<Real>::getLeastNegative();
00086 static const Real& MostNegativeReal = NTraits<Real>::getMostNegative();
00087
00088
00089
00090 static const int NumDigitsReal = NTraits<Real>::getNumDigits();
00091
00092
00093
00094
00095 static const int LosslessNumDigitsReal = NTraits<Real>::getLosslessNumDigits();
00096
00097
00098
00099 static const Real& Zero = NTraits<Real>::getZero();
00100 static const Real& One = NTraits<Real>::getOne();
00101 static const Real& MinusOne = NTraits<Real>::getMinusOne();
00102 static const Real& Two = NTraits<Real>::getTwo();
00103 static const Real& Three = NTraits<Real>::getThree();
00104
00105 static const Real& OneHalf = NTraits<Real>::getOneHalf();
00106 static const Real& OneThird = NTraits<Real>::getOneThird();
00107 static const Real& OneFourth = NTraits<Real>::getOneFourth();
00108 static const Real& OneFifth = NTraits<Real>::getOneFifth();
00109 static const Real& OneSixth = NTraits<Real>::getOneSixth();
00110 static const Real& OneSeventh = NTraits<Real>::getOneSeventh();
00111 static const Real& OneEighth = NTraits<Real>::getOneEighth();
00112 static const Real& OneNinth = NTraits<Real>::getOneNinth();
00113 static const Real& Pi = NTraits<Real>::getPi();
00114 static const Real& OneOverPi = NTraits<Real>::getOneOverPi();
00115 static const Real& E = NTraits<Real>::getE();
00116 static const Real& Log2E = NTraits<Real>::getLog2E();
00117 static const Real& Log10E = NTraits<Real>::getLog10E();
00118 static const Real& Sqrt2 = NTraits<Real>::getSqrt2();
00119 static const Real& OneOverSqrt2 = NTraits<Real>::getOneOverSqrt2();
00120 static const Real& Sqrt3 = NTraits<Real>::getSqrt3();
00121 static const Real& OneOverSqrt3 = NTraits<Real>::getOneOverSqrt3();
00122 static const Real& CubeRoot2 = NTraits<Real>::getCubeRoot2();
00123 static const Real& CubeRoot3 = NTraits<Real>::getCubeRoot3();
00124 static const Real& Ln2 = NTraits<Real>::getLn2();
00125 static const Real& Ln10 = NTraits<Real>::getLn10();
00126
00127
00128
00129
00130 static const Complex& I = NTraits<Complex>::getI();
00131
00132
00134
00136
00137
00151
00152
00153 inline bool atMostOneBitIsSet(unsigned char v) {return (v&v-1)==0;}
00154 inline bool atMostOneBitIsSet(unsigned short v) {return (v&v-1)==0;}
00155 inline bool atMostOneBitIsSet(unsigned int v) {return (v&v-1)==0;}
00156 inline bool atMostOneBitIsSet(unsigned long v) {return (v&v-1)==0;}
00157 inline bool atMostOneBitIsSet(unsigned long long v) {return (v&v-1)==0;}
00158 inline bool atMostOneBitIsSet(signed char v) {return (v&v-1)==0;}
00159 inline bool atMostOneBitIsSet(char v) {return (v&v-1)==0;}
00160 inline bool atMostOneBitIsSet(short v) {return (v&v-1)==0;}
00161 inline bool atMostOneBitIsSet(int v) {return (v&v-1)==0;}
00162 inline bool atMostOneBitIsSet(long v) {return (v&v-1)==0;}
00163 inline bool atMostOneBitIsSet(long long v) {return (v&v-1)==0;}
00165
00180 inline bool exactlyOneBitIsSet(unsigned char v) {return v && atMostOneBitIsSet(v);}
00181 inline bool exactlyOneBitIsSet(unsigned short v) {return v && atMostOneBitIsSet(v);}
00182 inline bool exactlyOneBitIsSet(unsigned int v) {return v && atMostOneBitIsSet(v);}
00183 inline bool exactlyOneBitIsSet(unsigned long v) {return v && atMostOneBitIsSet(v);}
00184 inline bool exactlyOneBitIsSet(unsigned long long v) {return v && atMostOneBitIsSet(v);}
00185 inline bool exactlyOneBitIsSet(signed char v) {return v && atMostOneBitIsSet(v);}
00186 inline bool exactlyOneBitIsSet(char v) {return v && atMostOneBitIsSet(v);}
00187 inline bool exactlyOneBitIsSet(short v) {return v && atMostOneBitIsSet(v);}
00188 inline bool exactlyOneBitIsSet(int v) {return v && atMostOneBitIsSet(v);}
00189 inline bool exactlyOneBitIsSet(long v) {return v && atMostOneBitIsSet(v);}
00190 inline bool exactlyOneBitIsSet(long long v) {return v && atMostOneBitIsSet(v);}
00192
00219
00220 inline bool signBit(unsigned char i) {return false;}
00221 inline bool signBit(unsigned short i) {return false;}
00222 inline bool signBit(unsigned int i) {return false;}
00223 inline bool signBit(unsigned long i) {return false;}
00224 inline bool signBit(unsigned long long i) {return false;}
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 inline bool signBit(signed char i) {return ((unsigned char)i & 0x80U) != 0;}
00235 inline bool signBit(short i) {return ((unsigned short)i & 0x8000U) != 0;}
00236 inline bool signBit(int i) {return ((unsigned int)i & 0x80000000U) != 0;}
00237 inline bool signBit(long long i) {return ((unsigned long long)i & 0x8000000000000000ULL) != 0;}
00238
00239 inline bool signBit(long i) {return ((unsigned long)i
00240 & (unsigned long)LONG_MIN) != 0;}
00241
00242 inline bool signBit(const float& f) {return std::signbit(f);}
00243 inline bool signBit(const double& d) {return std::signbit(d);}
00244 inline bool signBit(const negator<float>& nf) {return std::signbit(-nf);}
00245 inline bool signBit(const negator<double>& nd) {return std::signbit(-nd);}
00246
00261 inline unsigned int sign(unsigned char u) {return u==0 ? 0 : 1;}
00262 inline unsigned int sign(unsigned short u) {return u==0 ? 0 : 1;}
00263 inline unsigned int sign(unsigned int u) {return u==0 ? 0 : 1;}
00264 inline unsigned int sign(unsigned long u) {return u==0 ? 0 : 1;}
00265 inline unsigned int sign(unsigned long long u) {return u==0 ? 0 : 1;}
00266
00267
00268
00269
00270 inline int sign(signed char i) {return i>0 ? 1 : (i<0 ? -1 : 0);}
00271 inline int sign(short i) {return i>0 ? 1 : (i<0 ? -1 : 0);}
00272 inline int sign(int i) {return i>0 ? 1 : (i<0 ? -1 : 0);}
00273 inline int sign(long i) {return i>0 ? 1 : (i<0 ? -1 : 0);}
00274 inline int sign(long long i) {return i>0 ? 1 : (i<0 ? -1 : 0);}
00275
00276 inline int sign(const float& x) {return x>0 ? 1 : (x<0 ? -1 : 0);}
00277 inline int sign(const double& x) {return x>0 ? 1 : (x<0 ? -1 : 0);}
00278 inline int sign(const long double& x) {return x>0 ? 1 : (x<0 ? -1 : 0);}
00279
00280 inline int sign(const negator<float>& x) {return -sign(-x);}
00281 inline int sign(const negator<double>& x) {return -sign(-x);}
00282 inline int sign(const negator<long double>& x) {return -sign(-x);}
00284
00301 inline unsigned char square(unsigned char u) {return u*u;}
00302 inline unsigned short square(unsigned short u) {return u*u;}
00303 inline unsigned int square(unsigned int u) {return u*u;}
00304 inline unsigned long square(unsigned long u) {return u*u;}
00305
00306 inline char square(char c) {return c*c;}
00307
00308 inline signed char square(signed char i) {return i*i;}
00309 inline short square(short i) {return i*i;}
00310 inline int square(int i) {return i*i;}
00311 inline long square(long i) {return i*i;}
00312
00313 inline float square(const float& x) {return x*x;}
00314 inline double square(const double& x) {return x*x;}
00315 inline long double square(const long double& x) {return x*x;}
00316
00317
00318
00319 inline float square(const negator<float>& x) {return square(-x);}
00320 inline double square(const negator<double>& x) {return square(-x);}
00321 inline long double square(const negator<long double>& x) {return square(-x);}
00322
00323
00324
00325
00326 template <class P> inline
00327 std::complex<P> square(const std::complex<P>& x) {
00328 const P re=x.real(), im=x.imag();
00329 return std::complex<P>(re*re-im*im, 2*re*im);
00330 }
00331
00332
00333
00334
00335 template <class P> inline
00336 std::complex<P> square(const conjugate<P>& x) {
00337 const P re=x.real(), nim=x.negImag();
00338 return std::complex<P>(re*re-nim*nim, -2*re*nim);
00339 }
00340
00341 template <class P> inline
00342 std::complex<P> square(const negator< std::complex<P> >& x) {
00343 return square(-x);
00344 }
00345
00346
00347
00348 template <class P> inline
00349 std::complex<P> square(const negator< conjugate<P> >& x) {
00350 return square(-x);
00351 }
00353
00372 inline unsigned char cube(unsigned char u) {return u*u*u;}
00373 inline unsigned short cube(unsigned short u) {return u*u*u;}
00374 inline unsigned int cube(unsigned int u) {return u*u*u;}
00375 inline unsigned long cube(unsigned long u) {return u*u*u;}
00376
00377 inline char cube(char c) {return c*c*c;}
00378
00379 inline signed char cube(signed char i) {return i*i*i;}
00380 inline short cube(short i) {return i*i*i;}
00381 inline int cube(int i) {return i*i*i;}
00382 inline long cube(long i) {return i*i*i;}
00383
00384 inline float cube(const float& x) {return x*x*x;}
00385 inline double cube(const double& x) {return x*x*x;}
00386 inline long double cube(const long double& x) {return x*x*x;}
00387
00388
00389
00390
00391 inline negator<float> cube(const negator<float>& x) {
00392 return negator<float>::recast(cube(-x));
00393 }
00394 inline negator<double> cube(const negator<double>& x) {
00395 return negator<double>::recast(cube(-x));
00396 }
00397 inline negator<long double> cube(const negator<long double>& x) {
00398 return negator<long double>::recast(cube(-x));
00399 }
00400
00401
00402
00403
00404 template <class P> inline
00405 std::complex<P> cube(const std::complex<P>& x) {
00406 const P re=x.real(), im=x.imag(), rr=re*re, ii=im*im;
00407 return std::complex<P>(re*(rr-3*ii), im*(3*rr-ii));
00408 }
00409
00410
00411
00412
00413
00414 template <class P> inline
00415 std::complex<P> cube(const negator< std::complex<P> >& x) {
00416
00417 const P nre=(-x).real(), nim=(-x).imag(), rr=nre*nre, ii=nim*nim;
00418 return std::complex<P>(nre*(3*ii-rr), nim*(ii-3*rr));
00419 }
00420
00421
00422
00423 template <class P> inline
00424 std::complex<P> cube(const conjugate<P>& x) {
00425 const P re=x.real(), nim=x.negImag(), rr=re*re, ii=nim*nim;
00426 return std::complex<P>(re*(rr-3*ii), nim*(ii-3*rr));
00427 }
00428
00429
00430
00431
00432 template <class P> inline
00433 std::complex<P> cube(const negator< conjugate<P> >& x) {
00434
00435 const P nre=(-x).real(), im=(-x).negImag(), rr=nre*nre, ii=im*im;
00436 return std::complex<P>(nre*(3*ii-rr), im*(3*rr-ii));
00437 }
00439
00471
00487 inline double& clampInPlace(double low, double& v, double high)
00488 { assert(low<=high); if (v<low) v=low; else if (v>high) v=high; return v; }
00490 inline float& clampInPlace(float low, float& v, float high)
00491 { assert(low<=high); if (v<low) v=low; else if (v>high) v=high; return v; }
00493 inline long double& clampInPlace(long double low, long double& v, long double high)
00494 { assert(low<=high); if (v<low) v=low; else if (v>high) v=high; return v; }
00495
00496
00497
00498
00501 inline double& clampInPlace(int low, double& v, int high)
00502 { return clampInPlace((double)low,v,(double)high); }
00505 inline float& clampInPlace(int low, float& v, int high)
00506 { return clampInPlace((float)low,v,(float)high); }
00509 inline long double& clampInPlace(int low, long double& v, int high)
00510 { return clampInPlace((long double)low,v,(long double)high); }
00511
00514 inline double& clampInPlace(int low, double& v, double high)
00515 { return clampInPlace((double)low,v,high); }
00518 inline float& clampInPlace(int low, float& v, float high)
00519 { return clampInPlace((float)low,v,high); }
00522 inline long double& clampInPlace(int low, long double& v, long double high)
00523 { return clampInPlace((long double)low,v,high); }
00524
00527 inline double& clampInPlace(double low, double& v, int high)
00528 { return clampInPlace(low,v,(double)high); }
00531 inline float& clampInPlace(float low, float& v, int high)
00532 { return clampInPlace(low,v,(float)high); }
00535 inline long double& clampInPlace(long double low, long double& v, int high)
00536 { return clampInPlace(low,v,(long double)high); }
00537
00539 inline unsigned char& clampInPlace(unsigned char low, unsigned char& v, unsigned char high)
00540 { assert(low<=high); if (v<low) v=low; else if (v>high) v=high; return v; }
00542 inline unsigned short& clampInPlace(unsigned short low, unsigned short& v, unsigned short high)
00543 { assert(low<=high); if (v<low) v=low; else if (v>high) v=high; return v; }
00545 inline unsigned int& clampInPlace(unsigned int low, unsigned int& v, unsigned int high)
00546 { assert(low<=high); if (v<low) v=low; else if (v>high) v=high; return v; }
00548 inline unsigned long& clampInPlace(unsigned long low, unsigned long& v, unsigned long high)
00549 { assert(low<=high); if (v<low) v=low; else if (v>high) v=high; return v; }
00551 inline unsigned long long& clampInPlace(unsigned long long low, unsigned long long& v, unsigned long long high)
00552 { assert(low<=high); if (v<low) v=low; else if (v>high) v=high; return v; }
00553
00555 inline char& clampInPlace(char low, char& v, char high)
00556 { assert(low<=high); if (v<low) v=low; else if (v>high) v=high; return v; }
00558 inline signed char& clampInPlace(signed char low, signed char& v, signed char high)
00559 { assert(low<=high); if (v<low) v=low; else if (v>high) v=high; return v; }
00560
00562 inline short& clampInPlace(short low, short& v, short high)
00563 { assert(low<=high); if (v<low) v=low; else if (v>high) v=high; return v; }
00565 inline int& clampInPlace(int low, int& v, int high)
00566 { assert(low<=high); if (v<low) v=low; else if (v>high) v=high; return v; }
00568 inline long& clampInPlace(long low, long& v, long high)
00569 { assert(low<=high); if (v<low) v=low; else if (v>high) v=high; return v; }
00571 inline long long& clampInPlace(long long low, long long& v, long long high)
00572 { assert(low<=high); if (v<low) v=low; else if (v>high) v=high; return v; }
00573
00575 inline negator<float>& clampInPlace(float low, negator<float>& v, float high)
00576 { assert(low<=high); if (v<low) v=low; else if (v>high) v=high; return v; }
00578 inline negator<double>& clampInPlace(double low, negator<double>& v, double high)
00579 { assert(low<=high); if (v<low) v=low; else if (v>high) v=high; return v; }
00581 inline negator<long double>& clampInPlace(long double low, negator<long double>& v, long double high)
00582 { assert(low<=high); if (v<low) v=low; else if (v>high) v=high; return v; }
00583
00584
00585
00606 inline double clamp(double low, double v, double high)
00607 { return clampInPlace(low,v,high); }
00609 inline float clamp(float low, float v, float high)
00610 { return clampInPlace(low,v,high); }
00612 inline long double clamp(long double low, long double v, long double high)
00613 { return clampInPlace(low,v,high); }
00614
00617 inline double clamp(int low, double v, int high)
00618 { return clampInPlace(low,v,high); }
00621 inline float clamp(int low, float v, int high)
00622 { return clampInPlace(low,v,high); }
00625 inline long double clamp(int low, long double v, int high)
00626 { return clampInPlace(low,v,high); }
00627
00630 inline double clamp(int low, double v, double high)
00631 { return clampInPlace(low,v,high); }
00634 inline float clamp(int low, float v, float high)
00635 { return clampInPlace(low,v,high); }
00638 inline long double clamp(int low, long double v, long double high)
00639 { return clampInPlace(low,v,high); }
00640
00643 inline double clamp(double low, double v, int high)
00644 { return clampInPlace(low,v,high); }
00647 inline float clamp(float low, float v, int high)
00648 { return clampInPlace(low,v,high); }
00651 inline long double clamp(long double low, long double v, int high)
00652 { return clampInPlace(low,v,high); }
00653
00655 inline unsigned char clamp(unsigned char low, unsigned char v, unsigned char high)
00656 { return clampInPlace(low,v,high); }
00658 inline unsigned short clamp(unsigned short low, unsigned short v, unsigned short high)
00659 { return clampInPlace(low,v,high); }
00661 inline unsigned int clamp(unsigned int low, unsigned int v, unsigned int high)
00662 { return clampInPlace(low,v,high); }
00664 inline unsigned long clamp(unsigned long low, unsigned long v, unsigned long high)
00665 { return clampInPlace(low,v,high); }
00667 inline unsigned long long clamp(unsigned long long low, unsigned long long v, unsigned long long high)
00668 { return clampInPlace(low,v,high); }
00669
00671 inline char clamp(char low, char v, char high)
00672 { return clampInPlace(low,v,high); }
00674 inline signed char clamp(signed char low, signed char v, signed char high)
00675 { return clampInPlace(low,v,high); }
00676
00678 inline short clamp(short low, short v, short high)
00679 { return clampInPlace(low,v,high); }
00681 inline int clamp(int low, int v, int high)
00682 { return clampInPlace(low,v,high); }
00684 inline long clamp(long low, long v, long high)
00685 { return clampInPlace(low,v,high); }
00687 inline long long clamp(long long low, long long v, long long high)
00688 { return clampInPlace(low,v,high); }
00689
00690
00691
00692
00693
00694
00695
00696
00701 inline float clamp(float low, negator<float> v, float high)
00702 { return clamp(low,(float)v,high); }
00707 inline double clamp(double low, negator<double> v, double high)
00708 { return clamp(low,(double)v,high); }
00713 inline long double clamp(long double low, negator<long double> v, long double high)
00714 { return clamp(low,(long double)v,high); }
00755
00770 inline double stepUp(double x)
00771 { assert(0 <= x && x <= 1);
00772 return x*x*x*(10+x*(6*x-15)); }
00773
00774
00789 inline double stepDown(double x) {return 1.0 -stepUp(x);}
00790
00791
00866 inline double stepAny(double y0, double yRange,
00867 double x0, double oneOverXRange,
00868 double x)
00869 { double xadj = (x-x0)*oneOverXRange;
00870 assert(-NTraits<double>::getSignificant() <= xadj
00871 && xadj <= 1 + NTraits<double>::getSignificant());
00872 clampInPlace(0.0,xadj,1.0);
00873 return y0 + yRange*stepUp(xadj); }
00874
00878 inline double dstepUp(double x) {
00879 assert(0 <= x && x <= 1);
00880 const double xxm1=x*(x-1);
00881 return 30*xxm1*xxm1;
00882 }
00883
00887 inline double dstepDown(double x) {return -dstepUp(x);}
00888
00892 inline double dstepAny(double yRange,
00893 double x0, double oneOverXRange,
00894 double x)
00895 { double xadj = (x-x0)*oneOverXRange;
00896 assert(-NTraits<double>::getSignificant() <= xadj
00897 && xadj <= 1 + NTraits<double>::getSignificant());
00898 clampInPlace(0.0,xadj,1.0);
00899 return yRange*oneOverXRange*dstepUp(xadj); }
00900
00904 inline double d2stepUp(double x) {
00905 assert(0 <= x && x <= 1);
00906 return 60*x*(1+x*(2*x-3));
00907 }
00908
00912 inline double d2stepDown(double x) {return -d2stepUp(x);}
00913
00917 inline double d2stepAny(double yRange,
00918 double x0, double oneOverXRange,
00919 double x)
00920 { double xadj = (x-x0)*oneOverXRange;
00921 assert(-NTraits<double>::getSignificant() <= xadj
00922 && xadj <= 1 + NTraits<double>::getSignificant());
00923 clampInPlace(0.0,xadj,1.0);
00924 return yRange*square(oneOverXRange)*d2stepUp(xadj); }
00925
00929 inline double d3stepUp(double x) {
00930 assert(0 <= x && x <= 1);
00931 return 60+360*x*(x-1);
00932 }
00933
00937 inline double d3stepDown(double x) {return -d3stepUp(x);}
00938
00942 inline double d3stepAny(double yRange,
00943 double x0, double oneOverXRange,
00944 double x)
00945 { double xadj = (x-x0)*oneOverXRange;
00946 assert(-NTraits<double>::getSignificant() <= xadj
00947 && xadj <= 1 + NTraits<double>::getSignificant());
00948 clampInPlace(0.0,xadj,1.0);
00949 return yRange*cube(oneOverXRange)*d3stepUp(xadj); }
00950
00951
00952
00954 inline float stepUp(float x)
00955 { assert(0 <= x && x <= 1);
00956 return x*x*x*(10+x*(6*x-15)); }
00958 inline float stepDown(float x) {return 1.0f-stepUp(x);}
00960 inline float stepAny(float y0, float yRange,
00961 float x0, float oneOverXRange,
00962 float x)
00963 { float xadj = (x-x0)*oneOverXRange;
00964 assert(-NTraits<float>::getSignificant() <= xadj
00965 && xadj <= 1 + NTraits<float>::getSignificant());
00966 clampInPlace(0.0f,xadj,1.0f);
00967 return y0 + yRange*stepUp(xadj); }
00968
00970 inline float dstepUp(float x)
00971 { assert(0 <= x && x <= 1);
00972 const float xxm1=x*(x-1);
00973 return 30*xxm1*xxm1; }
00975 inline float dstepDown(float x) {return -dstepUp(x);}
00977 inline float dstepAny(float yRange,
00978 float x0, float oneOverXRange,
00979 float x)
00980 { float xadj = (x-x0)*oneOverXRange;
00981 assert(-NTraits<float>::getSignificant() <= xadj
00982 && xadj <= 1 + NTraits<float>::getSignificant());
00983 clampInPlace(0.0f,xadj,1.0f);
00984 return yRange*oneOverXRange*dstepUp(xadj); }
00985
00987 inline float d2stepUp(float x)
00988 { assert(0 <= x && x <= 1);
00989 return 60*x*(1+x*(2*x-3)); }
00991 inline float d2stepDown(float x) {return -d2stepUp(x);}
00993 inline float d2stepAny(float yRange,
00994 float x0, float oneOverXRange,
00995 float x)
00996 { float xadj = (x-x0)*oneOverXRange;
00997 assert(-NTraits<float>::getSignificant() <= xadj
00998 && xadj <= 1 + NTraits<float>::getSignificant());
00999 clampInPlace(0.0f,xadj,1.0f);
01000 return yRange*square(oneOverXRange)*d2stepUp(xadj); }
01001
01003 inline float d3stepUp(float x)
01004 { assert(0 <= x && x <= 1);
01005 return 60+360*x*(x-1); }
01007 inline float d3stepDown(float x) {return -d3stepUp(x);}
01009 inline float d3stepAny(float yRange,
01010 float x0, float oneOverXRange,
01011 float x)
01012 { float xadj = (x-x0)*oneOverXRange;
01013 assert(-NTraits<float>::getSignificant() <= xadj
01014 && xadj <= 1 + NTraits<float>::getSignificant());
01015 clampInPlace(0.0f,xadj,1.0f);
01016 return yRange*cube(oneOverXRange)*d3stepUp(xadj); }
01017
01018
01019
01021 inline long double stepUp(long double x)
01022 { assert(0 <= x && x <= 1);
01023 return x*x*x*(10+x*(6*x-15)); }
01025 inline long double stepDown(long double x) {return 1.0L-stepUp(x);}
01027 inline long double stepAny(long double y0, long double yRange,
01028 long double x0, long double oneOverXRange,
01029 long double x)
01030 { long double xadj = (x-x0)*oneOverXRange;
01031 assert(-NTraits<long double>::getSignificant() <= xadj
01032 && xadj <= 1 + NTraits<long double>::getSignificant());
01033 clampInPlace(0.0L,xadj,1.0L);
01034 return y0 + yRange*stepUp(xadj); }
01035
01036
01038 inline long double dstepUp(long double x)
01039 { assert(0 <= x && x <= 1);
01040 const long double xxm1=x*(x-1);
01041 return 30*xxm1*xxm1; }
01043 inline long double dstepDown(long double x) {return -dstepUp(x);}
01045 inline long double dstepAny(long double yRange,
01046 long double x0, long double oneOverXRange,
01047 long double x)
01048 { long double xadj = (x-x0)*oneOverXRange;
01049 assert(-NTraits<long double>::getSignificant() <= xadj
01050 && xadj <= 1 + NTraits<long double>::getSignificant());
01051 clampInPlace(0.0L,xadj,1.0L);
01052 return yRange*oneOverXRange*dstepUp(xadj); }
01053
01055 inline long double d2stepUp(long double x)
01056 { assert(0 <= x && x <= 1);
01057 return 60*x*(1+x*(2*x-3)); }
01059 inline long double d2stepDown(long double x) {return -d2stepUp(x);}
01061 inline long double d2stepAny(long double yRange,
01062 long double x0, long double oneOverXRange,
01063 long double x)
01064 { long double xadj = (x-x0)*oneOverXRange;
01065 assert(-NTraits<long double>::getSignificant() <= xadj
01066 && xadj <= 1 + NTraits<long double>::getSignificant());
01067 clampInPlace(0.0L,xadj,1.0L);
01068 return yRange*square(oneOverXRange)*d2stepUp(xadj); }
01069
01070
01072 inline long double d3stepUp(long double x)
01073 { assert(0 <= x && x <= 1);
01074 return 60+360*x*(x-1); }
01076 inline long double d3stepDown(long double x) {return -d3stepUp(x);}
01078 inline long double d3stepAny(long double yRange,
01079 long double x0, long double oneOverXRange,
01080 long double x)
01081 { long double xadj = (x-x0)*oneOverXRange;
01082 assert(-NTraits<long double>::getSignificant() <= xadj
01083 && xadj <= 1 + NTraits<long double>::getSignificant());
01084 clampInPlace(0.0L,xadj,1.0L);
01085 return yRange*cube(oneOverXRange)*d3stepUp(xadj); }
01086
01087
01090 inline double stepUp(int x) {return stepUp((double)x);}
01093 inline double stepDown(int x) {return stepDown((double)x);}
01094
01095
01098 }
01099
01100 #endif //SimTK_SIMMATRIX_SCALAR_H_