cmtkMathUtil.h

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 1997-2009 Torsten Rohlfing
00004 //
00005 //  Copyright 2004-2011 SRI International
00006 //
00007 //  This file is part of the Computational Morphometry Toolkit.
00008 //
00009 //  http://www.nitrc.org/projects/cmtk/
00010 //
00011 //  The Computational Morphometry Toolkit is free software: you can
00012 //  redistribute it and/or modify it under the terms of the GNU General Public
00013 //  License as published by the Free Software Foundation, either version 3 of
00014 //  the License, or (at your option) any later version.
00015 //
00016 //  The Computational Morphometry Toolkit is distributed in the hope that it
00017 //  will be useful, but WITHOUT ANY WARRANTY; without even the implied
00018 //  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 //  GNU General Public License for more details.
00020 //
00021 //  You should have received a copy of the GNU General Public License along
00022 //  with the Computational Morphometry Toolkit.  If not, see
00023 //  <http://www.gnu.org/licenses/>.
00024 //
00025 //  $Revision: 2752 $
00026 //
00027 //  $LastChangedDate: 2011-01-17 11:33:31 -0800 (Mon, 17 Jan 2011) $
00028 //
00029 //  $LastChangedBy: torstenrohlfing $
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 /* Some useful constants taken from SGI's math.h */
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 } // namespace cmtk
00439 
00440 #include "cmtkMathUtil_Statistics.txx"
00441 
00442 #endif // #ifndef __cmtkMathUtil_h_included_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines