Changeset 23988 for trunk/psLib/src/math/psStats.c
- Timestamp:
- Apr 28, 2009, 11:19:59 AM (17 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/math/psStats.c (modified) (66 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/math/psStats.c
r23416 r23988 24 24 // unity, even though the standard deviation is not defined in that case (NAN). 25 25 26 // reworking the return values and failure conditions: it should only be an error if the 27 // inputs imply a programming error: eg, NULL data vectors, non-sensical input 28 // parameters. If the statistic cannot be calculated (0 length vector, 0 range, no 29 // unmasked data values), the statistic should be reported as NAN, but an error should not 30 // be raised. (TBD: do we need to have a unique field in psStats or a return parameter 31 // that can be checked for an invalid result?) 32 26 33 #ifdef HAVE_CONFIG_H 27 # include "config.h"34 #include "config.h" 28 35 #endif 29 36 … … 42 49 #include "psMemory.h" 43 50 #include "psAbort.h" 44 //#include "psImage.h"45 51 #include "psVector.h" 46 52 #include "psTrace.h" … … 69 75 #define PS_POLY_MEDIAN_MAX_ITERATIONS 30 70 76 77 #define TRACE "psLib.math" 78 71 79 #define MASK_MARK 0x80 // XXX : can we change this? bit to use internally to mark data as bad 72 80 #define PS_ROBUST_MAX_ITERATIONS 20 // Maximum number of iterations for robust statistics … … 87 95 break; \ 88 96 case PS_BINARY_DISECT_OUTSIDE_RANGE: \ 89 psTrace ("psLib.math", 6, "selected bin outside range"); \97 psTrace(TRACE, 6, "selected bin outside range"); \ 90 98 if (USE_END == -1) { RESULT = 0; } \ 91 99 if (USE_END == +1) { RESULT = VECTOR->n - 1; } \ … … 116 124 } \ 117 125 Xt = PS_MIN (BOUNDS->data.F32[BIN+1], PS_MAX(BOUNDS->data.F32[BIN], Xt)); \ 118 psTrace( "psLib.math", 6, "(Xo, Yo, dX, dY, Xt, Yt) is (%.2f %.2f %.2f %.2f %.2f %.2f)\n", \126 psTrace(TRACE, 6, "(Xo, Yo, dX, dY, Xt, Yt) is (%.2f %.2f %.2f %.2f %.2f %.2f)\n", \ 119 127 Xo, Yo, dX, dY, Xt, VALUE); \ 120 128 RESULT = Xt; } 121 122 #define TRACE "psLib.math"123 129 124 130 /*****************************************************************************/ … … 182 188 psStats* stats) 183 189 { 184 psTrace(TRACE, 4, "---- %s() begin ----\n", __func__);185 186 190 long count = 0; // Number of points contributing to this mean 187 191 psF32 mean = 0.0; // The mean … … 222 226 } 223 227 stats->sampleMean = mean; 224 if (isnan(mean)) { 225 // XXX raise an error here? 226 psTrace(TRACE, 4, "---- %s(false) end ----\n", __func__); 227 return true; 228 } 229 230 stats->results |= PS_STAT_SAMPLE_MEAN; 231 psTrace(TRACE, 4, "---- %s(true) end ----\n", __func__); 228 229 if (!isnan(mean)) { 230 stats->results |= PS_STAT_SAMPLE_MEAN; 231 } 232 232 return true; 233 233 } … … 252 252 ) 253 253 { 254 psTrace(TRACE, 4, "---- %s() begin ----\n", __func__);255 254 psF32 max = -PS_MAX_F32; // The calculated maximum 256 255 psF32 min = PS_MAX_F32; // The calculated minimum … … 289 288 stats->results |= PS_STAT_MAX; 290 289 } 291 psTrace(TRACE, 4, "---- %s(%d) end ----\n", __func__, numValid);292 290 return numValid; 293 291 } … … 303 301 psStats* stats) 304 302 { 305 psTrace(TRACE, 4, "---- %s() begin ----\n", __func__);306 307 303 bool useRange = stats->options & PS_STAT_USE_RANGE; 308 304 psVectorMaskType *maskData = (maskVector == NULL) ? NULL : maskVector->data.PS_TYPE_VECTOR_MASK_DATA; // Dereference the vector … … 334 330 335 331 if (count == 0) { 336 ps Error(PS_ERR_BAD_PARAMETER_SIZE, true, "No valid data in input vector.\n");332 psLogMsg(TRACE, PS_LOG_DETAIL, "No valid data in input vector.\n"); 337 333 stats->sampleUQ = NAN; 338 334 stats->sampleLQ = NAN; … … 343 339 // Sort the temporary vector. 344 340 if (!psVectorSort(outVector, outVector)) { // Sort in-place (since it's a copy, it's OK) 341 // an error in psVectorSort is a serious error 345 342 psError(PS_ERR_UNEXPECTED_NULL, false, _("Failed to sort input data.")); 346 343 stats->sampleUQ = NAN; … … 364 361 stats->results |= PS_STAT_SAMPLE_QUARTILE; 365 362 366 // Return "true" on success.367 psTrace(TRACE, 4, "---- %s(true) end ----\n", __func__);368 363 return true; 369 364 } … … 390 385 psStats* stats) 391 386 { 392 psTrace(TRACE, 4, "---- %s() begin ----\n", __func__);393 394 387 // This procedure requires the mean. If it has not been already 395 388 // calculated, then call vectorSampleMean() … … 400 393 // If the mean is NAN, then generate a warning and set the stdev to NAN. 401 394 if (isnan(stats->sampleMean)) { 402 psTrace(TRACE, 5, "WARNING: vectorSampleStdev(): sample mean is NAN. " 403 "Setting stats->sampleStdev = NAN.\n"); 395 psLogMsg(TRACE, PS_LOG_DETAIL, "WARNING: vectorSampleStdev(): sample mean is NAN. Setting stats->sampleStdev = NAN.\n"); 404 396 stats->sampleStdev = NAN; 405 397 return true; … … 445 437 // Assume that the user knows what he's doing when he masks out everything --> no error. 446 438 stats->sampleStdev = NAN; 447 psTrace(TRACE, 5, "WARNING: vectorSampleStdev(): no valid psVector elements (%ld). " 448 "Setting stats->sampleStdev = NAN.\n", count); 439 psLogMsg(TRACE, PS_LOG_DETAIL, "WARNING: vectorSampleStdev(): no valid psVector elements (%ld). Setting stats->sampleStdev = NAN.\n", count); 449 440 return true; 450 441 } 451 442 if (count == 1) { 452 443 stats->sampleStdev = 0.0; 453 ps Trace(TRACE, 5, "WARNING: vectorSampleStdev(): only one valid psVector elements (%ld). "444 psLogMsg(TRACE, PS_LOG_DETAIL, "WARNING: vectorSampleStdev(): only one valid psVector elements (%ld). " 454 445 "Setting stats->sampleStdev = 0.0.\n", count); 455 446 return true; … … 462 453 } 463 454 stats->results |= PS_STAT_SAMPLE_STDEV; 464 465 psTrace(TRACE, 4, "---- %s() end ----\n", __func__);466 455 467 456 return true; … … 473 462 psStats* stats) 474 463 { 475 psTrace(TRACE, 4, "---- %s() begin ----\n", __func__);476 477 464 // This procedure requires the mean and standard deviation 478 465 if (!(stats->results & PS_STAT_SAMPLE_MEAN)) { … … 480 467 } 481 468 if (isnan(stats->sampleMean)) { 482 ps Trace(TRACE, 5, "WARNING: vectorSampleMoments(): sample mean is NAN.\n");469 psLogMsg(TRACE, PS_LOG_DETAIL, "WARNING: vectorSampleMoments(): sample mean is NAN.\n"); 483 470 goto SAMPLE_MOMENTS_BAD; 484 471 } … … 487 474 } 488 475 if (isnan(stats->sampleStdev) || stats->sampleStdev == 0.0) { 489 ps Trace(TRACE, 5, "WARNING: vectorSampleMoments(): sample stdev is NAN or 0.\n");476 psLogMsg(TRACE, PS_LOG_DETAIL, "WARNING: vectorSampleMoments(): sample stdev is NAN or 0.\n"); 490 477 goto SAMPLE_MOMENTS_BAD; 491 478 } … … 534 521 stats->results |= PS_STAT_SAMPLE_SKEWNESS | PS_STAT_SAMPLE_KURTOSIS; 535 522 536 psTrace(TRACE, 4, "---- %s() end ----\n", __func__);537 538 523 return true; 539 524 … … 542 527 stats->sampleSkewness = NAN; 543 528 stats->sampleKurtosis = NAN; 544 stats->results |= PS_STAT_SAMPLE_SKEWNESS | PS_STAT_SAMPLE_KURTOSIS;545 529 return true; 546 530 } … … 565 549 ) 566 550 { 567 psTrace(TRACE, 4, "---- %s() begin ----\n", __func__);568 psTrace(TRACE, 4, "Trace level is %d\n", psTraceGetLevel("psLib.math"));569 570 551 // Ensure that stats->clipIter is within the proper range. 571 552 PS_ASSERT_INT_WITHIN_RANGE(stats->clipIter, … … 601 582 vectorSampleMedian(myVector, tmpMask, maskVal, stats); 602 583 if (isnan(stats->sampleMedian)) { 603 psTrace(TRACE, 5, "Call to vectorSampleMedian returned NAN\n"); 604 psTrace(TRACE, 4, "---- %s(false) end ----\n", __func__); 605 return false; 584 psLogMsg(TRACE, PS_LOG_DETAIL, "Call to vectorSampleMedian returned NAN\n"); 585 return true; 606 586 } 607 587 psTrace(TRACE, 6, "The initial sample median is %f\n", stats->sampleMedian); … … 610 590 vectorSampleStdev(myVector, errors, tmpMask, maskVal, stats); 611 591 if (isnan(stats->sampleStdev)) { 612 psTrace(TRACE, 5, "Call to vectorSampleStdev returned NAN\n"); 613 psTrace(TRACE, 4, "---- %s(false) end ----\n", __func__); 614 return false; 592 psLogMsg(TRACE, PS_LOG_DETAIL, "Call to vectorSampleStdev returned NAN\n"); 593 return true; 615 594 } 616 595 psTrace(TRACE, 6, "The initial sample stdev is %f\n", stats->sampleStdev); … … 669 648 if (isnan(stats->sampleMean) || isnan(stats->sampleStdev)) { 670 649 iter = stats->clipIter; 671 psError(PS_ERR_UNKNOWN, true, "vectorSampleMean() or vectorSampleStdev() returned a NAN.\n"); 672 return false; 650 psLogMsg(TRACE, PS_LOG_DETAIL, "vectorSampleMean() or vectorSampleStdev() returned a NAN.\n"); 651 clippedMean = NAN; 652 clippedStdev = NAN; 653 return true; 673 654 } else { 674 655 clippedMean = stats->sampleMean; … … 693 674 psTrace(TRACE, 6, "The final clipped stdev is %f\n", clippedStdev); 694 675 695 psTrace(TRACE, 4, "---- %s(true) end ----\n", __func__);696 676 return true; 697 677 } … … 722 702 psStats* stats) 723 703 { 724 psTrace(TRACE, 4, "---- %s() begin ----\n", __func__);725 704 if (psTraceGetLevel("psLib.math") >= 8) { 726 705 PS_VECTOR_PRINT_F32(myVector); … … 767 746 if (numValid == 0 || isnan(min) || isnan(max)) { 768 747 // Data range calculation failed 769 ps Error(PS_ERR_UNKNOWN, false, "Failed to calculate the min/max of the input vector.\n");748 psLogMsg(TRACE, PS_LOG_DETAIL, "Failed to calculate the min/max of the input vector.\n"); 770 749 goto escape; 771 750 } … … 779 758 stats->robustLQ = min; 780 759 stats->robustN50 = numValid; 760 // XXX this is sort of an invalid / out-of-bounds result: to set or not to set these bits: 781 761 stats->results |= PS_STAT_ROBUST_MEDIAN; 782 762 stats->results |= PS_STAT_ROBUST_STDEV; 783 763 stats->results |= PS_STAT_ROBUST_QUARTILE; 784 psTrace(TRACE, 5, "All data points have the same value: %f.\n", min); 785 psTrace(TRACE, 4, "---- %s(0) end ----\n", __func__); 764 psLogMsg(TRACE, PS_LOG_DETAIL, "All data points have the same value: %f.\n", min); 786 765 psFree(mask); 787 766 psFree(statsMinMax); … … 809 788 // XXXXX we need to consider this step if errors -> variance 810 789 if (!psVectorHistogram(histogram, myVector, errors, mask, maskVal)) { 790 // if psVectorHistogram returns false, we have a programming error 811 791 psError(PS_ERR_UNKNOWN, false, "Unable to generate histogram for robust statistics.\n"); 812 goto escape; 792 psFree(histogram); 793 psFree(cumulative); 794 psFree(statsMinMax); 795 psFree(mask); 796 797 return false; 813 798 } 814 799 if (psTraceGetLevel("psLib.math") >= 8) { … … 843 828 stats->robustMedian = fitQuadraticSearchForYThenReturnXusingValues(cumulative->bounds, cumulative->nums, binMedian, totalDataPoints/2.0); 844 829 if (isnan(stats->robustMedian)) { 845 psError(PS_ERR_UNKNOWN, false, 846 "Failed to fit a quadratic and calculate the 50-percent position.\n"); 830 psLogMsg(TRACE, PS_LOG_DETAIL, "Failed to fit a quadratic and calculate the 50-percent position.\n"); 847 831 goto escape; 848 832 } … … 866 850 867 851 if ((binLo < 0) || (binHi < 0)) { 868 ps Error(PS_ERR_UNKNOWN, false, "Failed to calculate the 15.8655%% and 84.1345%% data points.\n");852 psLogMsg(TRACE, PS_LOG_DETAIL, "Failed to calculate the 15.8655%% and 84.1345%% data points.\n"); 869 853 goto escape; 870 854 } … … 962 946 stats->results |= PS_STAT_ROBUST_STDEV; 963 947 stats->results |= PS_STAT_ROBUST_QUARTILE; 964 psTrace(TRACE, 5, "Maximum number of iterations (%d) exceeded.", PS_ROBUST_MAX_ITERATIONS); 965 psTrace(TRACE, 4, "---- %s(0) end ----\n", __func__); 948 psLogMsg(TRACE, PS_LOG_DETAIL, "Maximum number of iterations (%d) exceeded.", PS_ROBUST_MAX_ITERATIONS); 966 949 psFree(mask); 967 950 psFree(statsMinMax); 968 return false;951 return true; 969 952 } 970 953 } else { … … 991 974 psF32 binHi25F32 = fitQuadraticSearchForYThenReturnXusingValues(cumulative->bounds, cumulative->nums, binHi25, totalDataPoints * 0.75f); 992 975 if (isnan(binLo25F32) || isnan(binHi25F32)) { 993 psError(PS_ERR_UNKNOWN, false, 994 "could not determine the robustUQ: fitQuadraticSearchForYThenReturnX() returned a NAN.\n"); 976 psLogMsg(TRACE, PS_LOG_DETAIL, "could not determine the robustUQ: fitQuadraticSearchForYThenReturnX() returned a NAN.\n"); 995 977 goto escape; 996 978 } … … 1020 1002 stats->results |= PS_STAT_ROBUST_QUARTILE; 1021 1003 1022 psTrace(TRACE, 4, "---- %s(0) end ----\n", __func__);1023 1004 return true; 1024 1005 … … 1033 1014 stats->results |= PS_STAT_ROBUST_QUARTILE; 1034 1015 1035 psTrace(TRACE, 4, "---- %s(false) end ----\n", __func__);1036 1037 1016 psFree(histogram); 1038 1017 psFree(cumulative); … … 1040 1019 psFree(mask); 1041 1020 1042 return false;1021 return true; 1043 1022 } 1044 1023 … … 1057 1036 // calculated, then call vectorSampleMean() 1058 1037 if (!(stats->results & PS_STAT_ROBUST_MEDIAN)) { 1059 vectorRobustStats(myVector, errors, mask, maskVal, stats); 1038 if (!vectorRobustStats(myVector, errors, mask, maskVal, stats)) { 1039 psError(PS_ERR_UNKNOWN, false, "failure to measure robust stats\n"); 1040 return false; 1041 } 1060 1042 } 1061 1043 … … 1064 1046 stats->fittedStdev = NAN; 1065 1047 stats->fittedStdev = NAN; 1066 psTrace(TRACE, 4, "---- %s() end ----\n", __func__); 1067 return false; 1048 return true; 1068 1049 } 1069 1050 … … 1096 1077 float max = statsMinMax->max; 1097 1078 if (numValid == 0 || isnan(min) || isnan(max)) { 1098 ps Error(PS_ERR_UNKNOWN, false, "Failed to calculate the min/max of the input vector.\n");1079 psTrace(TRACE, 5, "Failed to calculate the min/max of the input vector.\n"); 1099 1080 psFree(statsMinMax); 1100 psTrace(TRACE, 4, "---- %s(false) end ----\n", __func__); 1101 return false; 1081 return true; 1102 1082 } 1103 1083 … … 1111 1091 psHistogram *histogram = psHistogramAlloc(min, max, numBins); // A new histogram (without outliers) 1112 1092 if (!psVectorHistogram(histogram, myVector, errors, mask, maskVal)) { 1093 // if psVectorHistogram returns false, we have a programming error 1113 1094 psError(PS_ERR_UNKNOWN, false, "Unable to generate histogram for fitted statistics.\n"); 1114 1095 psFree(histogram); … … 1175 1156 PS_VECTOR_PRINT_F32(y); 1176 1157 } 1158 1159 // psMinimizeLMChi2 can return false for bad data as well as for serious failures 1177 1160 if (!psMinimizeLMChi2(minimizer, NULL, params, NULL, x, y, NULL, minimizeLMChi2Gauss1D)) { 1178 1161 psError(PS_ERR_UNKNOWN, false, "Failed to fit a gaussian to the robust histogram.\n"); … … 1183 1166 psFree(histogram); 1184 1167 psFree(statsMinMax); 1185 psTrace(TRACE, 4, "---- %s(false) end ----\n", __func__); 1186 return false; 1168 return true; 1187 1169 } 1188 1170 if (psTraceGetLevel("psLib.math") >= 8) { … … 1235 1217 // calculated, then call vectorSampleMean() 1236 1218 if (!(stats->results & PS_STAT_ROBUST_MEDIAN)) { 1237 vectorRobustStats(myVector, errors, mask, maskVal, stats); 1219 if (!vectorRobustStats(myVector, errors, mask, maskVal, stats)) { 1220 psError(PS_ERR_UNKNOWN, false, "failure to measure robust stats\n"); 1221 return false; 1222 } 1238 1223 } 1239 1224 … … 1243 1228 stats->fittedStdev = NAN; 1244 1229 psTrace(TRACE, 4, "---- %s() end ----\n", __func__); 1245 return false;1230 return true; 1246 1231 } 1247 1232 … … 1274 1259 float max = statsMinMax->max; 1275 1260 if (numValid == 0 || isnan(min) || isnan(max)) { 1276 ps Error(PS_ERR_UNKNOWN, false, "Failed to calculate the min/max of the input vector.\n");1261 psLogMsg(TRACE, PS_LOG_DETAIL, "Failed to calculate the min/max of the input vector.\n"); 1277 1262 psFree(statsMinMax); 1278 1263 psTrace(TRACE, 4, "---- %s(false) end ----\n", __func__); 1279 return false;1264 return true; 1280 1265 } 1281 1266 … … 1354 1339 // psVectorInit (fitMask, 0); 1355 1340 1341 // XXX not sure if these should result in errors or not... 1356 1342 if (!psVectorFitPolynomial1D (poly, NULL, 0, y, NULL, x)) { 1357 1343 psError(PS_ERR_UNKNOWN, false, "Failed to fit a gaussian to the robust histogram.\n"); … … 1366 1352 1367 1353 if (poly->coeff[2] >= 0.0) { 1368 psTrace(TRACE, 6, "Parabolic fit results: %f + %f x + %f x^2\n", 1369 poly->coeff[0], poly->coeff[1], poly->coeff[2]); 1354 psTrace(TRACE, 6, "Parabolic fit results: %f + %f x + %f x^2\n", poly->coeff[0], poly->coeff[1], poly->coeff[2]); 1370 1355 psError(PS_ERR_UNKNOWN, false, "fit did not converge\n"); 1371 1356 psFree(x); … … 1429 1414 // calculated, then call vectorSampleMean() 1430 1415 if (!(stats->results & PS_STAT_ROBUST_MEDIAN)) { 1431 vectorRobustStats(myVector, errors, mask, maskVal, stats); 1416 if (!vectorRobustStats(myVector, errors, mask, maskVal, stats)) { 1417 psError(PS_ERR_UNKNOWN, false, "failure to measure robust stats\n"); 1418 return false; 1419 } 1432 1420 } 1433 1421 … … 1437 1425 stats->fittedStdev = NAN; 1438 1426 psTrace(TRACE, 4, "---- %s() end ----\n", __func__); 1439 return false;1427 return true; 1440 1428 } 1441 1429 … … 1468 1456 float max = statsMinMax->max; 1469 1457 if (numValid == 0 || isnan(min) || isnan(max)) { 1470 ps Error(PS_ERR_UNKNOWN, false, "Failed to calculate the min/max of the input vector.\n");1458 psLogMsg(TRACE, PS_LOG_DETAIL, "Failed to calculate the min/max of the input vector.\n"); 1471 1459 psFree(statsMinMax); 1472 1460 psTrace(TRACE, 4, "---- %s(false) end ----\n", __func__); 1473 return false;1461 return true; 1474 1462 } 1475 1463 … … 1516 1504 PS_BIN_FOR_VALUE (binMax, histogram->bounds, guessMean + maxFitSigma*guessStdev, 0); 1517 1505 if (binMin == binMax) { 1518 ps Error(PS_ERR_UNKNOWN, false, "Failed to calculate the min/max of the input vector.\n");1506 psLogMsg(TRACE, PS_LOG_DETAIL, "Failed to calculate the min/max of the input vector.\n"); 1519 1507 psFree(statsMinMax); 1520 psTrace(TRACE, 4, "---- %s(false) end ----\n", __func__); 1521 return false; 1508 return true; 1522 1509 } 1523 1510 … … 1724 1711 // calculated, then call vectorSampleMean() 1725 1712 if (!(stats->results & PS_STAT_ROBUST_MEDIAN)) { 1726 vectorRobustStats(myVector, errors, mask, maskVal, stats); 1713 if (!vectorRobustStats(myVector, errors, mask, maskVal, stats)) { 1714 psError(PS_ERR_UNKNOWN, false, "failure to measure robust stats\n"); 1715 return false; 1716 } 1727 1717 } 1728 1718 … … 1731 1721 stats->fittedStdev = NAN; 1732 1722 stats->fittedStdev = NAN; 1733 psTrace(TRACE, 4, "---- %s() end ----\n", __func__); 1734 return false; 1723 return true; 1735 1724 } 1736 1725 … … 1763 1752 float max = statsMinMax->max; 1764 1753 if (numValid == 0 || isnan(min) || isnan(max)) { 1765 ps Error(PS_ERR_UNKNOWN, false, "Failed to calculate the min/max of the input vector.\n");1754 psLogMsg(TRACE, PS_LOG_DETAIL, "Failed to calculate the min/max of the input vector.\n"); 1766 1755 psFree(statsMinMax); 1767 psTrace(TRACE, 4, "---- %s(false) end ----\n", __func__); 1768 return false; 1756 stats->fittedStdev = NAN; 1757 stats->fittedStdev = NAN; 1758 return true; 1769 1759 } 1770 1760 … … 1780 1770 psHistogram *histogram = psHistogramAlloc(min, max, numBins); // A new histogram (without outliers) 1781 1771 if (!psVectorHistogram(histogram, myVector, errors, mask, maskVal)) { 1782 ps Error(PS_ERR_UNKNOWN, false, "Unable to generate histogram for fitted statistics v4.\n");1772 psLogMsg(TRACE, PS_LOG_DETAIL, "Unable to generate histogram for fitted statistics v4.\n"); 1783 1773 psFree(histogram); 1784 1774 psFree(statsMinMax); 1785 return false; 1775 stats->fittedStdev = NAN; 1776 stats->fittedStdev = NAN; 1777 return true; 1786 1778 } 1787 1779 if (psTraceGetLevel("psLib.math") >= 8) { … … 1813 1805 PS_BIN_FOR_VALUE (binMax, histogram->bounds, guessMean + maxFitSigma*guessStdev, 0); 1814 1806 if (binMin == binMax) { 1815 ps Error(PS_ERR_UNKNOWN, false, "Failed to calculate the min/max of the input vector.\n");1807 psLogMsg(TRACE, PS_LOG_DETAIL, "Failed to calculate the min/max of the input vector.\n"); 1816 1808 psFree(statsMinMax); 1817 psTrace(TRACE, 4, "---- %s(false) end ----\n", __func__); 1818 return false; 1809 stats->fittedStdev = NAN; 1810 stats->fittedStdev = NAN; 1811 return true; 1819 1812 } 1820 1813 … … 1877 1870 1878 1871 // fit 2nd order polynomial to ln(y) = -(x-xo)^2/2sigma^2 1872 // XXX this fit may fail with an error for an ill-conditioned matrix (bad data) 1873 // we probably should be able to handle the data errors gracefully 1879 1874 psPolynomial1D *poly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, 2); 1880 1875 bool status = psVectorFitPolynomial1D (poly, NULL, 0, y, NULL, x); … … 1883 1878 1884 1879 if (!status) { 1885 ps Error(PS_ERR_UNKNOWN, false, "Failed to fit a gaussian to the robust histogram.\n");1880 psLogMsg(TRACE, PS_LOG_DETAIL, "Failed to fit a gaussian to the robust histogram.\n"); 1886 1881 psFree(poly); 1887 1882 psFree(histogram); 1888 1883 psFree(statsMinMax); 1889 psTrace(TRACE, 4, "---- %s(false) end ----\n", __func__); 1890 return false; 1884 stats->fittedStdev = NAN; 1885 stats->fittedStdev = NAN; 1886 return true; 1891 1887 } 1892 1888 1893 1889 if (poly->coeff[2] >= 0.0) { 1894 psTrace(TRACE, 6, "Failed parabolic fit: %f + %f x + %f x^2\n", 1895 poly->coeff[0], poly->coeff[1], poly->coeff[2]); 1890 psLogMsg(TRACE, PS_LOG_MINUTIA, "Failed parabolic fit: %f + %f x + %f x^2\n", poly->coeff[0], poly->coeff[1], poly->coeff[2]); 1896 1891 psFree(poly); 1897 1892 psFree(histogram); … … 1907 1902 } 1908 1903 1909 psError(PS_ERR_UNKNOWN, false, "fit did not converge\n"); 1910 psTrace(TRACE, 4, "---- %s(false) end ----\n", __func__); 1911 return false; 1904 psLogMsg(TRACE, PS_LOG_DETAIL, "fit did not converge\n"); 1905 stats->fittedStdev = NAN; 1906 stats->fittedStdev = NAN; 1907 return true; 1912 1908 } 1913 1909 … … 1975 1971 1976 1972 if (!status) { 1977 ps Error(PS_ERR_UNKNOWN, false, "Failed to fit a gaussian to the robust histogram.\n");1973 psLogMsg(TRACE, PS_LOG_DETAIL, "Failed to fit a gaussian to the robust histogram.\n"); 1978 1974 psFree(poly); 1979 1975 psFree(histogram); 1980 1976 psFree(statsMinMax); 1981 psTrace(TRACE, 4, "---- %s(false) end ----\n", __func__); 1982 return false; 1977 stats->fittedStdev = NAN; 1978 stats->fittedStdev = NAN; 1979 return true; 1983 1980 } 1984 1981 … … 2155 2152 psStats* p_psStatsAlloc(const char *file, unsigned int lineno, const char *func, psStatsOptions options) 2156 2153 { 2157 psTrace(TRACE, 3,"---- %s() begin ----\n", __func__);2158 2159 2154 psStats *stats = p_psAlloc(file, lineno, func, sizeof(psStats)); 2160 2155 psMemSetDeallocator(stats, (psFreeFunc)statsFree); … … 2172 2167 stats->tmpMask = NULL; 2173 2168 2174 psTrace(TRACE, 3, "---- %s() end ----\n", __func__);2175 2169 return stats; 2176 2170 } … … 2231 2225 psVectorMaskType maskVal) 2232 2226 { 2233 psTrace(TRACE, 3,"---- %s() begin ----\n", __func__);2234 2227 PS_ASSERT_PTR_NON_NULL(stats, false); 2235 2228 PS_ASSERT_VECTOR_NON_NULL(in, false); … … 2380 2373 psFree(errorsF32); 2381 2374 psFree(maskVector); 2382 psTrace(TRACE, 3,"---- %s() end ----\n", __func__);2383 2375 return status; 2384 2376 }
Note:
See TracChangeset
for help on using the changeset viewer.
