00001
00009 #ifdef HAVE_CONFIG_H
00010 #include "config.h"
00011 #else
00012 #ifdef _MSC_VER
00013 #include "msdevstudio/MSconfig.h"
00014 #endif
00015 #endif
00016
00017 #include "Erfc.h"
00018 #include "FunctionHelper.h"
00019
00020 #include <cmath>
00021
00022 #include <cassert>
00023
00024 #ifdef ITERATOR_MEMBER_DEFECT
00025 using namespace std;
00026 #else
00027 using std::exp;
00028 using std::vector;
00029 #endif
00030
00031 Erfc::Erfc ( )
00032 {
00033 initialize ();
00034 }
00035
00036 Erfc::Erfc(double m, double s, double n)
00037 {
00038 initialize();
00039
00040 m_parms[MEAN] = m;
00041 m_parms[SIGMA] = s;
00042 m_parms[NORM] = n;
00043 }
00044
00045 void Erfc::initialize ()
00046 {
00047 m_name = "Erfc";
00048
00049 m_parm_names.push_back ( "Mean" );
00050 m_parm_names.push_back ( "Sigma" );
00051 m_parm_names.push_back ( "Normalization" );
00052
00053 resize ();
00054 }
00055
00056 FunctionBase * Erfc::clone () const
00057 {
00058 return new Erfc ( *this );
00059 }
00060
00063 double Erfc::operator () (double value) const
00064 {
00065 double result = 1;
00066
00067 double x = calcRed(value);
00068
00069 result = calcErfc(x);
00070
00071 result *= m_parms[NORM];
00072
00073 return result;
00074 }
00075
00076
00077
00078 void Erfc::initialParameters ( const FunctionHelper * helper )
00079 {
00080 m_parms[MEAN] = helper->meanCoord();
00081 m_parms[SIGMA] = 1;
00082 m_parms[NORM] = helper->maxValue () / 2;
00083 }
00084
00085
00086 double Erfc::derivByParm ( int i, double value ) const
00087 {
00088 double result = 0;
00089
00090 switch ( i ) {
00091 case MEAN :
00092 result = -1.0/m_parms[SIGMA] * m_parms[NORM] * derivByRed ( calcRed(value) );
00093 return result;
00094 break;
00095
00096 case SIGMA :
00097 result = - calcRed(value)/m_parms[SIGMA] * m_parms[NORM] * derivByRed ( calcRed(value) );
00098 return result;
00099 break;
00100
00101 case NORM :
00102 result = operator () ( value ) / m_parms[NORM];
00103 return result;
00104 break;
00105
00106 default :
00107 assert ( false );
00108 break;
00109 }
00110
00111 return 0.0;
00112 }
00113
00114
00115
00116 double Erfc::derivByRed( const double x ) const
00117 {
00118
00119 static const double m_2_sqrtpi = 1.12837916709551257390;
00120
00121 double result = - m_2_sqrtpi;
00122
00123 result *= exp(-x*x);
00124 return result;
00125 }
00126
00127
00128
00129 double Erfc::calcErfc(double x) const
00130 {
00131
00132
00133
00134
00135
00136
00137 const double
00138 a1 = -1.26551223, a2 = 1.00002368,
00139 a3 = 0.37409196, a4 = 0.09678418,
00140 a5 = -0.18628806, a6 = 0.27886807,
00141 a7 = -1.13520398, a8 = 1.48851587,
00142 a9 = -0.82215223, a10 = 0.17087277;
00143
00144 double v = 1;
00145
00146 double z = x>=0 ? x : -x;
00147
00148 if (z <= 0) return v;
00149
00150 double t = 1/(1+0.5*z);
00151
00152 v = t*exp((-z*z) +a1+t*(a2+t*(a3+t*(a4+t*(a5+t*(a6+t*(a7+t*(a8+t*(a9+t*a10)))))))));
00153
00154 if (x < 0) v = 2-v;
00155
00156 return v;
00157 }
00158