IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Sep 17, 2013, 11:13:22 AM (13 years ago)
Author:
eugene
Message:

fix boundaries on cumulative histogram; iterative clip uses 25 fixed bins, not 25 cumulative hist bins; tweak linear fit to use cumulative vector mid points

File:
1 edited

Legend:

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

    r36114 r36121  
    879879        cumulative = psHistogramAlloc(min, max, numBins);
    880880        cumulative->nums->data.F32[0] = histogram->nums->data.F32[0];
    881 
     881        cumulative->bounds->data.F32[0] = histogram->bounds->data.F32[0];
     882
     883        // Correctly fill the cumulative distribution with monotonically increasing values (skip zero valued bins).
     884        long Nc = 1;  // track the current bin of cumulative
     885        // the boundaries for the current cumulative bin are from upper end of the last valid histogram bin to the
     886        // upper end of the current histogram bin
     887        for (long i = 1; i < histogram->nums->n; i++) {
     888            if (histogram->nums->data.F32[i] == 0.0) continue;
     889            cumulative->nums->data.F32[Nc] = cumulative->nums->data.F32[Nc - 1] + histogram->nums->data.F32[i];
     890            cumulative->bounds->data.F32[Nc] = histogram->bounds->data.F32[i];
     891            Nc ++;
     892        }
     893        long Nlast = Nc - 1;  // last valid cumulative bin
     894        for (long i = Nc; i < histogram->nums->n; i++) { // Ensure the unused entries are filled.
     895            cumulative->nums->data.F32[i] = cumulative->nums->data.F32[Nlast];
     896            cumulative->bounds->data.F32[i] = cumulative->bounds->data.F32[i-1] + 1.0;
     897        }
     898
     899# if (0)
    882900        // Correctly fill the cumulative distribution with monotonically increasing values (skip zero valued bins).
    883901        long delta = 0;
     
    898916          cumulative->bounds->data.F32[i] = cumulative->bounds->data.F32[i-1] + 1.0;
    899917        }
     918# endif
    900919       
    901920        if (psTraceGetLevel("psLib.math") >= 8) {
     
    10511070        if (sigma < (3.0 * binSize)) {
    10521071            psTrace(TRACE, 6, "*************: Do another iteration (%f %f).\n", sigma, binSize);
    1053             long maskLo = PS_MAX(0, (binMedian - 25)); // Low index for masking region
    1054             long maskHi = PS_MIN(histogram->bounds->n - 1, (binMedian + 25)); // High index for masking
    1055             psF32 medianLo = histogram->bounds->data.F32[maskLo]; // Value at low index
    1056             psF32 medianHi = histogram->bounds->data.F32[maskHi]; // Value at high index
     1072
     1073            // these limits are supposed to be 25 x the raw bin size, NOT 25 of the cumulative histogram bins
     1074            psF32 medianLo = stats->robustMedian - 25*binSize;
     1075            psF32 medianHi = stats->robustMedian + 25*binSize;
     1076
     1077            // long maskLo = PS_MAX(0, (binMedian - 25)); // Low index for masking region
     1078            // long maskHi = PS_MIN(cumulative->bounds->n - 1, (binMedian + 25)); // High index for masking
     1079            // psF32 medianLo = cumulative->bounds->data.F32[maskLo]; // Value at low index
     1080            // psF32 medianHi = cumulative->bounds->data.F32[maskHi]; // Value at high index
    10571081            psTrace(TRACE, 6, "Masking data more than 25 bins from the median\n");
    1058             psTrace(TRACE, 6,
    1059                     "The median is at bin number %ld.  We mask bins outside the bin range (%ld:%ld)\n",
    1060                     binMedian, maskLo, maskHi);
     1082            // psTrace(TRACE, 6, "The median is at bin number %ld.  We mask bins outside the bin range (%ld:%ld)\n", binMedian, maskLo, maskHi);
    10611083            psTrace(TRACE, 6, "Masking data outside (%f %f)\n", medianLo, medianHi);
     1084            int Nmasked = 0;
    10621085            for (long i = 0 ; i < myVector->n ; i++) {
    10631086                if ((myVector->data.F32[i] < medianLo) || (myVector->data.F32[i] > medianHi)) {
    1064                     // XXXX is this correct?  is MASK_MARK safe?
     1087                    if (mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & MASK_MARK) continue;
    10651088                    mask->data.PS_TYPE_VECTOR_MASK_DATA[i] |= MASK_MARK;
    10661089                    psTrace(TRACE, 6, "Masking element %ld is %f\n", i, myVector->data.F32[i]);
     1090                    Nmasked ++;
    10671091                }
    10681092            }
     1093
     1094            if (Nmasked == 0) {
     1095                // no significant change to the sigma & binsize -- we are done here
     1096                iterate = -1;
     1097                continue;
     1098            }
    10691099
    10701100            // Free the histograms; they will be recreated on the next iteration, with new bounds
     
    11081138    PS_BIN_FOR_VALUE (binLo25, cumulative->nums, totalDataPoints * 0.25f, 0);
    11091139    PS_BIN_FOR_VALUE (binHi25, cumulative->nums, totalDataPoints * 0.75f, 0);
    1110     psTrace(TRACE, 6, "The 25-percent and 75-precent data point bins are (%ld, %ld).\n", binLo25, binHi25);
     1140    psTrace(TRACE, 6, "The 25-percent and 75-percent data point bins are (%ld, %ld).\n", binLo25, binHi25);
    11111141
    11121142    // ADD step 8: Interpolate to find these two positions exactly: these are the upper and lower quartile
     
    25302560                 yVec->data.F32[binNum - 0] +
    25312561                 yVec->data.F32[binNum + 1] + yVec->data.F32[binNum + 2]);
    2532     double Sy = (xVec->data.F32[binNum - 2] + xVec->data.F32[binNum - 1] +
    2533                  xVec->data.F32[binNum - 0] +
    2534                  xVec->data.F32[binNum + 1] + xVec->data.F32[binNum + 2]);
     2562
     2563    double YM = 0.5*(xVec->data.F32[binNum - 2] + xVec->data.F32[binNum - 1]);
     2564    double Ym = 0.5*(xVec->data.F32[binNum - 1] + xVec->data.F32[binNum - 0]);
     2565    double Yo = 0.5*(xVec->data.F32[binNum - 0] + xVec->data.F32[binNum + 1]);
     2566    double Yp = 0.5*(xVec->data.F32[binNum + 1] + xVec->data.F32[binNum + 2]);
     2567    double YP = 0.5*(xVec->data.F32[binNum + 2] + xVec->data.F32[binNum + 3]);
     2568
     2569    double Sy = YM + Ym + Yo + Yp + YP;
     2570
    25352571    double Sxx = (PS_SQR(yVec->data.F32[binNum - 2]) + PS_SQR(yVec->data.F32[binNum - 1]) +
    25362572                  PS_SQR(yVec->data.F32[binNum - 0]) +
    25372573                  PS_SQR(yVec->data.F32[binNum + 1]) + PS_SQR(yVec->data.F32[binNum + 2]));
    2538     double Sxy = (xVec->data.F32[binNum - 2] * yVec->data.F32[binNum - 2] +
    2539                   xVec->data.F32[binNum - 1] * yVec->data.F32[binNum - 1] +
    2540                   xVec->data.F32[binNum - 0] * yVec->data.F32[binNum - 0] +
    2541                   xVec->data.F32[binNum + 1] * yVec->data.F32[binNum + 1] +
    2542                   xVec->data.F32[binNum + 2] * yVec->data.F32[binNum + 2]);
    2543     double value = ((Sy * Sxx - Sx * Sxy) + (5 * Sxy - Sx * Sy) * yVal)/(5 * Sxx - Sx * Sx);
     2574
     2575    double Sxy = (yVec->data.F32[binNum - 2] * YM +
     2576                  yVec->data.F32[binNum - 1] * Ym +
     2577                  yVec->data.F32[binNum - 0] * Yo +
     2578                  yVec->data.F32[binNum + 1] * Yp +
     2579                  yVec->data.F32[binNum + 2] * YP);
     2580
     2581    double Det = 5*Sxx - Sx*Sx;
     2582    if (Det == 0.0) return NAN;
     2583
     2584    double C0 = (Sy*Sxx - Sx*Sxy) / Det;
     2585    double C1 = (Sxy*5 - Sx*Sy) / Det;
     2586
     2587    double value = C0 + yVal*C1;
    25442588
    25452589    return value;
Note: See TracChangeset for help on using the changeset viewer.