1#ifndef SimTK_SIMMATRIX_SCALAR_H_
2#define SimTK_SIMMATRIX_SCALAR_H_
260inline bool signBit(
unsigned char u) {
return false;}
261inline bool signBit(
unsigned short u) {
return false;}
262inline bool signBit(
unsigned int u) {
return false;}
263inline bool signBit(
unsigned long u) {
return false;}
264inline bool signBit(
unsigned long long u) {
return false;}
274inline bool signBit(
signed char i) {
return ((
unsigned char)i & 0x80U) != 0;}
275inline bool signBit(
short i) {
return ((
unsigned short)i & 0x8000U) != 0;}
276inline bool signBit(
int i) {
return ((
unsigned int)i & 0x80000000U) != 0;}
277inline bool signBit(
long long i) {
return ((
unsigned long long)i & 0x8000000000000000ULL) != 0;}
279inline bool signBit(
long i) {
return ((
unsigned long)i
280 & (
unsigned long)LONG_MIN) != 0;}
282inline bool signBit(
const float& f) {
return std::signbit(f);}
283inline bool signBit(
const double& d) {
return std::signbit(d);}
301inline unsigned int sign(
unsigned char u) {
return u==0 ? 0 : 1;}
302inline unsigned int sign(
unsigned short u) {
return u==0 ? 0 : 1;}
303inline unsigned int sign(
unsigned int u) {
return u==0 ? 0 : 1;}
304inline unsigned int sign(
unsigned long u) {
return u==0 ? 0 : 1;}
305inline unsigned int sign(
unsigned long long u) {
return u==0 ? 0 : 1;}
310inline int sign(
signed char i) {
return i>0 ? 1 : (i<0 ? -1 : 0);}
311inline int sign(
short i) {
return i>0 ? 1 : (i<0 ? -1 : 0);}
312inline int sign(
int i) {
return i>0 ? 1 : (i<0 ? -1 : 0);}
313inline int sign(
long i) {
return i>0 ? 1 : (i<0 ? -1 : 0);}
314inline int sign(
long long i) {
return i>0 ? 1 : (i<0 ? -1 : 0);}
316inline int sign(
const float& x) {
return x>0 ? 1 : (x<0 ? -1 : 0);}
317inline int sign(
const double& x) {
return x>0 ? 1 : (x<0 ? -1 : 0);}
339inline unsigned char square(
unsigned char u) {
return u*u;}
340inline unsigned short square(
unsigned short u) {
return u*u;}
341inline unsigned int square(
unsigned int u) {
return u*u;}
342inline unsigned long square(
unsigned long u) {
return u*u;}
343inline unsigned long long square(
unsigned long long u) {
return u*u;}
347inline signed char square(
signed char i) {
return i*i;}
348inline short square(
short i) {
return i*i;}
351inline long long square(
long long i) {
return i*i;}
353inline float square(
const float& x) {
return x*x;}
354inline double square(
const double& x) {
return x*x;}
364template <
class P>
inline
365std::complex<P>
square(
const std::complex<P>& x) {
366 const P re=x.real(), im=x.imag();
367 return std::complex<P>(re*re-im*im, 2*re*im);
373template <
class P>
inline
375 const P re=x.real(), nim=x.negImag();
376 return std::complex<P>(re*re-nim*nim, -2*re*nim);
379template <
class P>
inline
386template <
class P>
inline
410inline unsigned char cube(
unsigned char u) {
return u*u*u;}
411inline unsigned short cube(
unsigned short u) {
return u*u*u;}
412inline unsigned int cube(
unsigned int u) {
return u*u*u;}
413inline unsigned long cube(
unsigned long u) {
return u*u*u;}
414inline unsigned long long cube(
unsigned long long u) {
return u*u*u;}
416inline char cube(
char c) {
return c*c*c;}
418inline signed char cube(
signed char i) {
return i*i*i;}
419inline short cube(
short i) {
return i*i*i;}
420inline int cube(
int i) {
return i*i*i;}
421inline long cube(
long i) {
return i*i*i;}
422inline long long cube(
long long i) {
return i*i*i;}
424inline float cube(
const float& x) {
return x*x*x;}
425inline double cube(
const double& x) {
return x*x*x;}
440template <
class P>
inline
441std::complex<P>
cube(
const std::complex<P>& x) {
442 const P re=x.real(), im=x.imag(), rr=re*re, ii=im*im;
443 return std::complex<P>(re*(rr-3*ii), im*(3*rr-ii));
450template <
class P>
inline
453 const P nre=(-x).
real(), nim=(-x).
imag(), rr=nre*nre, ii=nim*nim;
454 return std::complex<P>(nre*(3*ii-rr), nim*(ii-3*rr));
459template <
class P>
inline
461 const P re=x.real(), nim=x.negImag(), rr=re*re, ii=nim*nim;
462 return std::complex<P>(re*(rr-3*ii), nim*(ii-3*rr));
468template <
class P>
inline
471 const P nre=(-x).
real(), im=(-x).negImag(), rr=nre*nre, ii=im*im;
472 return std::complex<P>(nre*(3*ii-rr), im*(3*rr-ii));
524{ assert(low<=high);
if (v<low) v=low;
else if (v>high) v=high;
return v; }
527{ assert(low<=high);
if (v<low) v=low;
else if (v>high) v=high;
return v; }
560inline unsigned char&
clampInPlace(
unsigned char low,
unsigned char& v,
unsigned char high)
561{ assert(low<=high);
if (v<low) v=low;
else if (v>high) v=high;
return v; }
563inline unsigned short&
clampInPlace(
unsigned short low,
unsigned short& v,
unsigned short high)
564{ assert(low<=high);
if (v<low) v=low;
else if (v>high) v=high;
return v; }
566inline unsigned int&
clampInPlace(
unsigned int low,
unsigned int& v,
unsigned int high)
567{ assert(low<=high);
if (v<low) v=low;
else if (v>high) v=high;
return v; }
569inline unsigned long&
clampInPlace(
unsigned long low,
unsigned long& v,
unsigned long high)
570{ assert(low<=high);
if (v<low) v=low;
else if (v>high) v=high;
return v; }
572inline unsigned long long&
clampInPlace(
unsigned long long low,
unsigned long long& v,
unsigned long long high)
573{ assert(low<=high);
if (v<low) v=low;
else if (v>high) v=high;
return v; }
577{ assert(low<=high);
if (v<low) v=low;
else if (v>high) v=high;
return v; }
579inline signed char&
clampInPlace(
signed char low,
signed char& v,
signed char high)
580{ assert(low<=high);
if (v<low) v=low;
else if (v>high) v=high;
return v; }
584{ assert(low<=high);
if (v<low) v=low;
else if (v>high) v=high;
return v; }
587{ assert(low<=high);
if (v<low) v=low;
else if (v>high) v=high;
return v; }
590{ assert(low<=high);
if (v<low) v=low;
else if (v>high) v=high;
return v; }
592inline long long&
clampInPlace(
long long low,
long long& v,
long long high)
593{ assert(low<=high);
if (v<low) v=low;
else if (v>high) v=high;
return v; }
597{ assert(low<=high);
if (v<low) v=low;
else if (v>high) v=high;
return v; }
600{ assert(low<=high);
if (v<low) v=low;
else if (v>high) v=high;
return v; }
624inline double clamp(
double low,
double v,
double high)
627inline float clamp(
float low,
float v,
float high)
632inline double clamp(
int low,
double v,
int high)
636inline float clamp(
int low,
float v,
int high)
641inline double clamp(
int low,
double v,
double high)
645inline float clamp(
int low,
float v,
float high)
650inline double clamp(
double low,
double v,
int high)
654inline float clamp(
float low,
float v,
int high)
658inline unsigned char clamp(
unsigned char low,
unsigned char v,
unsigned char high)
661inline unsigned short clamp(
unsigned short low,
unsigned short v,
unsigned short high)
664inline unsigned int clamp(
unsigned int low,
unsigned int v,
unsigned int high)
667inline unsigned long clamp(
unsigned long low,
unsigned long v,
unsigned long high)
670inline unsigned long long clamp(
unsigned long long low,
unsigned long long v,
unsigned long long high)
674inline char clamp(
char low,
char v,
char high)
677inline signed char clamp(
signed char low,
signed char v,
signed char high)
681inline short clamp(
short low,
short v,
short high)
684inline int clamp(
int low,
int v,
int high)
687inline long clamp(
long low,
long v,
long high)
690inline long long clamp(
long long low,
long long v,
long long high)
705{
return clamp(low,(
float)v,high); }
711{
return clamp(low,(
double)v,high); }
768{ assert(0 <= x && x <= 1);
769 return x*x*x*(10+x*(6*x-15)); }
863inline double stepAny(
double y0,
double yRange,
864 double x0,
double oneOverXRange,
866{
double xadj = (x-x0)*oneOverXRange;
870 return y0 + yRange*
stepUp(xadj); }
876 assert(0 <= x && x <= 1);
877 const double xxm1=x*(x-1);
890 double x0,
double oneOverXRange,
892{
double xadj = (x-x0)*oneOverXRange;
896 return yRange*oneOverXRange*
dstepUp(xadj); }
902 assert(0 <= x && x <= 1);
903 return 60*x*(1+x*(2*x-3));
915 double x0,
double oneOverXRange,
917{
double xadj = (x-x0)*oneOverXRange;
927 assert(0 <= x && x <= 1);
928 return 60+360*x*(x-1);
940 double x0,
double oneOverXRange,
942{
double xadj = (x-x0)*oneOverXRange;
952{ assert(0 <= x && x <= 1);
953 return x*x*x*(10+x*(6*x-15)); }
958 float x0,
float oneOverXRange,
960{
float xadj = (x-x0)*oneOverXRange;
964 return y0 + yRange*
stepUp(xadj); }
968{ assert(0 <= x && x <= 1);
969 const float xxm1=x*(x-1);
970 return 30*xxm1*xxm1; }
975 float x0,
float oneOverXRange,
977{
float xadj = (x-x0)*oneOverXRange;
981 return yRange*oneOverXRange*
dstepUp(xadj); }
985{ assert(0 <= x && x <= 1);
986 return 60*x*(1+x*(2*x-3)); }
991 float x0,
float oneOverXRange,
993{
float xadj = (x-x0)*oneOverXRange;
1001{ assert(0 <= x && x <= 1);
1002 return 60+360*x*(x-1); }
1007 float x0,
float oneOverXRange,
1009{
float xadj = (x-x0)*oneOverXRange;
1085static inline std::pair<T,T> approxCompleteEllipticIntegralsKE_T(T m) {
1086 static const T a[] =
1087 { (T)1.38629436112, (T)0.09666344259, (T)0.03590092383,
1088 (T)0.03742563713, (T)0.01451196212 };
1089 static const T b[] =
1090 { (T)0.5, (T)0.12498593597, (T)0.06880248576,
1091 (T)0.03328355346, (T)0.00441787012 };
1092 static const T c[] =
1093 { (T)1, (T)0.44325141463, (T)0.06260601220,
1094 (T)0.04757383546, (T)0.01736506451 };
1095 static const T d[] =
1096 { (T)0, (T)0.24998368310, (T)0.09200180037,
1097 (T)0.04069697526, (T)0.00526449639 };
1100 const T PiOver2 = NTraits<T>::getPi()/2;
1101 const T
Infinity = NTraits<T>::getInfinity();
1104 "approxCompleteEllipticIntegralsKE()",
1105 "Argument m (%g) is outside the legal range [0,1].", (
double)m);
1106 if (m >= 1)
return std::make_pair(
Infinity, (T)1);
1107 if (m <= 0)
return std::make_pair(PiOver2, PiOver2);
1109 const T m1=1-m, m2=m1*m1, m3=m1*m2, m4=m2*m2;
1110 const T lnm2 = std::log(m1);
1113 const T K = (a[0] + a[1]*m1 + a[2]*m2 + a[3]*m3 + a[4]*m4)
1114 - lnm2*(b[0] + b[1]*m1 + b[2]*m2 + b[3]*m3 + b[4]*m4);
1115 const T
E = (c[0] + c[1]*m1 + c[2]*m2 + c[3]*m3 + c[4]*m4)
1116 - lnm2*( d[1]*m1 + d[2]*m2 + d[3]*m3 + d[4]*m4);
1118 return std::make_pair(K,
E);
1158inline std::pair<double,double>
1160{
return approxCompleteEllipticIntegralsKE_T<double>(m); }
1166inline std::pair<float,float>
1168{
return approxCompleteEllipticIntegralsKE_T<float>(m); }
1175inline std::pair<double,double>
1177{
return approxCompleteEllipticIntegralsKE_T<double>((
double)m); }
1182static inline std::pair<T,T> completeEllipticIntegralsKE_T(T m) {
1184 const T TenEps = 10*NTraits<T>::getEps();
1185 const T
Infinity = NTraits<T>::getInfinity();
1186 const T PiOver2 = NTraits<T>::getPi() / 2;
1192 "completeEllipticIntegralsKE()",
1193 "Argument m (%g) is outside the legal range [0,1].", (
double)m);
1194 if (m >= 1)
return std::make_pair(
Infinity, (T)1);
1195 if (m <= 0)
return std::make_pair(PiOver2, PiOver2);
1197 const T k = std::sqrt(1-m);
1198 T v1=1, w1=k, c1=1, d1=k*k;
1201 T w2 = std::sqrt(v1*w1);
1203 T d2 = (w1*c1+v1*d1)/(v1+w1);
1204 v1=v2; w1=w2; c1=c2; d1=d2;
1205 }
while(std::abs(v1-w1) >= TenEps);
1207 const T K = PiOver2/v1;
1210 return std::make_pair(K,
E);
1239{
return completeEllipticIntegralsKE_T<double>(m); }
1248{
return completeEllipticIntegralsKE_T<float>(m); }
1256{
return completeEllipticIntegralsKE_T<double>((
double)m); }
The purpose of the CNT<T> class is to hide the differences between built-in numerical types and compo...
High precision mathematical and physical constants.
This file contains macros which are convenient to use for sprinkling error checking around liberally ...
#define SimTK_ERRCHK1_ALWAYS(cond, whereChecked, fmt, a1)
Definition ExceptionMacros.h:285
This file contains classes and typedefs needed to provide uniform handling of floating point numeric ...
Mandatory first inclusion for any Simbody source or header file.
SimTK::conjugate<R> should be instantiated only for float, double.
Definition conjugate.h:178
negator<N>, where N is a number type (real, complex, conjugate), is represented in memory identically...
Definition negator.h:75
static const negator< N > & recast(const N &val)
Definition negator.h:235
This file defines the conjugate<R> template class, where R is one of the three built-in real types.
constexpr Real Sqrt2
Real(sqrt(2))
Definition Scalar.h:157
constexpr Real TinyReal
TinyReal is a floating point value smaller than the floating point precision; it is defined as Eps^(5...
Definition Scalar.h:104
constexpr Real LeastPositiveReal
This is the smallest positive real number that can be expressed in the type Real; it is ~1e-308 when ...
Definition Scalar.h:113
constexpr Real Eps
Epsilon is the size of roundoff noise; it is the smallest positive number of default-precision type R...
Definition Scalar.h:94
constexpr Real Log2E
Real(log2(e)) (log base 2)
Definition Scalar.h:155
constexpr Real NaN
This is the IEEE "not a number" constant for this implementation of the default-precision Real type; ...
Definition Scalar.h:85
constexpr Real LeastNegativeReal
This is the largest negative real number (that is, closest to zero) that can be expressed in values o...
Definition Scalar.h:120
constexpr Complex I
We only need one complex constant, i = sqrt(-1). For the rest just multiply the real constant by i,...
Definition Scalar.h:170
constexpr Real MinusOne
Real(-1)
Definition Scalar.h:140
constexpr Real MostPositiveReal
This is the largest finite positive real number that can be expressed in the Real type; ~1e+308 when ...
Definition Scalar.h:117
constexpr Real OneOverPi
1/Real(pi)
Definition Scalar.h:153
constexpr Real OneNinth
Real(1)/9.
Definition Scalar.h:151
constexpr Real Zero
Real(0)
Definition Scalar.h:138
constexpr Real Log10E
Real(log10(e)) (log base 10)
Definition Scalar.h:156
constexpr int LosslessNumDigitsReal
This is the smallest number of decimal digits you should store in a text file if you want to be able ...
Definition Scalar.h:136
constexpr Real OneOverSqrt3
Real(1/sqrt(3))
Definition Scalar.h:160
constexpr Real OneThird
Real(1)/3.
Definition Scalar.h:145
constexpr Real Pi
Real(pi)
Definition Scalar.h:152
constexpr Real Ln2
Real(ln(2)) (natural log of 2)
Definition Scalar.h:163
constexpr Real One
Real(1)
Definition Scalar.h:139
constexpr Real SignificantReal
SignificantReal is the smallest value that we consider to be clearly distinct from roundoff error whe...
Definition Scalar.h:109
constexpr Real MostNegativeReal
This is the smallest finite negative real number that can be expressed in values of type Real....
Definition Scalar.h:124
constexpr Real SqrtEps
This is the square root of Eps, ~1e-8 if Real is double, ~3e-4 if Real is float.
Definition Scalar.h:98
constexpr Real Three
Real(3)
Definition Scalar.h:142
constexpr Real Ln10
Real(ln(10)) (natural log of 10)
Definition Scalar.h:164
constexpr Real CubeRoot3
Real(3^(1/3)) (cube root of 3)
Definition Scalar.h:162
constexpr int NumDigitsReal
This is the number of decimal digits that can be reliably stored and retrieved in the default Real pr...
Definition Scalar.h:129
constexpr Real CubeRoot2
Real(2^(1/3)) (cube root of 2)
Definition Scalar.h:161
constexpr Real E
e = Real(exp(1))
Definition Scalar.h:154
constexpr Real OneHalf
Real(1)/2.
Definition Scalar.h:144
constexpr Real OneSixth
Real(1)/6.
Definition Scalar.h:148
constexpr Real OneOverSqrt2
1/sqrt(2)==sqrt(2)/2 as Real
Definition Scalar.h:158
constexpr Real OneFourth
Real(1)/4.
Definition Scalar.h:146
constexpr Real OneFifth
Real(1)/5.
Definition Scalar.h:147
constexpr Real Sqrt3
Real(sqrt(3))
Definition Scalar.h:159
constexpr Real Infinity
This is the IEEE positive infinity constant for this implementation of the default-precision Real typ...
Definition Scalar.h:89
constexpr Real OneSeventh
Real(1)/7.
Definition Scalar.h:149
constexpr Real OneEighth
Real(1)/8.
Definition Scalar.h:150
constexpr Real Two
Real(2)
Definition Scalar.h:141
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition Assembler.h:37
double stepUp(double x)
Interpolate smoothly from 0 up to 1 as the input argument goes from 0 to 1, with first and second der...
Definition Scalar.h:767
std::complex< Real > Complex
This is the default complex type for SimTK, with precision for the real and imaginary parts set to th...
Definition SimTKcommon/include/SimTKcommon/internal/common.h:629
double stepDown(double x)
Interpolate smoothly from 1 down to 0 as the input argument goes from 0 to 1, with first and second d...
Definition Scalar.h:786
double d3stepAny(double yRange, double x0, double oneOverXRange, double x)
Third derivative of stepAny(): d^3/dx^3 stepAny(x).
Definition Scalar.h:939
double d2stepDown(double x)
Second derivative of stepDown(): d^2/dx^2 stepDown(x).
Definition Scalar.h:909
double dstepAny(double yRange, double x0, double oneOverXRange, double x)
First derivative of stepAny(): d/dx stepAny(x).
Definition Scalar.h:889
double d2stepUp(double x)
Second derivative of stepUp(): d^2/dx^2 stepUp(x).
Definition Scalar.h:901
double dstepDown(double x)
First derivative of stepDown(): d/dx stepDown(x).
Definition Scalar.h:884
double dstepUp(double x)
First derivative of stepUp(): d/dx stepUp(x).
Definition Scalar.h:875
double & clampInPlace(double low, double &v, double high)
Check that low <= v <= high and modify v in place if necessary to bring it into that range.
Definition Scalar.h:523
double d2stepAny(double yRange, double x0, double oneOverXRange, double x)
Second derivative of stepAny(): d^2/dx^2 stepAny(x).
Definition Scalar.h:914
unsigned int sign(unsigned char u)
Definition Scalar.h:301
double d3stepDown(double x)
Third derivative of stepDown(): d^3/dx^3 stepDown(x).
Definition Scalar.h:934
const float & real(const conjugate< float > &c)
Definition conjugate.h:482
conjugate< Real > Conjugate
Definition Scalar.h:55
bool atMostOneBitIsSet(unsigned char v)
Definition Scalar.h:193
std::pair< double, double > completeEllipticIntegralsKE(double m)
Given 0<=m<=1, return complete elliptic integrals of the first and second kinds, K(m) and E(m),...
Definition Scalar.h:1238
unsigned char square(unsigned char u)
Definition Scalar.h:339
double stepAny(double y0, double yRange, double x0, double oneOverXRange, double x)
Interpolate smoothly from y0 to y1 as the input argument goes from x0 to x1, with first and second de...
Definition Scalar.h:863
bool exactlyOneBitIsSet(unsigned char v)
Definition Scalar.h:220
SimTK_Real Real
This is the default compiled-in floating point type for SimTK, either float or double.
Definition SimTKcommon/include/SimTKcommon/internal/common.h:626
std::pair< double, double > approxCompleteEllipticIntegralsKE(double m)
Given 0<=m<=1, return complete elliptic integrals of the first and second kinds, K(m) and E(m),...
Definition Scalar.h:1159
double clamp(double low, double v, double high)
If v is in range low <= v <= high then return v, otherwise return the nearest bound; this function do...
Definition Scalar.h:624
const negator< float > & imag(const conjugate< float > &c)
Definition conjugate.h:483
double d3stepUp(double x)
Third derivative of stepUp(): d^3/dx^3 stepUp(x).
Definition Scalar.h:926
bool signBit(unsigned char u)
Definition Scalar.h:260
unsigned char cube(unsigned char u)
Definition Scalar.h:410
This file defines the negator<N> template which is an adaptor for the numeric types N (Real,...