Changeset 14428
- Timestamp:
- Aug 8, 2007, 9:34:58 AM (19 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/math/psStats.c (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/math/psStats.c
r13991 r14428 13 13 * use ->min and ->max (PS_STAT_USE_RANGE) 14 14 * 15 * @version $Revision: 1.21 3$ $Name: not supported by cvs2svn $16 * @date $Date: 2007-0 6-30 00:35:38 $15 * @version $Revision: 1.214 $ $Name: not supported by cvs2svn $ 16 * @date $Date: 2007-08-08 19:34:58 $ 17 17 * 18 18 * Copyright 2006 IfA, University of Hawaii … … 382 382 383 383 using the method below, with a single loop for various options costs only a small amount and is 384 much easier to debug. running 10000 tests of 1000 point vectors for the two methods gives: 385 386 single 387 (mask: 0, range: 0): 0.193 sec 388 (mask: 1, range: 0): 0.257 sec 389 (mask: 0, range: 0): 0.349 sec 390 (mask: 1, range: 0): 0.401 sec 391 384 much easier to debug. 392 385 *****************************************************************************/ 393 static bool vectorSampleStdev(const psVector* myVector, 394 const psVector* errors, 395 const psVector* maskVector, 396 psMaskType maskVal, 397 psStats* stats) 386 387 static bool vectorSampleStdev(const psVector* myVector, 388 const psVector* errors, 389 const psVector* maskVector, 390 psMaskType maskVal, 391 psStats* stats) 398 392 { 399 393 psTrace(TRACE, 4, "---- %s() begin ----\n", __func__); … … 467 461 psTrace(TRACE, 4, "---- %s() end ----\n", __func__); 468 462 463 return true; 464 } 465 466 static bool vectorSampleMoments(const psVector* myVector, 467 const psVector* maskVector, 468 psMaskType maskVal, 469 psStats* stats) 470 { 471 psTrace(TRACE, 4, "---- %s() begin ----\n", __func__); 472 473 // This procedure requires the mean and standard deviation 474 if (!(stats->results & PS_STAT_SAMPLE_MEAN)) { 475 vectorSampleMean(myVector, NULL, maskVector, maskVal, stats); 476 } 477 if (isnan(stats->sampleMean)) { 478 psTrace(TRACE, 5, "WARNING: vectorSampleMoments(): sample mean is NAN.\n"); 479 goto SAMPLE_MOMENTS_BAD; 480 } 481 if (!(stats->results & PS_STAT_SAMPLE_STDEV)) { 482 vectorSampleMean(myVector, NULL, maskVector, maskVal, stats); 483 } 484 if (isnan(stats->sampleStdev) || stats->sampleStdev == 0.0) { 485 psTrace(TRACE, 5, "WARNING: vectorSampleMoments(): sample mean is NAN or 0.\n"); 486 goto SAMPLE_MOMENTS_BAD; 487 } 488 489 psF32 *data = myVector->data.F32; // Dereference 490 psU8 *maskData = (maskVector == NULL) ? NULL : maskVector->data.U8; 491 bool useRange = stats->options & PS_STAT_USE_RANGE; 492 493 // Accumulate the sums 494 double mean = stats->sampleMean; // The mean 495 double sum3 = 0.0; // Sum of the cubes of the differences 496 double sum4 = 0.0; // Sum of the fourth powers of the differences 497 long count = 0; // Number of data points being used 498 for (long i = 0; i < myVector->n; i++) { 499 // Check if the data is with the specified range 500 if (useRange && (data[i] < stats->min)) { 501 continue; 502 } 503 if (useRange && (data[i] > stats->max)) { 504 continue; 505 } 506 if (maskData && (maskData[i] & maskVal)) { 507 continue; 508 } 509 510 double diff = data[i] - mean; // Difference from the mean 511 double temp; // Temporary variable for accumulating 512 513 sum3 += temp = PS_SQR(diff); 514 sum4 += temp * diff; 515 516 count++; 517 } 518 519 assert(count > 1); // It should be, because we have a mean and standard deviation 520 521 double stdev = stats->sampleStdev; // Standard deviation 522 double variance = PS_SQR(stdev); // Variance 523 524 // Formula for skewness and kurtosis from Numerical Recipes in C, p 613. 525 // Note that we are defining the kurtosis relative to a normal distribution (hence the -3.0). 526 stats->sampleSkewness = sum3 / (count * variance * stdev); 527 stats->sampleKurtosis = sum4 / (count * PS_SQR(variance)) - 3.0; 528 stats->results |= PS_STAT_SAMPLE_SKEWNESS | PS_STAT_SAMPLE_KURTOSIS; 529 530 psTrace(TRACE, 4, "---- %s() end ----\n", __func__); 531 532 return true; 533 534 SAMPLE_MOMENTS_BAD: 535 // stats->sampleStdev has already been set 536 stats->sampleSkewness = NAN; 537 stats->sampleKurtosis = NAN; 538 stats->results |= PS_STAT_SAMPLE_SKEWNESS | PS_STAT_SAMPLE_KURTOSIS; 469 539 return true; 470 540 } … … 1683 1753 stats->sampleUQ = NAN; 1684 1754 stats->sampleLQ = NAN; 1755 stats->sampleSkewness = NAN; 1756 stats->sampleKurtosis = NAN; 1685 1757 stats->robustMedian = NAN; 1686 1758 stats->robustStdev = NAN; … … 1808 1880 } 1809 1881 1882 if (stats->options & (PS_STAT_SAMPLE_SKEWNESS | PS_STAT_SAMPLE_KURTOSIS)) { 1883 if (!vectorSampleMoments(inF32, maskU8, maskVal, stats)) { 1884 psError(PS_ERR_UNKNOWN, false, "Failed to calculate sample moments"); 1885 status &= false; 1886 } 1887 } 1888 1810 1889 // ************************************************************************ 1811 1890 if (stats->options & (PS_STAT_MAX | PS_STAT_MIN)) { … … 1878 1957 READ_STAT("MEAN", PS_STAT_SAMPLE_MEAN); 1879 1958 READ_STAT("STDEV", PS_STAT_SAMPLE_STDEV); 1959 READ_STAT("SKEWNESS", PS_STAT_SAMPLE_SKEWNESS); 1960 READ_STAT("KURTOSIS", PS_STAT_SAMPLE_KURTOSIS); 1880 1961 READ_STAT("MEDIAN", PS_STAT_SAMPLE_MEDIAN); 1881 1962 READ_STAT("QUARTILE", PS_STAT_SAMPLE_QUARTILE); … … 1884 1965 READ_STAT("SAMPLE_MEDIAN", PS_STAT_SAMPLE_MEDIAN); 1885 1966 READ_STAT("SAMPLE_QUARTILE", PS_STAT_SAMPLE_QUARTILE); 1967 READ_STAT("SAMPLE_SKEWNESS", PS_STAT_SAMPLE_SKEWNESS); 1968 READ_STAT("SAMPLE_KURTOSIS", PS_STAT_SAMPLE_KURTOSIS); 1886 1969 READ_STAT("ROBUST", PS_STAT_ROBUST_MEDIAN); 1887 1970 READ_STAT("ROBUST_MEDIAN", PS_STAT_ROBUST_MEDIAN); … … 1919 2002 WRITE_STAT("SAMPLE_MEDIAN", PS_STAT_SAMPLE_MEDIAN); 1920 2003 WRITE_STAT("SAMPLE_QUARTILE", PS_STAT_SAMPLE_QUARTILE); 2004 WRITE_STAT("SAMPLE_SKEWNESS", PS_STAT_SAMPLE_SKEWNESS); 2005 WRITE_STAT("SAMPLE_KURTOSIS", PS_STAT_SAMPLE_KURTOSIS); 1921 2006 WRITE_STAT("ROBUST_MEDIAN", PS_STAT_ROBUST_MEDIAN); 1922 2007 WRITE_STAT("ROBUST_STDEV", PS_STAT_ROBUST_STDEV); … … 1971 2056 case PS_STAT_SAMPLE_STDEV: 1972 2057 case PS_STAT_SAMPLE_QUARTILE: 2058 case PS_STAT_SAMPLE_SKEWNESS: 2059 case PS_STAT_SAMPLE_KURTOSIS: 1973 2060 case PS_STAT_ROBUST_MEDIAN: 1974 2061 case PS_STAT_ROBUST_STDEV: … … 2002 2089 case PS_STAT_SAMPLE_STDEV: 2003 2090 return stats->sampleStdev; 2091 case PS_STAT_SAMPLE_SKEWNESS: 2092 return stats->sampleSkewness; 2093 case PS_STAT_SAMPLE_KURTOSIS: 2094 return stats->sampleKurtosis; 2004 2095 case PS_STAT_ROBUST_MEDIAN: 2005 2096 return stats->robustMedian;
Note:
See TracChangeset
for help on using the changeset viewer.
