00001 00012 #ifdef HAVE_CONFIG_H 00013 #include "config.h" 00014 #else 00015 #ifdef _MSC_VER 00016 #include "msdevstudio/MSconfig.h" 00017 #endif 00018 #endif 00019 00020 #include "Gaussian.h" 00021 00022 #include "FunctionHelper.h" 00023 00024 #include <cmath> 00025 #include <cassert> 00026 00027 using std::distance; 00028 00029 #ifdef ITERATOR_MEMBER_DEFECT 00030 using namespace std; 00031 #else 00032 using std::exp; 00033 using std::vector; 00034 #endif 00035 00036 namespace { 00039 enum { norm = 0, mean = 1, sigma = 2 }; 00040 } 00041 00042 Gaussian::Gaussian ( ) 00043 { 00044 initialize (); 00045 } 00046 00047 Gaussian::Gaussian ( double n, double m, double s ) 00048 { 00049 initialize (); 00050 00051 m_parms[norm] = n; 00052 m_parms[mean] = m; 00053 m_parms[sigma] = s; 00054 } 00055 00056 void Gaussian::initialize () 00057 { 00058 m_name = "Gaussian"; 00059 00060 m_parm_names.push_back ( "Norm" ); 00061 m_parm_names.push_back ( "Mean" ); 00062 m_parm_names.push_back ( "Sigma" ); 00063 00064 resize (); 00065 } 00066 00067 FunctionBase * Gaussian::clone () const 00068 { 00069 return new Gaussian ( *this ); 00070 } 00071 00072 double Gaussian::operator () ( double x ) const 00073 { 00074 double value = 0.0; 00075 if ( m_parms[sigma] != 0.0 ) { 00076 double t = ( x - m_parms[mean] ) / m_parms[sigma]; 00077 t = 0.5 * t*t; 00078 if ( fabs ( t ) < 50.0 ) { 00079 value = exp ( -t ) / ( 2.50662828 * m_parms[sigma] ); 00080 } 00081 } // sigma == 0. 00082 else { 00083 if ( x == m_parms[mean] ) value = 1.0; 00084 } 00085 return value * m_parms[norm]; 00086 } 00087 00088 /* virtual */ 00089 void 00090 Gaussian:: 00091 initialParameters ( const FunctionHelper * helper ) 00092 { 00093 double min_x = helper->minCoord (); 00094 double max_x = helper->maxCoord (); 00095 int size = helper->size(); 00096 double total = helper->getTotal (); 00097 00098 m_parms[norm] = total * ( max_x - min_x ) / size; 00099 m_parms[mean] = helper->meanCoord (); 00100 m_parms[sigma] = helper->stdCoord (); 00101 } 00102 00103 double Gaussian::derivByParm ( int i, double x ) const 00104 { 00105 switch ( i ) { 00106 case norm : 00107 return derivByNorm ( x ); 00108 break; 00109 00110 case mean : 00111 return derivByMean ( x ); 00112 break; 00113 00114 case sigma : 00115 return derivBySigma ( x ); 00116 break; 00117 00118 default : 00119 assert ( false ); 00120 break; 00121 } 00122 return 0.0; 00123 } 00124 00125 double Gaussian::derivByNorm ( double x ) const 00126 { 00127 if ( m_parms[sigma] != 0.0 ) { 00128 double t = ( x - m_parms[mean] ) / m_parms[sigma]; 00129 t = 0.5 * t*t; 00130 if ( fabs ( t ) > 50.0 ) { 00131 return 0.0; 00132 } 00133 else { 00134 return exp ( -t ) / ( 2.50662828 * m_parms[sigma] ); 00135 } 00136 } // sigma == 0.0 00137 else { 00138 if ( x != m_parms[mean] ) { 00139 return 0.0; 00140 } else { 00141 return 1.0; 00142 } 00143 } 00144 } 00145 00146 double Gaussian::derivByMean ( double x ) const 00147 { 00148 double dx = x - m_parms[mean]; 00149 if ( m_parms[sigma] != 0.0 ) { 00150 return m_parms[norm] * dx 00151 * exp ( -dx*dx / ( 2.0 * m_parms[sigma] * m_parms[sigma] ) ) 00152 / ( 2.50662828 * m_parms[sigma] * m_parms[sigma] * m_parms[sigma] ); 00153 } 00154 else { 00155 if ( x != m_parms[mean] ) return 0.0; 00156 else return 1.0; 00157 } 00158 } 00159 00160 double Gaussian::derivBySigma ( double x ) const 00161 { 00162 if ( m_parms[sigma] == 0.0 ) return 0.0; 00163 double dx = x - m_parms[mean]; 00164 double p2 = m_parms[sigma] * m_parms[sigma]; 00165 double ex = exp ( -dx*dx / ( 2.0 * p2 ) ); 00166 return m_parms[norm] * ( dx*dx * ex / ( p2*p2) - ex / p2 ) / 2.50662828; 00167 }