CLAM_Math.hxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef __CLAM_MATH__
00023 #define __CLAM_MATH__
00024
00025 #include <cmath>
00026 #include "DataTypes.hxx"
00027 #include "FastRounding.hxx"
00028
00029
00030
00031
00032 const float PI_ = 3.1415926535897932384626433832795028841972;
00033 const float ONE_OVER_PI = (0.3183098861837906661338147750939f);
00034 const float TWOPI = (6.2831853071795864769252867665590057683943f);
00035 const float ONE_OVER_TWOPI = (0.15915494309189535682609381638f);
00036 const float PI_2 = (1.5707963267948966192313216916397514420986f);
00037 const float TWO_OVER_PI = (0.636619772367581332267629550188f);
00038 const float LN2 = (0.6931471805599453094172321214581765680755f);
00039 const float ONE_OVER_LN2 = (1.44269504088896333066907387547f);
00040 const float LN10 = (2.3025850929940456840179914546843642076011f);
00041 const float ONE_OVER_LN10 = (0.43429448190325177635683940025f);
00042 const float LN2_OVER_LN10 = LN2*ONE_OVER_LN10;
00043 const float TIMES20LN2_OVER_LN10 = 20*LN2_OVER_LN10;
00044 const long LONG_OFFSET = 4096L;
00045 const float FLOAT_OFFSET = 4096.0;
00046 const float HUGE_ = 1.0e8;
00047 const float ROOT2 = (1.4142135623730950488016887242096980785697f);
00048
00050 inline float CLAM_sin(register float x)
00051 {
00052 #ifndef CLAM_OPTIMIZE
00053 return (float) sin((double)x);
00054 #else
00055 x *= ONE_OVER_PI;
00056 register float accumulator, xPower, xSquared;
00057 register long evenIntPart = ((long)(0.5f*x + 1024.5) - 1024)<<1;
00058 x -= (float)evenIntPart;
00059 xSquared = x*x;
00060 accumulator = 3.14159265358979f*x;
00061 xPower = xSquared*x;
00062 accumulator += -5.16731953364340f*xPower;
00063 xPower *= xSquared;
00064 accumulator += 2.54620566822659f*xPower;
00065 xPower *= xSquared;
00066 accumulator += -0.586027023087261f*xPower;
00067 xPower *= xSquared;
00068 accumulator += 0.06554823491427f*xPower;
00069 return accumulator;
00070 #endif
00071 }
00072
00073 inline float CLAM_cos(register float x)
00074 {
00075 #ifndef CLAM_OPTIMIZE
00076 return (float) cos((double)x);
00077 #else
00078 x *= ONE_OVER_PI;
00079 register float accumulator, xPower, xSquared;
00080
00081 register long evenIntPart = ((long)(0.5f*x + 1024.5f) - 1024)<<1;
00082 x -= (float)evenIntPart;
00083
00084 xSquared = x*x;
00085 accumulator = 1.57079632679490f*x;
00086 xPower = xSquared*x;
00087 accumulator += -0.64596406188166f*xPower;
00088 xPower *= xSquared;
00089 accumulator += 0.07969158490912f*xPower;
00090 xPower *= xSquared;
00091 accumulator += -0.00467687997706f*xPower;
00092 xPower *= xSquared;
00093 accumulator += 0.00015303015470f*xPower;
00094 return 1.0f - 2.0f*accumulator*accumulator;
00095 #endif
00096 }
00097
00098 inline float CLAM_atan(register float x)
00099 {
00100 #ifndef CLAM_OPTIMIZE
00101 return (float) atan((double)x);
00102 #else
00103 register float accumulator, xPower, xSquared, offset;
00104
00105 offset = 0.0f;
00106
00107 if (x < -1.0f)
00108 {
00109 offset = -PI_2;
00110 x = -1.0f/x;
00111 }
00112 else if (x > 1.0f)
00113 {
00114 offset = PI_2;
00115 x = -1.0f/x;
00116 }
00117 xSquared = x*x;
00118 accumulator = 1.0f;
00119 xPower = xSquared;
00120 accumulator += 0.33288950512027f*xPower;
00121 xPower *= xSquared;
00122 accumulator += -0.08467922817644f*xPower;
00123 xPower *= xSquared;
00124 accumulator += 0.03252232640125f*xPower;
00125 xPower *= xSquared;
00126 accumulator += -0.00749305860992f*xPower;
00127
00128 return offset + x/accumulator;
00129 #endif
00130 }
00131
00132 inline float CLAM_atan2(float Imag, float Real)
00133 {
00134 #ifndef CLAM_OPTIMIZE
00135 return (float) atan2((double)Imag, (double)Real);
00136 #else
00137 if(Real==0 && Imag==0) return 0.f;
00138 register float accumulator, xPower, xSquared, offset, x;
00139
00140 if (Imag > 0.0f)
00141 {
00142 if (Imag <= -Real)
00143 {
00144 offset = PI_;
00145 x = Imag/Real;
00146 }
00147 else if (Imag > Real)
00148 {
00149 offset = PI_2;
00150 x = -Real/Imag;
00151 }
00152 else
00153 {
00154 offset = 0.0f;
00155 x = Imag/Real;
00156 }
00157 }
00158 else
00159 {
00160 if (Imag >= Real)
00161 {
00162 offset = -PI_;
00163 x = Imag/Real;
00164 }
00165 else if (Imag < -Real)
00166 {
00167 offset = -PI_2;
00168 x = -Real/Imag;
00169 }
00170 else
00171 {
00172 offset = 0.0f;
00173 x = Imag/Real;
00174 }
00175 }
00176
00177 xSquared = x*x;
00178 accumulator = 1.0f;
00179 xPower = xSquared;
00180 accumulator += 0.33288950512027f*xPower;
00181 xPower *= xSquared;
00182 accumulator += -0.08467922817644f*xPower;
00183 xPower *= xSquared;
00184 accumulator += 0.03252232640125f*xPower;
00185 xPower *= xSquared;
00186 accumulator += -0.00749305860992f*xPower;
00187
00188 return offset + x/accumulator;
00189 #endif
00190 }
00191
00192 inline float CLAM_exp2(register float x)
00193 {
00194 #ifndef CLAM_OPTIMIZE
00195 return (float) exp(LN2*(double)x);
00196 #else
00197 if (x >= -127.0f)
00198 {
00199 register float accumulator, xPower;
00200 register union {float f; long i;} xBits;
00201
00202 xBits.i = (long)(x + FLOAT_OFFSET) - LONG_OFFSET;
00203 x -= (float)(xBits.i);
00204
00205 accumulator = 1.0f + 0.69303212081966f*x;
00206 xPower = x*x;
00207 accumulator += 0.24137976293709f*xPower;
00208 xPower *= x;
00209 accumulator += 0.05203236900844f*xPower;
00210 xPower *= x;
00211 accumulator += 0.01355574723481f*xPower;
00212
00213 xBits.i += 127;
00214 xBits.i <<= 23;
00215
00216 return accumulator * xBits.f;
00217 }
00218 else
00219 {
00220 return 0.0f;
00221 }
00222 #endif
00223 }
00224
00225 inline float CLAM_log2(register float x)
00226 {
00227 #ifndef CLAM_OPTIMIZE
00228 return (float) (ONE_OVER_LN2*log((double)x));
00229 #else
00230 if (x > 5.877471754e-39f)
00231 {
00232 register float accumulator, xPower;
00233 register long intPart;
00234
00235 register union {float f; long i;} xBits;
00236
00237 xBits.f = x;
00238
00239 intPart = ((xBits.i)>>23);
00240 intPart -= 127;
00241
00242 x = (float)(xBits.i & 0x007FFFFF);
00243 x *= 1.192092895507812e-07f;
00244
00245 accumulator = 1.44254494359510f*x;
00246 xPower = x*x;
00247 accumulator += -0.71814525675041f*xPower;
00248 xPower *= x;
00249 accumulator += 0.45754919692582f*xPower;
00250 xPower *= x;
00251 accumulator += -0.27790534462866f*xPower;
00252 xPower *= x;
00253 accumulator += 0.12179791068782f*xPower;
00254 xPower *= x;
00255 accumulator += -0.02584144982967f*xPower;
00256
00257 return accumulator + (float)intPart;
00258 }
00259 else
00260 {
00261 return -HUGE_;
00262 }
00263 #endif
00264 }
00265
00266 inline float CLAM_pow(float x, float y)
00267 {
00268 #ifndef CLAM_OPTIMIZE
00269 return (float) pow((double)x, (double)y);
00270 #else
00271 return CLAM_exp2(y*CLAM_log2(x));
00272 #endif
00273 }
00274
00275 inline float CLAM_sqrt(register float x)
00276 {
00277 #ifndef CLAM_OPTIMIZE
00278 return (float) sqrt((double)x);
00279 #else
00280 if (x > 5.877471754e-39f)
00281 {
00282 register float accumulator, xPower;
00283 register long intPart;
00284 register union {float f; long i;} xBits;
00285
00286 xBits.f = x;
00287
00288 intPart = ((xBits.i)>>23);
00289 intPart -= 127;
00290
00291 x = (float)(xBits.i & 0x007FFFFF);
00292 x *= 1.192092895507812e-07f;
00293
00294 accumulator = 1.0f + 0.49959804148061f*x;
00295 xPower = x*x;
00296 accumulator += -0.12047308243453f*xPower;
00297 xPower *= x;
00298 accumulator += 0.04585425015501f*xPower;
00299 xPower *= x;
00300 accumulator += -0.01076564682800f*xPower;
00301
00302 if (intPart & 0x00000001)
00303 {
00304 accumulator *= ROOT2;
00305 }
00306
00307 xBits.i = intPart >> 1;
00308 xBits.i += 127;
00309 xBits.i <<= 23;
00310
00311 return accumulator * xBits.f;
00312 }
00313 else
00314 {
00315 return 0.0f;
00316 }
00317 #endif
00318 }
00319
00320 inline float CLAM_log(register float x)
00321 {
00322 #ifndef CLAM_OPTIMIZE
00323 return (float) log((double)x);
00324 #else
00325 return LN2*CLAM_log2(x);
00326 #endif
00327 }
00328
00329 inline float CLAM_log10(register float x)
00330 {
00331 #ifndef CLAM_OPTIMIZE
00332 return (float) log10((double)x);
00333 #else
00334 return LN2_OVER_LN10*CLAM_log2(x);
00335 #endif
00336 }
00337
00338 inline float CLAM_20log10(register float x)
00339 {
00340 #ifndef CLAM_OPTIMIZE
00341 return (float) 20*log10((double)x);
00342 #else
00343 return TIMES20LN2_OVER_LN10*CLAM_log2(x);
00344 #endif
00345 }
00346
00347 inline float CLAM_exp(register float x)
00348 {
00349 #ifndef CLAM_OPTIMIZE
00350 return (float) exp((double)x);
00351 #else
00352 return CLAM_exp2(ONE_OVER_LN2*x);
00353 #endif
00354 }
00355
00356 #if defined _MSC_VER && _MSC_VER < 1310 // MSVC++ 6
00357 #undef min
00358 #undef max
00359 namespace std
00360 {
00361 template < typename T >
00362 const T& max( const T& a, const T& b) {
00363 return (a>=b)? a : b;
00364 }
00365 template < typename T >
00366 const T& min(const T& a, const T& b) {
00367 return (a<=b)? a : b;
00368 }
00369 }
00370 #endif // MSVC++ 6
00371
00372 #if defined _MSC_VER // MSVC++7
00373 namespace std
00374 {
00375 template <typename T>
00376 bool isnan(T data)
00377 {
00378 return _isnan(data) == 1;
00379 }
00380 template <typename T>
00381 bool isinf(T data)
00382 {
00383 return _isnan(data) == 1;
00384 }
00385 }
00386 #endif // MSVC++ 7
00387
00388 #ifndef __USE_ISOC99
00389 #ifndef __APPLE__
00390 inline double round(double _X)
00391 {return (floor(_X+0.5)); }
00392 inline float round(float _X)
00393 {return (floorf(_X+0.5f)); }
00394 #endif // __APPLE__
00395 #endif // __USE_ISOC99
00396
00397
00400 inline float log2lin( float x )
00401 {
00402
00403
00404
00405 return CLAM_exp( x * 0.1151292546497f );
00406
00407 }
00408
00414 inline bool isPowerOfTwo( CLAM::TUInt32 n)
00415 {
00416 return (((n - 1) & n) == 0);
00417 }
00418
00424 inline CLAM::TUInt32 nextPowerOfTwo( CLAM::TUInt32 n)
00425 {
00426 --n;
00427
00428 n |= n >> 16;
00429 n |= n >> 8;
00430 n |= n >> 4;
00431 n |= n >> 2;
00432 n |= n >> 1;
00433 ++n;
00434
00435 return n;
00436 }
00437
00438 namespace CLAM
00439 {
00440
00441
00442 template <class T> inline T Abs(T value)
00443 {
00444 return ( value < 0 ) ? -value : value;
00445 }
00446
00447
00448
00449
00450 #define CLAM_DB_SCALING 20
00451
00452 inline double DB(double linData, int scaling=20)
00453 {
00454 return (scaling*CLAM_log10(linData));
00455 }
00456
00457 inline double Lin(double logData, int scaling=20 )
00458 {
00459 return (CLAM_pow(double(10),(logData/scaling)) );
00460 }
00461
00466 template<class T> inline
00467 T CLAM_max(const T& x, const T& y)
00468 {return (x < y ? y : x); }
00469
00470 template<class T> inline
00471 T CLAM_min(const T& x, const T& y)
00472 {return (x > y ? y : x); }
00473 }
00474
00475 #endif // CLAM_Math.hxx
00476