00001
00002
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 #ifndef __cmtkMathUtil_h_included_
00034 #define __cmtkMathUtil_h_included_
00035
00036 #include <cmtkconfig.h>
00037
00038 #include <Base/cmtkUnits.h>
00039 #include <Base/cmtkMatrix.h>
00040
00041 #ifdef HAVE_STDINT_H
00042 # include <stdint.h>
00043 #else
00044 # ifdef _MSC_VER
00045 typedef unsigned int uint32_t;
00046 # endif // _MSC_VER
00047 #endif
00048
00049 #include <algorithm>
00050 #include <cfloat>
00051 #include <math.h>
00052 #include <stdlib.h>
00053
00054 #ifndef M_PI
00055 #define M_PI 3.14159265358979323846
00056 #endif
00057
00058 #ifdef _MSC_VER
00059
00060 #define M_E 2.7182818284590452354
00061 #define M_LOG2E 1.4426950408889634074
00062 #define M_LOG10E 0.43429448190325182765
00063 #define M_LN2 0.69314718055994530942
00064 #define M_LN10 2.30258509299404568402
00065 #define M_PI_2 1.57079632679489661923
00066 #define M_PI_4 0.78539816339744830962
00067 #define M_1_PI 0.31830988618379067154
00068 #define M_2_PI 0.63661977236758134308
00069 #define M_2_SQRTPI 1.12837916709551257390
00070 #define M_SQRT2 1.41421356237309504880
00071 #define M_SQRT1_2 0.70710678118654752440
00072 #endif
00073
00074 namespace
00075 cmtk
00076 {
00077
00080
00083 class MathUtil
00084 {
00085 private:
00087 typedef MathUtil Self;
00088
00089 public:
00091 template<class T>
00092 static bool IsNaN( const T value )
00093 {
00094 return isnan( value );
00095 }
00096
00098 static double GetDoubleNaN()
00099 {
00100 return Self::GetInternalNaN().m_Union.d;
00101 }
00102
00104 static float GetFloatNaN()
00105 {
00106 #if WORDS_BIGENDIAN
00107 return Self::GetInternalNaN().m_Union.f[0];
00108 #else
00109 return Self::GetInternalNaN().m_Union.f[1];
00110 #endif
00111 }
00112
00114 static double GetDoubleInf()
00115 {
00116 return Self::GetInternalInf().m_Union.d;
00117 }
00118
00120 static float GetFloatInf()
00121 {
00122 #if WORDS_BIGENDIAN
00123 return Self::GetInternalInf().m_Union.f[0];
00124 #else
00125 return Self::GetInternalInf().m_Union.f[1];
00126 #endif
00127 }
00128
00130 static double Sin( const Units::Radians& radians )
00131 {
00132 return sin( radians.Value() );
00133 }
00134
00136 static double Cos( const Units::Radians& radians )
00137 {
00138 return cos( radians.Value() );
00139 }
00140
00142 static double Tan( const Units::Radians& radians )
00143 {
00144 return tan( radians.Value() );
00145 }
00146
00148 static const Units::Radians ArcSin( const double value )
00149 {
00150 return Units::Radians( asin( value ) );
00151 }
00152
00154 static const Units::Radians ArcCos( const double value )
00155 {
00156 return Units::Radians( acos( value ) );
00157 }
00158
00160 static const Units::Radians ArcTan( const double value )
00161 {
00162 return Units::Radians( atan( value ) );
00163 }
00164
00166 static const Units::Radians ArcTan2( const double y, const double x )
00167 {
00168 return Units::Radians( atan2( y, x ) );
00169 }
00170
00172 template<class T> static T Square ( const T a) { return a*a; }
00173
00176 template<class T> static T Min ( const int nValues, const T* Values )
00177 {
00178 T Result = Values[0];
00179 for ( int idx=1; idx<nValues; ++idx )
00180 Result = std::min( Result, Values[idx] );
00181
00182 return Result;
00183 }
00184
00187 template<class T> static T Max ( const int nValues, const T* Values )
00188 {
00189 T Result = Values[0];
00190 for ( int idx=1; idx<nValues; ++idx )
00191 Result = std::max( Result, Values[idx] );
00192
00193 return Result;
00194 }
00195
00197 template<class T> static T Intersect ( const T aMin, const T aMax, const T bMin, const T bMax )
00198 {
00199 return ( std::min( aMax, bMax ) - std::max( aMin, bMin ) );
00200 }
00201
00203 template<class T> static int Round ( const T a ) { return (int)floor(a+0.5); }
00204
00208 template<class T> static int Sign ( const T a ) { return (a<0)?-1:((a==0)?0:1); }
00209
00214 template<class T> static int CheckRange ( const T value, const T a, const T b )
00215 {
00216 const int sigA = Self::Sign(value-a);
00217 return (sigA == Self::Sign(value-b))?sigA:0;
00218 }
00219
00221 template<class T> static double plogp( const T p ) { return (p>0) ? p * log( p ) : 0.0; }
00222
00225 template<class T> static
00226 T Mean
00227 ( const unsigned int nValues, const T* values );
00228
00231 template<class T> static
00232 T Mean
00233 ( const std::vector<T>& values );
00234
00242 template<class T> static
00243 T Variance
00244 ( const unsigned int nValues, const T* values, T mean, const bool unbiased = false );
00245
00252 template<class T> static
00253 T Variance
00254 ( const std::vector<T>& values, T mean, const bool unbiased = false );
00255
00258 template<class T> static
00259 T Correlation( const std::vector<T>& x, const std::vector<T>& y );
00260
00262 static double TStatFromCorrelation
00263 ( const double r,
00264 const size_t df
00265 );
00266
00268 static double ProbabilityFromTStat
00269 ( const double t,
00270 const size_t df
00271 );
00272
00275 template<class T> static
00276 T TTest ( const std::vector<T>& valuesX, const std::vector<T>& valuesY, T& t );
00277
00281 template<class T> static
00282 T TTest ( const std::vector<T>& valuesX, const std::vector<T>& valuesY, T& t, T& avgX, T& avgY );
00283
00287 template<class T> static
00288 T PairedTTest ( const std::vector<T>& valuesX, const std::vector<T>& valuesY, T& t, T& avgX, T& avgY );
00289
00293 template<class T> static
00294 T TTest ( const std::vector<T>& valuesX, T& t, T& avgX );
00295
00297 static double Betai( const double a, const double b, const double x );
00298
00300 static double BetaCf( const double a, const double b, const double x );
00301
00303 static double GammaLn( const double xx );
00304
00306 static void SVD( Matrix2D<double> *U, size_t m, size_t n, std::vector<double> *W, Matrix2D<double> *V );
00307
00309 static void
00310 SVDLinearRegression( Matrix2D<double> *U, size_t m, size_t n, std::vector<double> *W, Matrix2D<double> *V, double *b, std::vector<double>& lm_params );
00311
00313 static inline int CompareFloat( const void *a, const void *b )
00314 {
00315 const float* A = static_cast<const float*>( a );
00316 const float* B = static_cast<const float*>( b );
00317 if ( *A > *B ) return +1;
00318 if ( *A < *B ) return -11;
00319 return 0;
00320 }
00321
00323 static inline int CompareDouble( const void *a, const void *b )
00324 {
00325 const double* A = static_cast<const double*>( a );
00326 const double* B = static_cast<const double*>( b );
00327 if ( *A > *B ) return +1;
00328 if ( *A < *B ) return -11;
00329 return 0;
00330 }
00331
00341 static inline double NormalRandom( const double sigma )
00342 {
00343 static bool secondNumberReady = false;
00344 static double secondNumber = 0;
00345
00346 if ( secondNumberReady ) {
00347 secondNumberReady = false;
00348 return secondNumber;
00349 }
00350
00351 double x1, x2, w;
00352 do {
00353 x1 = 2.0 * (random()&0xffffff)/0x1000000 - 1.0;
00354 x2 = 2.0 * (random()&0xffffff)/0x1000000 - 1.0;
00355 w = x1 * x1 + x2 * x2;
00356 } while ( w >= 1.0 );
00357
00358 w = sqrt( (-2.0 * log( w ) ) / w );
00359 secondNumber = x1 * w * sigma;
00360 return x2 * w * sigma;
00361 }
00362
00367 static inline double NormalRandom( const double sigma, const unsigned int seed )
00368 {
00369 srandom( seed );
00370 return NormalRandom( sigma );
00371 }
00372
00374 static double UniformRandom();
00375
00377 template<class T> static void ComputeEigensystem( const Matrix2D<T>& matrix, Matrix2D<T>& eigensystem, std::vector<T>& eigenvalues );
00378
00380 template<class T> static void ComputeEigenvalues( const Matrix2D<T>& matrix, std::vector<T>& eigenvalues );
00381
00383 template<class T> static T CholeskyDeterminant( const Matrix2D<T>& matrix, int n);
00384
00385 private:
00387 class BitInitializer
00388 {
00389 public:
00391 typedef union
00392 {
00394 uint32_t i[2];
00396 float f[2];
00398 double d;
00399 } InitializeUnion;
00400
00402 InitializeUnion m_Union;
00403
00404 public:
00406 BitInitializer( const uint32_t i0, const uint32_t i1 )
00407 {
00408 this->m_Union.i[0] = i0;
00409 this->m_Union.i[1] = i1;
00410 }
00411 };
00412
00414 static const Self::BitInitializer& GetInternalNaN()
00415 {
00416 #if WORDS_BIGENDIAN
00417 static const Self::BitInitializer bits( 0x7fffffff, 0xffffffff );
00418 #else
00419 static const Self::BitInitializer bits( 0xffffffff, 0x7fffffff );
00420 #endif
00421 return bits;
00422 }
00423
00425 static const Self::BitInitializer& GetInternalInf()
00426 {
00427 #if WORDS_BIGENDIAN
00428 static const Self::BitInitializer bits( 0x7f800000, 0x00000000 );
00429 #else
00430 static const Self::BitInitializer bits( 0x00000000, 0x7f800000 );
00431 #endif
00432 return bits;
00433 }
00434 };
00435
00437
00438 }
00439
00440 #include "cmtkMathUtil_Statistics.txx"
00441
00442 #endif // #ifndef __cmtkMathUtil_h_included_