IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jun 16, 2008, 4:26:34 PM (18 years ago)
Author:
Paul Price
Message:

Robust statistics should fall over gracefully when the iteration limit is reached.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/math/psStats.c

    r17612 r18155  
    1313 * use ->min and ->max (PS_STAT_USE_RANGE)
    1414 *
    15  *  @version $Revision: 1.223 $ $Name: not supported by cvs2svn $
    16  *  @date $Date: 2008-05-09 21:34:42 $
     15 *  @version $Revision: 1.224 $ $Name: not supported by cvs2svn $
     16 *  @date $Date: 2008-06-17 02:26:34 $
    1717 *
    1818 *  Copyright 2006 IfA, University of Hawaii
     
    6868#define PS_POLY_MEDIAN_MAX_ITERATIONS 30
    6969#define MASK_MARK 0x80   // bit to use internally to mark data as bad
     70#define PS_ROBUST_MAX_ITERATIONS 20     // Maximum number of iterations for robust statistics
    7071
    7172#define PS_BIN_MIDPOINT(HISTOGRAM, BIN_NUM) \
     
    752753    long binMedian;
    753754
    754     // Iterate to get the best bin size
     755    // Iterate to get the best bin size; an iteration limit is enforced at the bottom of the loop.
    755756    for (int iterate = 1; iterate > 0; iterate++) {
    756757        psTrace(TRACE, 6,
     
    768769        }
    769770        psTrace(TRACE, 6, "Data min/max is (%.2f, %.2f)\n", min, max);
    770         assert (iterate < 20);
    771         // fprintf (stderr, "%d @ %d : %f - %f\n", iterate, numValid, min, max);
    772771
    773772        // If all data points have the same value, then we set the appropriate members of stats and return.
     
    817816
    818817        // ADD step 1: Convert the specific histogram to a cumulative histogram
    819         // The cumulative histogram data points correspond to the UPPER bound value (N < Bin[i+1])
     818        // The cumulative histogram data points correspond to the UPPER bound value (N < Bin[i+1])
    820819        cumulative = psHistogramAlloc(min, max, numBins);
    821820        cumulative->nums->data.F32[0] = histogram->nums->data.F32[0];
    822821        for (long i = 1; i < histogram->nums->n; i++) {
    823822            cumulative->nums->data.F32[i] = cumulative->nums->data.F32[i-1] + histogram->nums->data.F32[i];
    824             cumulative->bounds->data.F32[i-1] = histogram->bounds->data.F32[i];
     823            cumulative->bounds->data.F32[i-1] = histogram->bounds->data.F32[i];
    825824        }
    826825        if (psTraceGetLevel("psLib.math") >= 8) {
     
    833832        psTrace(TRACE, 6, "Total data points is %ld\n", totalDataPoints);
    834833
    835         // find bin which is the lower bound of median (value[binMedian] < median < value[binMedian+1]
     834        // find bin which is the lower bound of median (value[binMedian] < median < value[binMedian+1]
    836835        PS_BIN_FOR_VALUE(binMedian, cumulative->nums, totalDataPoints/2.0, 0);
    837836
     
    840839
    841840        // ADD step 3: Interpolate to the exact 50% position: this is the robust histogram median.
    842         stats->robustMedian = fitQuadraticSearchForYThenReturnXusingValues(cumulative->bounds, cumulative->nums, binMedian, totalDataPoints/2.0);
     841        stats->robustMedian = fitQuadraticSearchForYThenReturnXusingValues(cumulative->bounds, cumulative->nums, binMedian, totalDataPoints/2.0);
    843842        if (isnan(stats->robustMedian)) {
    844843            psError(PS_ERR_UNKNOWN, false,
     
    940939                }
    941940            }
     941
    942942            // Free the histograms; they will be recreated on the next iteration, with new bounds
    943943            psFree(histogram);
     
    946946            psFree(cumulative);
    947947            cumulative = NULL;
     948
     949            if (iterate >= PS_ROBUST_MAX_ITERATIONS) {
     950                // This occurs when a large number of the values are identical --- a bin size cannot be found
     951                // that will spread out the distribution.  Therefore, set what we can, and fall over
     952                // gracefully.
     953                // stats->robustMedian has already been set
     954                stats->robustStdev = sigma;
     955                stats->robustUQ = stats->robustMedian;
     956                stats->robustLQ = stats->robustMedian;
     957                stats->robustN50 = numValid;
     958                stats->results |= PS_STAT_ROBUST_MEDIAN;
     959                stats->results |= PS_STAT_ROBUST_STDEV;
     960                stats->results |= PS_STAT_ROBUST_QUARTILE;
     961                psTrace(TRACE, 5, "Maximum number of iterations (%d) exceeded.", PS_ROBUST_MAX_ITERATIONS);
     962                psTrace(TRACE, 4, "---- %s(0) end  ----\n", __func__);
     963                psFree(mask);
     964                psFree(statsMinMax);
     965                return false;
     966            }
    948967        } else {
    949968            // We've got the bin size correct now
     
    27292748*****************************************************************************/
    27302749static psF32 fitQuadraticSearchForYThenReturnXusingValues(const psVector *xVec,
    2731                                                           psVector *yVec,
    2732                                                           psS32 binNum,
    2733                                                           psF32 yVal
     2750                                                          psVector *yVec,
     2751                                                          psS32 binNum,
     2752                                                          psF32 yVal
    27342753    )
    27352754{
     
    28242843        if (binNum == 0) {
    28252844            // We have two points only at the beginning of the vectors x and y.
    2826             // XXX this does not seem to be doing the linear interpolation / extrapolation
     2845            // XXX this does not seem to be doing the linear interpolation / extrapolation
    28272846            tmpFloat = 0.5 * (xVec->data.F32[binNum] +
    28282847                              xVec->data.F32[binNum + 1]);
Note: See TracChangeset for help on using the changeset viewer.