00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #if defined(_WIN32) || defined(_WIN64)
00018 #include <spl/configwin32.h>
00019 #else
00020 #include <spl/autoconf/config.h>
00021 #endif
00022
00023 #include <spl/io/Directory.h>
00024 #include <sys/types.h>
00025
00026 #include <math.h>
00027 #ifdef HAVE_FLOAT_H
00028 #include <float.h>
00029 #endif
00030 #ifdef HAVE_LIMITS_H
00031 #include <limits.h>
00032 #endif
00033
00034 #include <spl/Debug.h>
00035 #include <spl/math/Math.h>
00036 #include <spl/math/Sample.h>
00037 #include <spl/math/SampleTest.h>
00038
00039
00040
00041
00042 static void _ArrayInsert(double *a, const int alen, const double d)
00043 {
00044 for (int x = alen - 2; x >= 0; x--)
00045 {
00046 if( d > a[x] )
00047 {
00048
00049 a[x + 1] = a[x];
00050 }
00051 else
00052 {
00053
00054 a[x + 1] = d;
00055 return;
00056 }
00057 }
00058
00059 a[0] = d;
00060 }
00061
00062 void Sample::Recalc()
00063 {
00064 double sum = 0;
00065 int x;
00066
00067 for (x = 0; x < m_n; x++)
00068 {
00069 double val = m_data[x];
00070 if (val < m_min)
00071 {
00072 m_min = val;
00073 }
00074 if (val > m_max)
00075 {
00076 m_max = val;
00077 }
00078 sum += val;
00079 }
00080 m_mean = sum / m_n;
00081
00082 sum = 0;
00083 double mean2 = m_mean * m_mean;
00084 for (x = 0; x < m_n; x++)
00085 {
00086 double val = m_data[x];
00087 sum += (val * val) - mean2;
00088
00089 m_variance = m_variance + ((val - m_mean) * (val - m_mean));
00090 m_averageDeviation = m_averageDeviation + Math::Abs(val - m_mean);
00091 }
00092 m_ssd = Math::Sqrt(sum / m_n);
00093 m_variance /= m_n;
00094 m_averageDeviation /= m_n;
00095 }
00096
00097 Sample::Sample(List<double> *list)
00098 : m_min(DBL_MAX), m_max(DBL_MIN), m_mean(0), m_ssd(0)
00099 {
00100 if ( NULL == (m_data = (double *)malloc(sizeof(double) * list->Count())) )
00101 {
00102 throw OutOfMemoryException();
00103 }
00104 m_n = list->Count();
00105 List<double>::Iterator iter = list->Begin();
00106 int x = 0;
00107 while(iter.Next())
00108 {
00109 m_data[x++] = iter.Current();
00110 }
00111 Recalc();
00112 }
00113
00114 Sample::Sample(Vector<double> *list)
00115 : m_min(DBL_MAX), m_max(DBL_MIN), m_mean(0), m_ssd(0)
00116 {
00117 if ( NULL == (m_data = (double *)malloc(sizeof(double) * list->Count())) )
00118 {
00119 throw OutOfMemoryException();
00120 }
00121 m_n = list->Count();
00122 for (int x = 0; x < m_n; x++)
00123 {
00124 m_data[x] = list->ElementAt(x);
00125 }
00126 Recalc();
00127 }
00128
00129 Sample::Sample(const double *list, const int count)
00130 : m_min(DBL_MAX), m_max(DBL_MIN), m_mean(0), m_ssd(0)
00131 {
00132 if ( NULL == (m_data = (double *)malloc(sizeof(double) * count)) )
00133 {
00134 throw OutOfMemoryException();
00135 }
00136 m_n = count;
00137 for (int x = 0; x < m_n; x++)
00138 {
00139 m_data[x] = list[x];
00140 }
00141 Recalc();
00142 }
00143
00144 Sample::Sample (const Sample& s)
00145 : m_min(s.m_min), m_max(s.m_max), m_mean(s.m_mean), m_ssd(s.m_ssd), m_variance(s.m_variance), m_averageDeviation(s.m_averageDeviation), m_n(s.m_n)
00146 {
00147 if ( NULL == (m_data = (double *)malloc(sizeof(double) * m_n)) )
00148 {
00149 throw OutOfMemoryException();
00150 }
00151 for ( int x = 0; x < m_n; x++ )
00152 {
00153 m_data[x] = s.m_data[x];
00154 }
00155 }
00156
00157 Sample::~Sample()
00158 {
00159 free(m_data);
00160 }
00161
00162 Sample& Sample::operator =(const Sample& s)
00163 {
00164 m_min = s.m_min;
00165 m_max = s.m_max;
00166 m_mean = s.m_mean;
00167 m_ssd = s.m_ssd;
00168 m_variance = s.m_variance;
00169 m_averageDeviation = s.m_averageDeviation;
00170 m_n = s.m_n;
00171
00172 if ( NULL == (m_data = (double *)malloc(sizeof(double) * m_n)) )
00173 {
00174 throw OutOfMemoryException();
00175 }
00176 for ( int x = 0; x < m_n; x++ )
00177 {
00178 m_data[x] = s.m_data[x];
00179 }
00180
00181 return *this;
00182 }
00183
00184 double Sample::AverageVariance() const
00185 {
00186 double ep = 0;
00187 double s;
00188 double var = 0;
00189
00190 for (int j = 0; j < m_n; j++)
00191 {
00192 s = m_data[j] - m_mean;
00193 ep = ep + s;
00194 var = var + s * s;
00195 }
00196
00197 return (var - ep * ep / m_n) / (m_n - 1);
00198 }
00199
00200 double Sample::Skew() const
00201 {
00202 double sum = 0;
00203 for ( int x = 0; x < m_n; x++ )
00204 {
00205 sum += ((m_data[x] - m_mean) / m_ssd) * ((m_data[x] - m_mean) / m_ssd) * ((m_data[x] - m_mean) / m_ssd);
00206 }
00207 return sum / m_n;
00208 }
00209
00210 double Sample::Kurtosis() const
00211 {
00212 double sum = 0;
00213 for ( int x = 0; x < m_n; x++ )
00214 {
00215 sum = sum + ((m_data[x] - m_mean) / m_ssd) * ((m_data[x] - m_mean) / m_ssd) * ((m_data[x] - m_mean) / m_ssd) * ((m_data[x] - m_mean) / m_ssd);
00216 }
00217 return sum / m_n - 3;
00218 }
00219
00220 double Sample::Median() const
00221 {
00222 double *da = new double[m_n];
00223 if ( NULL == da )
00224 {
00225 throw OutOfMemoryException();
00226 }
00227
00228 for (int x = 0; x < m_n; x++)
00229 {
00230 _ArrayInsert(da, m_n, m_data[x]);
00231 ASSERT_MEM(da, m_n * sizeof(double));
00232 }
00233 #ifdef DEBUG
00234 for ( int i = 0; i < m_n; i++ )
00235 {
00236 bool found = false;
00237 for ( int j = 0; j < m_n; j++ )
00238 {
00239 ASSERT( (j > i) ? da[j] <= da[i] : da[j] >= da[i] );
00240 if ( m_data[j] == da[i] )
00241 {
00242 found = true;
00243 break;
00244 }
00245 }
00246 ASSERT(found);
00247 }
00248 #endif
00249
00250 double median = da[m_n / 2];
00251 delete[] da;
00252 return median;
00253 }
00254
00255 double Sample::ErrorFunction(double x) const
00256 {
00257 if (x < 0)
00258 {
00259 return 1 + Gammp(0.5, x * x);
00260 }
00261 else
00262 {
00263 return Gammq(0.5, x * x);
00264 }
00265 }
00266
00267 double Sample::Gammp(const double a, const double x)
00268 {
00269 if (x < 0 || a <= 0)
00270 {
00271 throw new InvalidArgumentException("gammp bad, bad args");
00272 }
00273
00274 if (x < (a + 1))
00275 {
00276 return Gser(a, x);
00277 }
00278 else
00279 {
00280 return 1 - Gcf(a, x);
00281 }
00282 }
00283
00284 double Sample::Gammq(const double a, const double x)
00285 {
00286 if (x < 0 || a <= 0)
00287 {
00288 throw new InvalidArgumentException("gammp bad, bad args");
00289 }
00290
00291 if( x < (a + 1) )
00292 {
00293 return 1 - Gser(a, x);
00294 }
00295 else
00296 {
00297 return Gcf(a, x);
00298 }
00299 }
00300
00301 double Sample::Gcf(const double a, const double x)
00302 {
00303 int i;
00304 double gln = SampleTest::Gammaln(a);
00305 double b = x + 1 - a;
00306 double c = 1 / 1E-30;
00307 double d = 1 / b;
00308 double h = d;
00309
00310 for(i = 0; i < 200; i++)
00311 {
00312 double an = -i * (1 - a);
00313 b = b + 2;
00314 d = an * d + b;
00315 if ( Math::Abs(d) < 1E-30 )
00316 {
00317 d = 1E-30;
00318 }
00319 c = b + an / c;
00320 if (Math::Abs(c) < 1E-30)
00321 {
00322 c = 1E-30;
00323 }
00324 d = 1 / d;
00325 double del = d * c;
00326 h = h * del;
00327 if (Math::Abs(del) < 0.0000003)
00328 {
00329 break;
00330 }
00331 }
00332 if( i >= 200 )
00333 {
00334 throw new Exception("gcf failed");
00335 }
00336 return Math::Exp(-x + a * Math::Log(x) - gln) * h;
00337 }
00338
00339 double Sample::Gser(const double a, const double x)
00340 {
00341 double gln = SampleTest::Gammaln(a);
00342
00343 if( x <= 0 )
00344 {
00345 if (x < 0)
00346 {
00347 throw new InvalidArgumentException("gser x less than 0 in gser");
00348 }
00349 return 0;
00350 }
00351
00352 double ap = a;
00353 double sum = 1 / a;
00354 double del = sum;
00355
00356 for (int N = 1; N <= 200; N++)
00357 {
00358 ap = ap + 1;
00359 del = del * x / ap;
00360 sum = sum + del;
00361 if (Math::Abs(del) < Math::Abs(sum) * 0.0000003 )
00362 {
00363 return sum * Math::Exp(-x + a * Math::Log(x) - gln);
00364 }
00365 }
00366
00367 throw new Exception( "gser a too large or ITMaX to small" );
00368 }
00369
00370 Sample Sample::TransformASin() const
00371 {
00372 List<double> vals;
00373
00374 for( int x = 0; x < m_n; x++ )
00375 {
00376 vals.Add(Math::Asin(Math::Sqrt(m_data[x])));
00377 }
00378 return Sample(&vals);
00379 }
00380
00381 Sample Sample::TransformSqrt375() const
00382 {
00383 List<double> vals;
00384
00385 for( int x = 0; x < m_n; x++ )
00386 {
00387 vals.Add(Math::Sqrt(m_data[x] + 0.375));
00388 }
00389 return Sample(&vals);
00390 }
00391
00392 Sample Sample::TransformLog10() const
00393 {
00394 List<double> vals;
00395
00396 for( int x = 0; x < m_n; x++ )
00397 {
00398 vals.Add(Math::Log(m_data[x]) / Math::Log(10.0) + 1);
00399 }
00400 return Sample(&vals);
00401 }
00402
00403 #ifdef DEBUG
00404 void Sample::ValidateMem() const
00405 {
00406 ASSERT_MEM( m_data, sizeof(double) * m_n );
00407 }
00408
00409 void Sample::CheckMem() const
00410 {
00411 DEBUG_NOTE_MEM( m_data );
00412 }
00413 #endif