IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Sep 13, 2024, 10:19:51 PM (22 months ago)
Author:
hgao
Message:

finetune overscan region and stats for reducing and smoothing overscan array/vector

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2dbias/psLib/src/math/psStats.c

    r41520 r42719  
    1919 */
    2020
    21 
    2221// Note: choice of return values in many places is quite grey.  For example, calculating the sample standard
    2322// deviation: here it's an error to get an array of size zero, but it's not an error to get an array of size
     
    6362#include "psString.h"
    6463
    65 
    66 
    6764/*****************************************************************************/
    6865/* DEFINE STATEMENTS                                                         */
    6966/*****************************************************************************/
    70 #define PS_GAUSS_WIDTH 3                // The width of the Gaussian smoothing.
     67#define PS_GAUSS_WIDTH 3         // The width of the Gaussian smoothing.
    7168#define PS_CLIPPED_NUM_ITER_LB 1 // This corresponds to N in the ADD.
    7269#define PS_CLIPPED_NUM_ITER_UB 10
     
    7774#define TRACE "psLib.math"
    7875
    79 #define MASK_MARK 0x80   // XXX : can we change this? bit to use internally to mark data as bad
    80 #define PS_ROBUST_MAX_ITERATIONS 20     // Maximum number of iterations for robust statistics
     76#define MASK_MARK 0x80              // XXX : can we change this? bit to use internally to mark data as bad
     77#define PS_ROBUST_MAX_ITERATIONS 20 // Maximum number of iterations for robust statistics
    8178
    8279#define PS_BIN_MIDPOINT(HISTOGRAM, BIN_NUM) \
    83 (0.5 * (HISTOGRAM->bounds->data.F32[(BIN_NUM)] + HISTOGRAM->bounds->data.F32[(BIN_NUM)+1]))
     80    (0.5 * (HISTOGRAM->bounds->data.F32[(BIN_NUM)] + HISTOGRAM->bounds->data.F32[(BIN_NUM) + 1]))
    8481
    8582// set the bin closest to the corresponding value.  if USE_END is +/- 1,
    8683// out-of-range saturates on lower/upper bin REGARDLESS of actual value
    87 #define PS_BIN_FOR_VALUE(RESULT, VECTOR, VALUE, USE_END) { \
    88         psVectorBinaryDisectResult result; \
    89         psScalar tmpScalar; \
    90         tmpScalar.type.type = PS_TYPE_F32; \
    91         tmpScalar.data.F32 = (VALUE); \
    92         RESULT = psVectorBinaryDisect (&result, VECTOR, &tmpScalar); \
    93         switch (result) { \
    94           case PS_BINARY_DISECT_PASS: \
    95             break; \
    96           case PS_BINARY_DISECT_OUTSIDE_RANGE: \
    97             psTrace(TRACE, 6, "selected bin outside range"); \
    98             if (USE_END == -1) { RESULT = 0; } \
    99             if (USE_END == +1) { RESULT = VECTOR->n - 1; } \
    100             break; \
    101           case PS_BINARY_DISECT_INVALID_INPUT: \
    102           case PS_BINARY_DISECT_INVALID_TYPE: \
    103             psAbort ("programming error"); \
    104             break; \
    105         } }
    106 
    107 # define PS_BIN_INTERPOLATE(RESULT, VECTOR, BOUNDS, BIN, VALUE) { \
    108         float dX, dY, Xo, Yo, Xt; \
    109         if (BIN == BOUNDS->n - 1) { \
    110             dX = 0.5*(BOUNDS->data.F32[BIN+1] - BOUNDS->data.F32[BIN-1]); \
    111             dY = VECTOR->data.F32[BIN] - VECTOR->data.F32[BIN-1]; \
    112             Xo = 0.5*(BOUNDS->data.F32[BIN+1] + BOUNDS->data.F32[BIN]); \
    113             Yo = VECTOR->data.F32[BIN]; \
    114         } else { \
    115             dX = 0.5*(BOUNDS->data.F32[BIN+2] - BOUNDS->data.F32[BIN]); \
    116             dY = VECTOR->data.F32[BIN+1] - VECTOR->data.F32[BIN]; \
    117             Xo = 0.5*(BOUNDS->data.F32[BIN+1] + BOUNDS->data.F32[BIN]); \
    118             Yo = VECTOR->data.F32[BIN]; \
    119         } \
    120         if (dY != 0) { \
    121             Xt = (VALUE - Yo)*dX/dY + Xo; \
    122         } else { \
    123             Xt = Xo; \
    124         } \
    125         Xt = PS_MIN (BOUNDS->data.F32[BIN+1], PS_MAX(BOUNDS->data.F32[BIN], Xt)); \
     84#define PS_BIN_FOR_VALUE(RESULT, VECTOR, VALUE, USE_END)            \
     85    {                                                               \
     86        psVectorBinaryDisectResult result;                          \
     87        psScalar tmpScalar;                                         \
     88        tmpScalar.type.type = PS_TYPE_F32;                          \
     89        tmpScalar.data.F32 = (VALUE);                               \
     90        RESULT = psVectorBinaryDisect(&result, VECTOR, &tmpScalar); \
     91        switch (result)                                             \
     92        {                                                           \
     93        case PS_BINARY_DISECT_PASS:                                 \
     94            break;                                                  \
     95        case PS_BINARY_DISECT_OUTSIDE_RANGE:                        \
     96            psTrace(TRACE, 6, "selected bin outside range");        \
     97            if (USE_END == -1)                                      \
     98            {                                                       \
     99                RESULT = 0;                                         \
     100            }                                                       \
     101            if (USE_END == +1)                                      \
     102            {                                                       \
     103                RESULT = VECTOR->n - 1;                             \
     104            }                                                       \
     105            break;                                                  \
     106        case PS_BINARY_DISECT_INVALID_INPUT:                        \
     107        case PS_BINARY_DISECT_INVALID_TYPE:                         \
     108            psAbort("programming error");                           \
     109            break;                                                  \
     110        }                                                           \
     111    }
     112
     113#define PS_BIN_INTERPOLATE(RESULT, VECTOR, BOUNDS, BIN, VALUE)                             \
     114    {                                                                                      \
     115        float dX, dY, Xo, Yo, Xt;                                                          \
     116        if (BIN == BOUNDS->n - 1)                                                          \
     117        {                                                                                  \
     118            dX = 0.5 * (BOUNDS->data.F32[BIN + 1] - BOUNDS->data.F32[BIN - 1]);            \
     119            dY = VECTOR->data.F32[BIN] - VECTOR->data.F32[BIN - 1];                        \
     120            Xo = 0.5 * (BOUNDS->data.F32[BIN + 1] + BOUNDS->data.F32[BIN]);                \
     121            Yo = VECTOR->data.F32[BIN];                                                    \
     122        }                                                                                  \
     123        else                                                                               \
     124        {                                                                                  \
     125            dX = 0.5 * (BOUNDS->data.F32[BIN + 2] - BOUNDS->data.F32[BIN]);                \
     126            dY = VECTOR->data.F32[BIN + 1] - VECTOR->data.F32[BIN];                        \
     127            Xo = 0.5 * (BOUNDS->data.F32[BIN + 1] + BOUNDS->data.F32[BIN]);                \
     128            Yo = VECTOR->data.F32[BIN];                                                    \
     129        }                                                                                  \
     130        if (dY != 0)                                                                       \
     131        {                                                                                  \
     132            Xt = (VALUE - Yo) * dX / dY + Xo;                                              \
     133        }                                                                                  \
     134        else                                                                               \
     135        {                                                                                  \
     136            Xt = Xo;                                                                       \
     137        }                                                                                  \
     138        Xt = PS_MIN(BOUNDS->data.F32[BIN + 1], PS_MAX(BOUNDS->data.F32[BIN], Xt));         \
    126139        psTrace(TRACE, 6, "(Xo, Yo, dX, dY, Xt, Yt) is (%.2f %.2f %.2f %.2f %.2f %.2f)\n", \
    127                 Xo, Yo, dX, dY, Xt, VALUE); \
    128         RESULT = Xt; }
    129 
    130 # define COUNT_WARNING(LIMIT, INTERVAL, ...) { \
    131         static int nCalls = 1; \
    132         if (nCalls < LIMIT) { \
    133             psWarning(__VA_ARGS__); \
    134         } \
    135         if (!(nCalls % INTERVAL)) { \
    136             psWarning(__VA_ARGS__); \
     140                Xo, Yo, dX, dY, Xt, VALUE);                                                \
     141        RESULT = Xt;                                                                       \
     142    }
     143
     144#define COUNT_WARNING(LIMIT, INTERVAL, ...)                 \
     145    {                                                       \
     146        static int nCalls = 1;                              \
     147        if (nCalls < LIMIT)                                 \
     148        {                                                   \
     149            psWarning(__VA_ARGS__);                         \
     150        }                                                   \
     151        if (!(nCalls % INTERVAL))                           \
     152        {                                                   \
     153            psWarning(__VA_ARGS__);                         \
    137154            psWarning("(warning raised %d times)", nCalls); \
    138         } \
    139         nCalls ++; \
    140 }
     155        }                                                   \
     156        nCalls++;                                          \
     157    }
    141158
    142159// Debug information
     
    195212To optmize this, use a macro and ifdef in or out the three states (errors, mask, range)
    196213*****************************************************************************/
    197     static bool vectorSampleMean(const psVector* myVector,
    198                                  const psVector* errors,
    199                                  const psVector* maskVector,
    200                                  psVectorMaskType maskVal,
    201                                  psStats* stats)
     214static bool vectorSampleMean(const psVector *myVector,
     215                             const psVector *errors,
     216                             const psVector *maskVector,
     217                             psVectorMaskType maskVal,
     218                             psStats *stats)
    202219{
    203     long count = 0;                     // Number of points contributing to this mean
    204     psF32 mean = 0.0;                   // The mean
     220    long count = 0;   // Number of points contributing to this mean
     221    psF32 mean = 0.0; // The mean
    205222    psF32 weight;
    206223
    207     psF32 *data = myVector->data.F32;   // Dereference
    208     int numData = myVector->n;          // Number of data points
     224    psF32 *data = myVector->data.F32; // Dereference
     225    int numData = myVector->n;        // Number of data points
    209226
    210227    psVectorMaskType *maskData = (maskVector == NULL) ? NULL : maskVector->data.PS_TYPE_VECTOR_MASK_DATA;
    211228    bool useRange = stats->options & PS_STAT_USE_RANGE;
    212229
    213     psF32 sumWeights = 0.0;  // The sum of the weights
     230    psF32 sumWeights = 0.0; // The sum of the weights
    214231    psF32 *errorsData = (errors == NULL) ? NULL : errors->data.F32;
    215232
    216     for (long i = 0; i < numData; i++) {
     233    for (long i = 0; i < numData; i++)
     234    {
    217235        // Check if the data is with the specified range
    218236        if (!isfinite(data[i]))
     
    224242        if (maskData && (maskData[i] & maskVal))
    225243            continue;
    226         if (errors) {
     244        if (errors)
     245        {
    227246            weight = (errorsData[i] == 0) ? 0.0 : PS_SQR(errorsData[i]);
    228247            mean += data[i] * weight;
    229248            sumWeights += weight;
    230         } else {
     249        }
     250        else
     251        {
    231252            mean += data[i];
    232253        }
    233254        count++;
    234 
    235     }
    236     if (errors) {
     255    }
     256    if (errors)
     257    {
    237258        mean = (count > 0) ? mean / sumWeights : NAN;
    238     } else {
     259    }
     260    else
     261    {
    239262        mean = (count > 0) ? mean / count : NAN;
    240263    }
    241264    stats->sampleMean = mean;
    242265
    243     if (!isnan(mean)) {
     266    if (!isnan(mean))
     267    {
    244268        stats->results |= PS_STAT_SAMPLE_MEAN;
    245269    }
     
    260284(mask: 1, range: 0):  0.200 sec  0.244 sec
    261285*****************************************************************************/
    262     static long vectorMinMax(const psVector* myVector,
    263                              const psVector* maskVector,
    264                              psVectorMaskType maskVal,
    265                              psStats* stats
    266         )
     286static long vectorMinMax(const psVector *myVector,
     287                         const psVector *maskVector,
     288                         psVectorMaskType maskVal,
     289                         psStats *stats)
    267290{
    268291    psF32 max = -PS_MAX_F32;            // The calculated maximum
     
    270293    psF32 *vector = myVector->data.F32; // Dereference the vector
    271294
    272     int num = myVector->n;              // Number of values
    273     int numValid = 0;                   // Number of valid values
     295    int num = myVector->n; // Number of values
     296    int numValid = 0;      // Number of valid values
    274297
    275298    psVectorMaskType *maskData = (maskVector == NULL) ? NULL : maskVector->data.PS_TYPE_VECTOR_MASK_DATA;
    276299    bool useRange = stats->options & PS_STAT_USE_RANGE;
    277300
    278     for (long i = 0; i < num; i++) {
     301    for (long i = 0; i < num; i++)
     302    {
    279303        // Check if the data is with the specified range
    280304        if (!isfinite(vector[i]))
     
    288312
    289313        numValid++;
    290         max = PS_MAX (vector[i], max);
    291         min = PS_MIN (vector[i], min);
     314        max = PS_MAX(vector[i], max);
     315        min = PS_MIN(vector[i], min);
    292316    }
    293317
    294318    // XXX save numValid in psStats?
    295     if (numValid == 0) {
     319    if (numValid == 0)
     320    {
    296321        stats->max = NAN;
    297322        stats->min = NAN;
    298     } else {
     323    }
     324    else
     325    {
    299326        stats->max = max;
    300327        stats->min = min;
     
    310337were no valid input vector elements). Expects F32 vector for input.
    311338*****************************************************************************/
    312 static bool vectorSampleMedian(const psVector* inVector,
    313                                const psVector* maskVector,
     339static bool vectorSampleMedian(const psVector *inVector,
     340                               const psVector *maskVector,
    314341                               psVectorMaskType maskVal,
    315                                psStats* stats)
     342                               psStats *stats)
    316343{
    317344    bool useRange = stats->options & PS_STAT_USE_RANGE;
    318345    psVectorMaskType *maskData = (maskVector == NULL) ? NULL : maskVector->data.PS_TYPE_VECTOR_MASK_DATA; // Dereference the vector
    319     psF32 *input = inVector->data.F32; // Dereference the vector
     346    psF32 *input = inVector->data.F32;                                                                    // Dereference the vector
    320347
    321348    // use the temporary vector for the sorted output
    322     stats->tmpData = psVectorRecycle (stats->tmpData, inVector->n, PS_TYPE_F32);
     349    stats->tmpData = psVectorRecycle(stats->tmpData, inVector->n, PS_TYPE_F32);
    323350    psVector *outVector = stats->tmpData;
    324351    psF32 *output = outVector->data.F32; // Dereference the vector
    325352
    326     if (maskData) psAssert (maskVector->n == inVector->n, "oops");
    327 
    328     long count = 0;                     // Number of valid entries
     353    if (maskData)
     354        psAssert(maskVector->n == inVector->n, "oops");
     355
     356    long count = 0; // Number of valid entries
    329357
    330358    // Store all non-masked data points within the min/max range
    331359    // into the temporary vectors.
    332     for (long i = 0; i < inVector->n; i++) {
    333         psAssert (count >= 0, "oops");
    334         psAssert (count < outVector->n, "oops");
    335         psAssert (i >= 0, "oops");
    336         psAssert (i < inVector->n, "oops");
    337 
    338         if (!isfinite(input[i])) continue;
    339         if (useRange && (input[i] < stats->min)) continue;
    340         if (useRange && (input[i] > stats->max)) continue;
    341         if (maskData && (maskData[i] & maskVal)) continue;
     360    for (long i = 0; i < inVector->n; i++)
     361    {
     362        psAssert(count >= 0, "oops");
     363        psAssert(count < outVector->n, "oops");
     364        psAssert(i >= 0, "oops");
     365        psAssert(i < inVector->n, "oops");
     366
     367        if (!isfinite(input[i]))
     368            continue;
     369        if (useRange && (input[i] < stats->min))
     370            continue;
     371        if (useRange && (input[i] > stats->max))
     372            continue;
     373        if (maskData && (maskData[i] & maskVal))
     374            continue;
    342375
    343376        output[count] = input[i];
     
    346379    outVector->n = count;
    347380
    348     if (count == 0) {
     381    if (count == 0)
     382    {
    349383        COUNT_WARNING(10, 100, "No valid data in input vector.\n");
    350384        stats->sampleUQ = NAN;
     
    355389
    356390    // Sort the temporary vector.
    357     if (!psVectorSort(outVector, outVector)) { // Sort in-place (since it's a copy, it's OK)
     391    if (!psVectorSort(outVector, outVector))
     392    { // Sort in-place (since it's a copy, it's OK)
    358393        // an error in psVectorSort is a serious error:
    359         // NULL input vector, psVectorCopy failure, invalid vector type
     394        // NULL input vector, psVectorCopy failure, invalid vector type
    360395        psError(PS_ERR_UNEXPECTED_NULL, false, _("Failed to sort input data."));
    361396        stats->sampleUQ = NAN;
     
    366401
    367402    // Calculate the median.  Use the average if the number of samples if even.
    368     int midPt = (count/2);
    369     psAssert (midPt >=           0, "oops");
    370     psAssert (midPt < outVector->n, "oops");
    371     if (count % 2 == 0) {
    372         psAssert ((midPt - 1) >=           0, "oops");
    373         psAssert ((midPt - 1) < outVector->n, "oops");
     403    int midPt = (count / 2);
     404    psAssert(midPt >= 0, "oops");
     405    psAssert(midPt < outVector->n, "oops");
     406    if (count % 2 == 0)
     407    {
     408        psAssert((midPt - 1) >= 0, "oops");
     409        psAssert((midPt - 1) < outVector->n, "oops");
    374410        stats->sampleMedian = 0.5 * (output[midPt - 1] + output[midPt]);
    375     } else {
     411    }
     412    else
     413    {
    376414        stats->sampleMedian = output[midPt];
    377415    }
    378416
    379     int Qmin = (int)(0.25*count);
    380     int Qmax = (int)(0.75*count);
    381     psAssert (Qmin >=          0, "oops");
    382     psAssert (Qmin < outVector->n, "oops");
    383     psAssert (Qmax >=          0, "oops");
    384     psAssert (Qmax < outVector->n, "oops");
     417    int Qmin = (int)(0.25 * count);
     418    int Qmax = (int)(0.75 * count);
     419    psAssert(Qmin >= 0, "oops");
     420    psAssert(Qmin < outVector->n, "oops");
     421    psAssert(Qmax >= 0, "oops");
     422    psAssert(Qmax < outVector->n, "oops");
    385423
    386424    // Calculate the quartile points exactly.
    387425    stats->sampleUQ = output[Qmax];
    388426    stats->sampleLQ = output[Qmin];
    389      
     427
    390428    stats->results |= PS_STAT_SAMPLE_MEDIAN;
    391429    stats->results |= PS_STAT_SAMPLE_QUARTILE;
     
    409447*****************************************************************************/
    410448
    411 static bool vectorSampleStdev(const psVector* myVector,
    412                               const psVector* errors,
    413                               const psVector* maskVector,
     449static bool vectorSampleStdev(const psVector *myVector,
     450                              const psVector *errors,
     451                              const psVector *maskVector,
    414452                              psVectorMaskType maskVal,
    415                               psStats* stats)
     453                              psStats *stats)
    416454{
    417455    // This procedure requires the mean.  If it has not been already
    418456    // calculated, then call vectorSampleMean()
    419     if (!(stats->results & PS_STAT_SAMPLE_MEAN)) {
     457    if (!(stats->results & PS_STAT_SAMPLE_MEAN))
     458    {
    420459        vectorSampleMean(myVector, errors, maskVector, maskVal, stats);
    421460    }
    422461
    423462    // If the mean is NAN, then generate a warning and set the stdev to NAN.
    424     if (isnan(stats->sampleMean)) {
     463    if (isnan(stats->sampleMean))
     464    {
    425465        COUNT_WARNING(10, 100, "WARNING: vectorSampleStdev(): sample mean is NAN. Setting stats->sampleStdev = NAN.");
    426466        stats->sampleStdev = NAN;
     
    428468    }
    429469
    430     psF32 *data = myVector->data.F32;   // Dereference
     470    psF32 *data = myVector->data.F32; // Dereference
    431471    psVectorMaskType *maskData = (maskVector == NULL) ? NULL : maskVector->data.PS_TYPE_VECTOR_MASK_DATA;
    432472    bool useRange = stats->options & PS_STAT_USE_RANGE;
     
    434474
    435475    // Accumulate the sums
    436     double mean = stats->sampleMean;    // The mean
    437     double sumSquares = 0.0;            // Sum of the squares
    438     double sumDiffs = 0.0;              // Sum of the differences
    439     double errorDivisor = 0.0;          // Division for errors
    440     long count = 0;                     // Number of data points being used
    441     for (long i = 0; i < myVector->n; i++) {
     476    double mean = stats->sampleMean; // The mean
     477    double sumSquares = 0.0;         // Sum of the squares
     478    double sumDiffs = 0.0;           // Sum of the differences
     479    double errorDivisor = 0.0;       // Division for errors
     480    long count = 0;                  // Number of data points being used
     481    for (long i = 0; i < myVector->n; i++)
     482    {
    442483        // Check if the data is with the specified range
    443484        if (!isfinite(data[i]))
    444485            continue;
    445         if (useRange && (data[i] < stats->min)) {
     486        if (useRange && (data[i] < stats->min))
     487        {
    446488            continue;
    447489        }
    448         if (useRange && (data[i] > stats->max)) {
     490        if (useRange && (data[i] > stats->max))
     491        {
    449492            continue;
    450493        }
    451         if (maskData && (maskData[i] & maskVal)) {
     494        if (maskData && (maskData[i] & maskVal))
     495        {
    452496            continue;
    453497        }
     
    457501        sumDiffs += diff;
    458502        count++;
    459         if (errors) {
     503        if (errors)
     504        {
    460505            errorDivisor += 1.0 / PS_SQR(errorsData[i]);
    461506        }
    462507    }
    463508
    464     if (count == 0) {
     509    if (count == 0)
     510    {
    465511        // This is an ambiguous case: error or not?
    466512        // It's not an empty array (that's been asserted on previously), but everything's been masked out.
     
    470516        return true;
    471517    }
    472     if (count == 1) {
     518    if (count == 1)
     519    {
    473520        stats->sampleStdev = 0.0;
    474521        COUNT_WARNING(10, 100, "WARNING: vectorSampleStdev(): only one valid psVector elements (%ld). Setting stats->sampleStdev = 0.0.\n", count);
     
    476523    }
    477524
    478     if (errors) {
     525    if (errors)
     526    {
    479527        stats->sampleStdev = (1.0 / sqrtf(errorDivisor));
    480     } else {
     528    }
     529    else
     530    {
    481531        stats->sampleStdev = sqrt((sumSquares - (sumDiffs * sumDiffs / (float)count)) / (float)(count - 1));
    482532    }
     
    486536}
    487537
    488 static bool vectorSampleMoments(const psVector* myVector,
    489                                 const psVector* maskVector,
     538static bool vectorSampleMoments(const psVector *myVector,
     539                                const psVector *maskVector,
    490540                                psVectorMaskType maskVal,
    491                                 psStats* stats)
     541                                psStats *stats)
    492542{
    493543    // This procedure requires the mean and standard deviation
    494     if (!(stats->results & PS_STAT_SAMPLE_MEAN)) {
     544    if (!(stats->results & PS_STAT_SAMPLE_MEAN))
     545    {
    495546        vectorSampleMean(myVector, NULL, maskVector, maskVal, stats);
    496547    }
    497     if (isnan(stats->sampleMean)) {
     548    if (isnan(stats->sampleMean))
     549    {
    498550        COUNT_WARNING(10, 100, "WARNING: vectorSampleMoments(): sample mean is NAN.\n");
    499551        goto SAMPLE_MOMENTS_BAD;
    500552    }
    501     if (!(stats->results & PS_STAT_SAMPLE_STDEV)) {
     553    if (!(stats->results & PS_STAT_SAMPLE_STDEV))
     554    {
    502555        vectorSampleStdev(myVector, NULL, maskVector, maskVal, stats);
    503556    }
    504     if (isnan(stats->sampleStdev) || stats->sampleStdev == 0.0) {
     557    if (isnan(stats->sampleStdev) || stats->sampleStdev == 0.0)
     558    {
    505559        COUNT_WARNING(10, 100, "WARNING: vectorSampleMoments(): sample stdev is NAN or 0.\n");
    506560        goto SAMPLE_MOMENTS_BAD;
    507561    }
    508562
    509     psF32 *data = myVector->data.F32;   // Dereference
     563    psF32 *data = myVector->data.F32; // Dereference
    510564    psVectorMaskType *maskData = (maskVector == NULL) ? NULL : maskVector->data.PS_TYPE_VECTOR_MASK_DATA;
    511565    bool useRange = stats->options & PS_STAT_USE_RANGE;
    512566
    513567    // Accumulate the sums
    514     double mean = stats->sampleMean;    // The mean
    515     double sum3 = 0.0;                  // Sum of the cubes of the differences
    516     double sum4 = 0.0;                  // Sum of the fourth powers of the differences
    517     long count = 0;                     // Number of data points being used
    518     for (long i = 0; i < myVector->n; i++) {
     568    double mean = stats->sampleMean; // The mean
     569    double sum3 = 0.0;               // Sum of the cubes of the differences
     570    double sum4 = 0.0;               // Sum of the fourth powers of the differences
     571    long count = 0;                  // Number of data points being used
     572    for (long i = 0; i < myVector->n; i++)
     573    {
    519574        // Check if the data is with the specified range
    520575        if (!isfinite(data[i]))
    521576            continue;
    522         if (useRange && (data[i] < stats->min)) {
     577        if (useRange && (data[i] < stats->min))
     578        {
    523579            continue;
    524580        }
    525         if (useRange && (data[i] > stats->max)) {
     581        if (useRange && (data[i] > stats->max))
     582        {
    526583            continue;
    527584        }
    528         if (maskData && (maskData[i] & maskVal)) {
     585        if (maskData && (maskData[i] & maskVal))
     586        {
    529587            continue;
    530588        }
    531589
    532         double diff = data[i] - mean;   // Difference from the mean
    533         double temp;                    // Temporary variable for accumulating
     590        double diff = data[i] - mean; // Difference from the mean
     591        double temp;                  // Temporary variable for accumulating
    534592
    535593        sum3 += temp = PS_SQR(diff);
     
    539597    }
    540598
    541     psAssert(count > 1, "impossible");                  // It should be, because we have a mean and standard deviation
    542 
    543     double stdev = stats->sampleStdev;  // Standard deviation
    544     double variance = PS_SQR(stdev);    // Variance
     599    psAssert(count > 1, "impossible"); // It should be, because we have a mean and standard deviation
     600
     601    double stdev = stats->sampleStdev; // Standard deviation
     602    double variance = PS_SQR(stdev);   // Variance
    545603
    546604    // Formula for skewness and kurtosis from Numerical Recipes in C, p 613.
     
    552610    return true;
    553611
    554  SAMPLE_MOMENTS_BAD:
     612SAMPLE_MOMENTS_BAD:
    555613    // stats->sampleStdev has already been set
    556614    stats->sampleSkewness = NAN;
     
    571629    true for success; false otherwise
    572630*****************************************************************************/
    573 static bool vectorClippedStats(const psVector* myVector,
    574                                const psVector* errors,
    575                                psVector* maskInput,
     631static bool vectorClippedStats(const psVector *myVector,
     632                               const psVector *errors,
     633                               psVector *maskInput,
    576634                               psVectorMaskType maskValInput,
    577                                psStats* stats
    578     )
     635                               psStats *stats)
    579636{
    580637    // Ensure that stats->clipIter is within the proper range.
     
    590647    // unless we succeed, these will have NAN values
    591648    stats->clippedMean = NAN;
     649    stats->clippedMedian = NAN;
    592650    stats->clippedStdev = NAN;
    593651    stats->clippedNvalues = 0;
     
    597655
    598656    // use the temporary vector for local temporary mask
    599     stats->tmpMask = psVectorRecycle (stats->tmpMask, myVector->n, PS_TYPE_VECTOR_MASK);
     657    stats->tmpMask = psVectorRecycle(stats->tmpMask, myVector->n, PS_TYPE_VECTOR_MASK);
    600658    psVector *tmpMask = stats->tmpMask;
    601659    psVectorInit(tmpMask, 0);
    602     if (maskInput) {
    603         for (long i = 0; i < myVector->n; i++) {
    604             if (maskInput->data.PS_TYPE_VECTOR_MASK_DATA[i] & maskValInput) {
     660    if (maskInput)
     661    {
     662        for (long i = 0; i < myVector->n; i++)
     663        {
     664            if (maskInput->data.PS_TYPE_VECTOR_MASK_DATA[i] & maskValInput)
     665            {
    605666                tmpMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = maskVal;
    606667            }
     
    610671    // 1. Compute the sample median, which we save for output
    611672    vectorSampleMedian(myVector, tmpMask, maskVal, stats);
    612     if (isnan(stats->sampleMedian)) {
     673    if (isnan(stats->sampleMedian))
     674    {
    613675        COUNT_WARNING(10, 100, "Call to vectorSampleMedian returned NAN\n");
    614676        return true;
     
    618680    // 2. Compute the sample standard deviation, which we save for output
    619681    vectorSampleStdev(myVector, errors, tmpMask, maskVal, stats);
    620     if (isnan(stats->sampleStdev)) {
     682    if (isnan(stats->sampleStdev))
     683    {
    621684        COUNT_WARNING(10, 100, "Call to vectorSampleStdev returned NAN\n");
    622685        return true;
     
    625688
    626689    // 3. Use the sample median as the first estimator of the mean X.
    627     psF32 clippedMean = stats->sampleMedian;
    628 
     690    psF32 clippedMedian = stats->sampleMedian;
     691   
    629692    // 4. Use the sample stdev as the first estimator of the mean stdev.
    630693    psF32 clippedStdev = stats->sampleStdev;
    631694
    632695    // 5. Repeat N (stats->clipIter) times:
    633     long numClipped = 0;                // Number of values clipped
    634     bool clipped = true;                // Have we clipped anything in this iteration
    635     for (int iter = 0; iter < stats->clipIter && clipped; iter++) {
     696    long numClipped = 0; // Number of values clipped
     697    bool clipped = true; // Have we clipped anything in this iteration
     698    for (int iter = 0; iter < stats->clipIter && clipped; iter++)
     699    {
    636700        clipped = false;
    637701        psTrace(TRACE, 6, "------------ Iteration %d ------------\n", iter);
    638702        // a) Exclude all values x_i for which |x_i - x| > K * stdev
    639         if (errors) {
     703        if (errors)
     704        {
    640705            // XXXX if we convert errors to variance, this should square the other terms (A*A faster than
    641706            // sqrt(A))
    642             for (long j = 0; j < myVector->n; j++) {
     707            for (long j = 0; j < myVector->n; j++)
     708            {
    643709                if (!tmpMask->data.PS_TYPE_VECTOR_MASK_DATA[j] &&
    644                     fabsf(myVector->data.F32[j] - clippedMean) > stats->clipSigma * errors->data.F32[j]) {
     710                    fabsf(myVector->data.F32[j] - clippedMedian) > stats->clipSigma * errors->data.F32[j])
     711                {
    645712                    tmpMask->data.PS_TYPE_VECTOR_MASK_DATA[j] = 0xff;
    646713                    psTrace(TRACE, 10, "Clipped %ld: %f +/- %f\n", j,
     
    650717                }
    651718            }
    652         } else {
    653             for (long j = 0; j < myVector->n; j++) {
     719        }
     720        else
     721        {
     722            for (long j = 0; j < myVector->n; j++)
     723            {
    654724                if (!tmpMask->data.PS_TYPE_VECTOR_MASK_DATA[j] &&
    655                     fabsf(myVector->data.F32[j] - clippedMean) > (stats->clipSigma * clippedStdev)) {
     725                    fabsf(myVector->data.F32[j] - clippedMedian) > (stats->clipSigma * clippedStdev))
     726                {
    656727                    tmpMask->data.PS_TYPE_VECTOR_MASK_DATA[j] = 0xff;
    657728                    psTrace(TRACE, 10, "Clipped %ld: %f\n", j, myVector->data.F32[j]);
     
    662733        }
    663734
    664         // b) compute new mean and stdev
     735        // b) compute new median and stdev
    665736        // Allocate a psStats structure for calculating the mean and stdev.
    666         // XXX Can we just use this psStats structure to calculate the SAMPLE MEAN and STDEV?
    667         // psStats *statsTmp = psStatsAlloc(PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV);
    668         // vectorSampleMean(myVector, errors, tmpMask, maskVal, statsTmp);
     737        // XXX Can we just use this psStats structure to calculate the SAMPLE MEDIAN and STDEV?
     738        // psStats *statsTmp = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV);
     739        // vectorSampleMedian(myVector, errors, tmpMask, maskVal, statsTmp);
    669740        // vectorSampleStdev(myVector, errors, tmpMask, maskVal, statsTmp);
    670         vectorSampleMean(myVector, errors, tmpMask, maskVal, stats);
     741        vectorSampleMedian(myVector, tmpMask, maskVal, stats);
    671742        vectorSampleStdev(myVector, errors, tmpMask, maskVal, stats);
    672         psTrace(TRACE, 6, "The new sample mean is %f\n", stats->sampleMean);
     743        psTrace(TRACE, 6, "The new sample mean is %f\n", stats->sampleMedian);
    673744        psTrace(TRACE, 6, "The new sample stdev is %f\n", stats->sampleStdev);
    674745
    675         // If the new mean and stdev are NAN, we must exit the loop.
     746        // If the new median and stdev are NAN, we must exit the loop.
    676747        // Otherwise, use the new results and continue.
    677         if (isnan(stats->sampleMean) || isnan(stats->sampleStdev)) {
     748        if (isnan(stats->sampleMedian) || isnan(stats->sampleStdev))
     749        {
    678750            iter = stats->clipIter;
    679             COUNT_WARNING(10, 100, "vectorSampleMean() or vectorSampleStdev() returned a NAN.\n");
    680             clippedMean = NAN;
     751            COUNT_WARNING(10, 100, "vectorSampleMedian() or vectorSampleStdev() returned a NAN.\n");
     752            clippedMedian = NAN;
    681753            clippedStdev = NAN;
    682754            return true;
    683         } else {
    684             clippedMean = stats->sampleMean;
     755        }
     756        else
     757        {
     758            clippedMedian = stats->sampleMedian;
    685759            clippedStdev = stats->sampleStdev;
    686760        }
     
    690764    // Number of values used in calculation is the total number of data values, minus those we clipped
    691765    stats->clippedNvalues = myVector->n - numClipped;
    692 
    693     // 7. The last calcuated value of x is the clipped mean.
     766    // calculate the clipped mean
     767    psF32 clippedMean = stats->sampleMean;
     768    vectorSampleMean(myVector, errors, tmpMask, maskVal, stats);
     769    if (isnan(stats->sampleMean))
     770    {
     771        COUNT_WARNING(10, 100, "vectorSampleMean() returned a NAN.\n");
     772        clippedMean = NAN;
     773        return true;
     774    }
     775    else
     776    {
     777        clippedMean = stats->sampleMean;
     778    }
     779
     780    // 7. The last calcuated value of x is the clipped median.
    694781    // 8. The last calcuated value of stdev is the clipped stdev.
    695     // we always return both stats even if only one was requested
     782    // we always return all stats even if only one was requested
    696783    stats->clippedMean = clippedMean;
     784    stats->clippedMedian = clippedMedian;
    697785    stats->clippedStdev = clippedStdev;
    698786
    699787    stats->results |= PS_STAT_CLIPPED_MEAN;
     788    stats->results |= PS_STAT_CLIPPED_MEDIAN;
    700789    stats->results |= PS_STAT_CLIPPED_STDEV;
    701790
    702791    psTrace(TRACE, 6, "The final clipped mean is %f\n", clippedMean);
     792    psTrace(TRACE, 6, "The final clipped median is %f\n", clippedMedian);
    703793    psTrace(TRACE, 6, "The final clipped stdev is %f\n", clippedStdev);
    704794
     
    725815*****************************************************************************/
    726816#define INITIAL_NUM_BINS 1000.0
    727 static bool vectorRobustStats(const psVector* myVector,
    728                               const psVector* errors,
    729                               psVector* maskInput,
     817static bool vectorRobustStats(const psVector *myVector,
     818                              const psVector *errors,
     819                              psVector *maskInput,
    730820                              psVectorMaskType maskValInput,
    731                               psStats* stats)
     821                              psStats *stats)
    732822{
    733     if (psTraceGetLevel("psLib.math") >= 8) {
     823    if (psTraceGetLevel("psLib.math") >= 8)
     824    {
    734825        PS_VECTOR_PRINT_F32(myVector);
    735826    }
     
    741832    psVector *mask = psVectorAlloc(myVector->n, PS_TYPE_VECTOR_MASK); // The actual mask we will use
    742833    psVectorInit(mask, 0);
    743     if (maskInput) {
    744         for (long i = 0; i < myVector->n; i++) {
    745             if (maskInput->data.PS_TYPE_VECTOR_MASK_DATA[i] & maskValInput) {
     834    if (maskInput)
     835    {
     836        for (long i = 0; i < myVector->n; i++)
     837        {
     838            if (maskInput->data.PS_TYPE_VECTOR_MASK_DATA[i] & maskValInput)
     839            {
    746840                mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = maskVal;
    747841            }
     
    751845    // statsMinMax is only applied to a subset of the data points
    752846    psStats *statsMinMax = psStatsAlloc(PS_STAT_MIN | PS_STAT_MAX); // Statistics for min and max
    753     psHistogram *histogram = NULL;      // Histogram of the data
    754     psHistogram *cumulative = NULL;     // Cumulative histogram of the data
    755     float min = NAN, max = NAN;         // Mimimum and maximum values
    756     float sigma = NAN;                  // The robust standard deviation
    757     long totalDataPoints = 0;           // Total number of (unmasked) data points
    758 
    759     float binSize = 0.0;            // Size of bins for histogram
     847    psHistogram *histogram = NULL;                                  // Histogram of the data
     848    psHistogram *cumulative = NULL;                                 // Cumulative histogram of the data
     849    float min = NAN, max = NAN;                                     // Mimimum and maximum values
     850    float sigma = NAN;                                              // The robust standard deviation
     851    long totalDataPoints = 0;                                       // Total number of (unmasked) data points
     852
     853    float binSize = 0.0; // Size of bins for histogram
    760854    long binLo, binHi;
    761855    long binL2, binH2;
     
    764858
    765859    // Iterate to get the best bin size; an iteration limit is enforced at the bottom of the loop.
    766     for (int iterate = 1; iterate > 0; iterate++) {
     860    for (int iterate = 1; iterate > 0; iterate++)
     861    {
    767862        psTrace(TRACE, 6, "-------------------- Iterating on Bin size.  Iteration number %d --------------------\n", iterate);
    768863
    769         if (iterate >= PS_ROBUST_MAX_ITERATIONS) {
    770           // This occurs when a large number of the values are identical --- a bin size cannot be found
    771           // that will spread out the distribution.  Therefore, set what we can, and fall over
    772           // gracefully.
    773           COUNT_WARNING(10, 100, "Maximum number of iterations (%d) exceeded.", PS_ROBUST_MAX_ITERATIONS);
    774           goto escape;
     864        if (iterate >= PS_ROBUST_MAX_ITERATIONS)
     865        {
     866            // This occurs when a large number of the values are identical --- a bin size cannot be found
     867            // that will spread out the distribution.  Therefore, set what we can, and fall over
     868            // gracefully.
     869            COUNT_WARNING(10, 100, "Maximum number of iterations (%d) exceeded.", PS_ROBUST_MAX_ITERATIONS);
     870            goto escape;
    775871        }
    776872
     
    779875        min = statsMinMax->min;
    780876        max = statsMinMax->max;
    781         if (numValid == 0 || isnan(min) || isnan(max)) {
     877        if (numValid == 0 || isnan(min) || isnan(max))
     878        {
    782879            // Data range calculation failed
    783880            COUNT_WARNING(10, 100, "Failed to calculate the min/max of the input vector.\n");
    784881            goto escape;
    785882        }
    786         if (!isfinite(max - min)) {
    787             COUNT_WARNING(10, 100, "Range of of the input vector is too large: %lf.\n", (double)max - (double) min);
     883        if (!isfinite(max - min))
     884        {
     885            COUNT_WARNING(10, 100, "Range of of the input vector is too large: %lf.\n", (double)max - (double)min);
    788886            goto escape;
    789887        }
     
    791889
    792890        // If all data points have the same value, then we set the appropriate members of stats and return.
    793         if (fabs(max - min) <= FLT_EPSILON) {
     891        if (fabs(max - min) <= FLT_EPSILON)
     892        {
    794893            stats->robustMedian = min;
    795894            stats->robustStdev = 0.0;
     
    807906        }
    808907
    809         if ((iterate == 1) && (stats->options & PS_STAT_USE_BINSIZE)) {
     908        if ((iterate == 1) && (stats->options & PS_STAT_USE_BINSIZE))
     909        {
    810910            // Set initial bin size to the specified value.
    811911            binSize = stats->binsize;
    812912            psTrace(TRACE, 6, "Setting initial robust bin size to %.2f\n", binSize);
    813         } else {
     913        }
     914        else
     915        {
    814916            // Determine the bin size of the robust histogram, using the pre-defined number of bins
    815             binSize = (max - min) / INITIAL_NUM_BINS;
     917            binSize = (max - min) / INITIAL_NUM_BINS;
    816918        }
    817919        psTrace(TRACE, 6, "Initial robust bin size is %.2f\n", binSize);
     
    830932        // Assert here so we can get more information about what is going wrong.
    831933        psAssert(numBins > 0, "Invalid numBins: %ld max: %f min: %f binSize: %f", numBins, max, min, binSize);
    832        
     934
    833935        // Generate the histogram
    834         histogram = psHistogramAlloc(min - 2.0*binSize, max + 2.0*binSize, numBins);
     936        histogram = psHistogramAlloc(min - 2.0 * binSize, max + 2.0 * binSize, numBins);
    835937        // XXXXX we need to consider this step if errors -> variance
    836         if (!psVectorHistogram(histogram, myVector, errors, mask, maskVal)) {
     938        if (!psVectorHistogram(histogram, myVector, errors, mask, maskVal))
     939        {
    837940            // if psVectorHistogram returns false, we have a programming error
    838941            psError(PS_ERR_UNKNOWN, false, "Unable to generate histogram for robust statistics.\n");
     
    843946            return false;
    844947        }
    845         if (psTraceGetLevel("psLib.math") >= 8) {
     948        if (psTraceGetLevel("psLib.math") >= 8)
     949        {
    846950            PS_VECTOR_PRINT_F32(histogram->bounds);
    847951            PS_VECTOR_PRINT_F32(histogram->nums);
     
    854958        int nMaxBin = histogram->nums->data.F32[0];
    855959        int iMaxBin = 0;
    856         for (long i = 1; i < histogram->nums->n; i++) {
    857             if (histogram->nums->data.F32[i] > nMaxBin) {
     960        for (long i = 1; i < histogram->nums->n; i++)
     961        {
     962            if (histogram->nums->data.F32[i] > nMaxBin)
     963            {
    858964                nMaxBin = histogram->nums->data.F32[i];
    859965                iMaxBin = i;
    860966            }
    861967        }
    862         if (nMaxBin > numValid / 2) {
    863             float minKeep = histogram->bounds->data.F32[iMaxBin] - 10*binSize;
    864             float maxKeep = histogram->bounds->data.F32[iMaxBin + 1] + 10*binSize;
     968        if (nMaxBin > numValid / 2)
     969        {
     970            float minKeep = histogram->bounds->data.F32[iMaxBin] - 10 * binSize;
     971            float maxKeep = histogram->bounds->data.F32[iMaxBin + 1] + 10 * binSize;
    865972            int nInvalid = 0;
    866             for (long i = 0; i < myVector->n; i++) {
     973            for (long i = 0; i < myVector->n; i++)
     974            {
    867975                // skip the already-masked values
    868                 if (mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & maskVal) continue;
     976                if (mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & maskVal)
     977                    continue;
    869978                bool invalid = false;
    870979                invalid |= (myVector->data.F32[i] < minKeep);
    871980                invalid |= (myVector->data.F32[i] > maxKeep);
    872981                invalid |= (!isfinite(myVector->data.F32[i]));
    873                 if (!invalid) continue;
     982                if (!invalid)
     983                    continue;
    874984                mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = maskVal;
    875                 nInvalid ++;
    876             }
    877 
    878             if (nInvalid) {
    879               psTrace(TRACE, 6, "data is concentrated in a single bin (%d = %f - %f), masking %d extreme outliers and retrying\n",
    880                       iMaxBin, histogram->bounds->data.F32[iMaxBin], histogram->bounds->data.F32[iMaxBin+1], nInvalid);
    881               psFree(histogram);
    882               psFree(cumulative);
    883               histogram = NULL;
    884               cumulative = NULL;
    885               continue;
     985                nInvalid++;
     986            }
     987
     988            if (nInvalid)
     989            {
     990                psTrace(TRACE, 6, "data is concentrated in a single bin (%d = %f - %f), masking %d extreme outliers and retrying\n",
     991                        iMaxBin, histogram->bounds->data.F32[iMaxBin], histogram->bounds->data.F32[iMaxBin + 1], nInvalid);
     992                psFree(histogram);
     993                psFree(cumulative);
     994                histogram = NULL;
     995                cumulative = NULL;
     996                continue;
    886997            }
    887998            // if we did not mask anything, give up.
    888999        }
    8891000
    890         // We were causing psHistogramAlloc to assert. 
     1001        // We were causing psHistogramAlloc to assert.
    8911002        // Assert here so we can get more information about what is going wrong.
    8921003        psAssert(numBins > 0, "Invalid numBins %ld max: %f min: %f binSize: %f", numBins, max, min, binSize);
     
    8981009        cumulative->bounds->data.F32[0] = histogram->bounds->data.F32[1];
    8991010
    900         // Correctly fill the cumulative distribution with monotonically increasing values (skip zero valued bins).
    901         long Nc = 1;  // track the current bin of cumulative
    902         // the boundaries for the current cumulative bin are from upper end of the last valid histogram bin to the
    903         // upper end of the current histogram bin
    904         for (long i = 1; i < histogram->nums->n - 1; i++) {
    905             if (histogram->nums->data.F32[i] == 0.0) continue;
    906             cumulative->nums->data.F32[Nc] = cumulative->nums->data.F32[Nc - 1] + histogram->nums->data.F32[i];
    907             cumulative->bounds->data.F32[Nc] = histogram->bounds->data.F32[i+1];
    908             Nc ++;
    909         }
    910         long Nlast = Nc - 1;  // last valid cumulative bin
    911         for (long i = Nc; i < histogram->nums->n; i++) { // Ensure the unused entries are filled.
    912             cumulative->nums->data.F32[i] = cumulative->nums->data.F32[Nlast];
    913             cumulative->bounds->data.F32[i] = cumulative->bounds->data.F32[i-1] + 1.0;
    914         }
    915        
    916         if (psTraceGetLevel("psLib.math") >= 8) {
     1011        // Correctly fill the cumulative distribution with monotonically increasing values (skip zero valued bins).
     1012        long Nc = 1; // track the current bin of cumulative
     1013        // the boundaries for the current cumulative bin are from upper end of the last valid histogram bin to the
     1014        // upper end of the current histogram bin
     1015        for (long i = 1; i < histogram->nums->n - 1; i++)
     1016        {
     1017            if (histogram->nums->data.F32[i] == 0.0)
     1018                continue;
     1019            cumulative->nums->data.F32[Nc] = cumulative->nums->data.F32[Nc - 1] + histogram->nums->data.F32[i];
     1020            cumulative->bounds->data.F32[Nc] = histogram->bounds->data.F32[i + 1];
     1021            Nc++;
     1022        }
     1023        long Nlast = Nc - 1; // last valid cumulative bin
     1024        for (long i = Nc; i < histogram->nums->n; i++)
     1025        { // Ensure the unused entries are filled.
     1026            cumulative->nums->data.F32[i] = cumulative->nums->data.F32[Nlast];
     1027            cumulative->bounds->data.F32[i] = cumulative->bounds->data.F32[i - 1] + 1.0;
     1028        }
     1029
     1030        if (psTraceGetLevel("psLib.math") >= 8)
     1031        {
    9171032            PS_VECTOR_PRINT_F32(cumulative->bounds);
    9181033            PS_VECTOR_PRINT_F32(cumulative->nums);
     
    9241039
    9251040        // find bin which is the lower bound of median (value[binMedian] < median < value[binMedian+1]
    926         PS_BIN_FOR_VALUE(binMedian, cumulative->nums, totalDataPoints/2.0, 0);
    927 
    928         psTrace(TRACE, 6, "The median bin is %ld (%.2f to %.2f)\n", binMedian, cumulative->bounds->data.F32[binMedian], cumulative->bounds->data.F32[binMedian+1]);
     1041        PS_BIN_FOR_VALUE(binMedian, cumulative->nums, totalDataPoints / 2.0, 0);
     1042
     1043        psTrace(TRACE, 6, "The median bin is %ld (%.2f to %.2f)\n", binMedian, cumulative->bounds->data.F32[binMedian], cumulative->bounds->data.F32[binMedian + 1]);
    9291044
    9301045        // ADD step 3: Interpolate to the exact 50% position in bin units
    9311046        // stats->robustMedian = fitQuadraticSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binMedian, totalDataPoints/2.0);
    932         // float robustBin = fitQuadraticSearchForYThenReturnXusingValues(cumulative->bounds, cumulative->nums, binMedian, totalDataPoints/2.0);
     1047        // float robustBin = fitQuadraticSearchForYThenReturnXusingValues(cumulative->bounds, cumulative->nums, binMedian, totalDataPoints/2.0);
    9331048        // fprintf (stderr, "robustBin : %f vs %f\n", robustBin, stats->robustMedian);
    934         // There's no reason to do a quadratic fit near the 50% bin, as it's approximately linear there.
    935         // Instead, do a 5-point linear fit.
    936         stats->robustMedian = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binMedian, totalDataPoints/2.0);
     1049        // There's no reason to do a quadratic fit near the 50% bin, as it's approximately linear there.
     1050        // Instead, do a 5-point linear fit.
     1051        stats->robustMedian = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binMedian, totalDataPoints / 2.0);
    9371052
    9381053        // convert bin to bin value: this is the robust histogram median.
    939         if (isnan(stats->robustMedian)) {
     1054        if (isnan(stats->robustMedian))
     1055        {
    9401056            COUNT_WARNING(10, 100, "Failed to fit a quadratic and calculate the 50-percent position.\n");
    9411057            goto escape;
     
    9491065        PS_BIN_FOR_VALUE(binL2, cumulative->nums, totalDataPoints * 0.308538f, 0);
    9501066        PS_BIN_FOR_VALUE(binH2, cumulative->nums, totalDataPoints * 0.691462f, 0);
    951         PS_BIN_FOR_VALUE(binL4, cumulative->nums, totalDataPoints * 0.022750f, 0);
    952         PS_BIN_FOR_VALUE(binH4, cumulative->nums, totalDataPoints * 0.977250f, 0);
    953        
    954        
     1067        PS_BIN_FOR_VALUE(binL4, cumulative->nums, totalDataPoints * 0.022750f, 0);
     1068        PS_BIN_FOR_VALUE(binH4, cumulative->nums, totalDataPoints * 0.977250f, 0);
     1069
    9551070        psTrace(TRACE, 6, "The 15.8655%% and 84.1345%% data point bins are (%ld, %ld).\n",
    9561071                binLo, binHi);
     
    9601075        psTrace(TRACE, 6, "binH2 midpoint is %f\n", PS_BIN_MIDPOINT(cumulative, binH2));
    9611076
    962         if ((binLo < 0) || (binHi < 0)) {
     1077        if ((binLo < 0) || (binHi < 0))
     1078        {
    9631079            COUNT_WARNING(10, 100, "Failed to calculate the 15.8655%% and 84.1345%% data points.\n");
    9641080            goto escape;
    9651081        }
    966    
     1082
    9671083        // ADD step 4b: Interpolate Sigma (linearly) to find these two positions exactly: these are the 1sigma
    9681084        // positions.
    9691085        psTrace(TRACE, 6, "binLo is %ld.  Nums at that bin and the next are (%.2f, %.2f)\n",
    970                 binLo, cumulative->nums->data.F32[binLo], cumulative->nums->data.F32[binLo+1]);
     1086                binLo, cumulative->nums->data.F32[binLo], cumulative->nums->data.F32[binLo + 1]);
    9711087        psTrace(TRACE, 6, "binHi is %ld.  Nums at that bin and the next are (%.2f, %.2f)\n",
    972                 binHi, cumulative->nums->data.F32[binHi], cumulative->nums->data.F32[binHi+1]);
     1088                binHi, cumulative->nums->data.F32[binHi], cumulative->nums->data.F32[binHi + 1]);
    9731089
    9741090        // find the +0.5 and -0.5 sigma points with linear interpolation.  binLo and binHi are the bins
     
    9771093        float binLoF32, binHiF32, binL2F32, binH2F32, binL4F32, binH4F32;
    9781094#if (0)
    979         PS_BIN_INTERPOLATE (binLoF32, cumulative->nums, cumulative->bounds, binLo,
    980                             totalDataPoints * 0.158655f);
    981         PS_BIN_INTERPOLATE (binHiF32, cumulative->nums, cumulative->bounds, binHi,
    982                             totalDataPoints * 0.841345f);
    983         PS_BIN_INTERPOLATE (binL2F32, cumulative->nums, cumulative->bounds, binL2,
    984                             totalDataPoints * 0.308538f);
    985         PS_BIN_INTERPOLATE (binH2F32, cumulative->nums, cumulative->bounds, binH2,
    986                             totalDataPoints * 0.691462f);
    987         PS_BIN_INTERPOLATE (binL4F32, cumulative->nums, cumulative->bounds, binL4,
    988                             totalDataPoints * 0.022750f);
    989         PS_BIN_INTERPOLATE (binH4F32, cumulative->nums, cumulative->bounds, binH4,
    990                             totalDataPoints * 0.977250f);
     1095        PS_BIN_INTERPOLATE(binLoF32, cumulative->nums, cumulative->bounds, binLo,
     1096                           totalDataPoints * 0.158655f);
     1097        PS_BIN_INTERPOLATE(binHiF32, cumulative->nums, cumulative->bounds, binHi,
     1098                           totalDataPoints * 0.841345f);
     1099        PS_BIN_INTERPOLATE(binL2F32, cumulative->nums, cumulative->bounds, binL2,
     1100                           totalDataPoints * 0.308538f);
     1101        PS_BIN_INTERPOLATE(binH2F32, cumulative->nums, cumulative->bounds, binH2,
     1102                           totalDataPoints * 0.691462f);
     1103        PS_BIN_INTERPOLATE(binL4F32, cumulative->nums, cumulative->bounds, binL4,
     1104                           totalDataPoints * 0.022750f);
     1105        PS_BIN_INTERPOLATE(binH4F32, cumulative->nums, cumulative->bounds, binH4,
     1106                           totalDataPoints * 0.977250f);
    9911107#else
    9921108        binLoF32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binLo, totalDataPoints * 0.158655);
    993         binHiF32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binHi, totalDataPoints * 0.841345);         
     1109        binHiF32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binHi, totalDataPoints * 0.841345);
    9941110        binL2F32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binL2, totalDataPoints * 0.308538);
    995         binH2F32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binH2, totalDataPoints * 0.691462);         
     1111        binH2F32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binH2, totalDataPoints * 0.691462);
    9961112        binL4F32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binL4, totalDataPoints * 0.022750);
    997         binH4F32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binH4, totalDataPoints * 0.977250);
    998 #endif 
     1113        binH4F32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binH4, totalDataPoints * 0.977250);
     1114#endif
    9991115        // report +/- 1 sigma points
    10001116        psTrace(TRACE, 5,
     
    10081124                binL4F32, binH4F32);
    10091125
    1010         // If some of the fits failed, attempt to fix this
    1011         if (!isfinite(binLoF32) && isfinite(binHiF32)) { binLoF32 = -1.0 * binHiF32; }
    1012         if (!isfinite(binHiF32) && isfinite(binLoF32)) { binHiF32 = -1.0 * binLoF32; }
    1013         if (!isfinite(binL2F32) && isfinite(binH2F32)) { binL2F32 = -1.0 * binH2F32; }
    1014         if (!isfinite(binH2F32) && isfinite(binL2F32)) { binH2F32 = -1.0 * binL2F32; }
    1015         if (!isfinite(binL4F32) && isfinite(binH4F32)) { binL4F32 = -1.0 * binH4F32; }
    1016         if (!isfinite(binH4F32) && isfinite(binL4F32)) { binH4F32 = -1.0 * binL4F32; }
    1017        
     1126        // If some of the fits failed, attempt to fix this
     1127        if (!isfinite(binLoF32) && isfinite(binHiF32))
     1128        {
     1129            binLoF32 = -1.0 * binHiF32;
     1130        }
     1131        if (!isfinite(binHiF32) && isfinite(binLoF32))
     1132        {
     1133            binHiF32 = -1.0 * binLoF32;
     1134        }
     1135        if (!isfinite(binL2F32) && isfinite(binH2F32))
     1136        {
     1137            binL2F32 = -1.0 * binH2F32;
     1138        }
     1139        if (!isfinite(binH2F32) && isfinite(binL2F32))
     1140        {
     1141            binH2F32 = -1.0 * binL2F32;
     1142        }
     1143        if (!isfinite(binL4F32) && isfinite(binH4F32))
     1144        {
     1145            binL4F32 = -1.0 * binH4F32;
     1146        }
     1147        if (!isfinite(binH4F32) && isfinite(binL4F32))
     1148        {
     1149            binH4F32 = -1.0 * binL4F32;
     1150        }
     1151
    10181152        // ADD step 5: Determine SIGMA as the distance between binL2 and binH2 (+/- 0.5 sigma)
    1019 
    10201153
    10211154        float sigma1 = (binH2F32 - binL2F32);
     
    10231156        float sigma4 = (binH4F32 - binL4F32) / 4.0;
    10241157
    1025         // Fix again?
    1026         if (!isfinite(sigma1) && isfinite(sigma2) && isfinite(sigma4)) { sigma1 = (sigma2 + sigma4) / 2.0; }
    1027         if (!isfinite(sigma2) && isfinite(sigma1) && isfinite(sigma4)) { sigma2 = (sigma1 + sigma4) / 2.0; }
    1028         if (!isfinite(sigma4) && isfinite(sigma2) && isfinite(sigma1)) { sigma4 = (sigma2 + sigma1) / 2.0; }
    1029        
     1158        // Fix again?
     1159        if (!isfinite(sigma1) && isfinite(sigma2) && isfinite(sigma4))
     1160        {
     1161            sigma1 = (sigma2 + sigma4) / 2.0;
     1162        }
     1163        if (!isfinite(sigma2) && isfinite(sigma1) && isfinite(sigma4))
     1164        {
     1165            sigma2 = (sigma1 + sigma4) / 2.0;
     1166        }
     1167        if (!isfinite(sigma4) && isfinite(sigma2) && isfinite(sigma1))
     1168        {
     1169            sigma4 = (sigma2 + sigma1) / 2.0;
     1170        }
     1171
    10301172        // take the smallest of the three: if we have a clump with wide outliers, sigma2 and
    10311173        // sigma4 will be biased high; if we have a bi-modal distribution, sigma1 and sigma2
    10321174        // will be biased high.
    1033         //        sigma = PS_MIN (sigma1, PS_MIN (sigma2, sigma4));
    1034         // CZW: Instead, take the median.  Taking the MIN forces a bias on unbiased data.
    1035         //      It seems like occasionally getting the wrong answer on a complex distribution
    1036         //      is more acceptable than always getting the wrong answer for simple ones.
    1037 
    1038        
    1039         sigma = PS_MAX( PS_MIN(sigma1,sigma2),
    1040                         PS_MIN( PS_MAX(sigma1,sigma2),
    1041                                 sigma4));
     1175        //        sigma = PS_MIN (sigma1, PS_MIN (sigma2, sigma4));
     1176        // CZW: Instead, take the median.  Taking the MIN forces a bias on unbiased data.
     1177        //      It seems like occasionally getting the wrong answer on a complex distribution
     1178        //      is more acceptable than always getting the wrong answer for simple ones.
     1179
     1180        sigma = PS_MAX(PS_MIN(sigma1, sigma2),
     1181                       PS_MIN(PS_MAX(sigma1, sigma2),
     1182                              sigma4));
    10421183
    10431184        psTrace(TRACE, 6, "The 1x sigma is %f.\n", sigma1);
     
    10461187
    10471188        psTrace(TRACE, 6, "The current sigma is %f.\n", sigma);
    1048         //        stats->robustStdev = sigma;
    1049         stats->robustStdev = sigma;
    1050 
    1051 #if (CZW && 0) 
    1052         // Skewness check: Find least biased sample for each pair.
    1053         sigma1 = 2.0 * PS_MIN(binH2F32 - stats->robustMedian,
    1054                               stats->robustMedian - binL2F32);
    1055         sigma2 = 1.0 * PS_MIN(binHiF32 - stats->robustMedian,
    1056                               stats->robustMedian - binLoF32);
    1057         sigma4 = 0.5 * PS_MIN(binH4F32 - stats->robustMedian,
    1058                               stats->robustMedian - binL4F32);
    1059         // Kurtosis check: Take median sample as the solution.
    1060         stats->robustStdev = PS_MAX( PS_MIN(sigma1,sigma2),
    1061                                      PS_MIN( PS_MAX(sigma1,sigma2),
    1062                                              sigma4));
     1189        //        stats->robustStdev = sigma;
     1190        stats->robustStdev = sigma;
     1191
     1192#if (CZW && 0)
     1193        // Skewness check: Find least biased sample for each pair.
     1194        sigma1 = 2.0 * PS_MIN(binH2F32 - stats->robustMedian,
     1195                              stats->robustMedian - binL2F32);
     1196        sigma2 = 1.0 * PS_MIN(binHiF32 - stats->robustMedian,
     1197                              stats->robustMedian - binLoF32);
     1198        sigma4 = 0.5 * PS_MIN(binH4F32 - stats->robustMedian,
     1199                              stats->robustMedian - binL4F32);
     1200        // Kurtosis check: Take median sample as the solution.
     1201        stats->robustStdev = PS_MAX(PS_MIN(sigma1, sigma2),
     1202                                    PS_MIN(PS_MAX(sigma1, sigma2),
     1203                                           sigma4));
    10631204#endif
    10641205
    1065        
    10661206#if (CZW)
    1067         //      printf("CZW: bad sigma?: %f %f  %f %f  %f %f  %f %f %f  %f\n",
    1068         //             binH2F32,binL2F32,binHiF32,binLoF32,binH4F32,binL4F32,
    1069         //             sigma1,sigma2,sigma4,sigma);
    1070        
    1071         printf("CZW Robust (%d): median %f sigma %f delta: %f \n\t %f %f %f %f %f %f %f \n\t %f %f %f %f %f %f %f\n",
    1072                iterate,
    1073                stats->robustMedian,stats->robustStdev,
    1074                fabs(cumulative->bounds->data.F32[binMedian] - cumulative->bounds->data.F32[binMedian + 1]),
    1075                
    1076                cumulative->bounds->data.F32[binMedian-3],cumulative->bounds->data.F32[binMedian-2],
    1077                cumulative->bounds->data.F32[binMedian-1],
    1078                cumulative->bounds->data.F32[binMedian],
    1079                cumulative->bounds->data.F32[binMedian+1],
    1080                cumulative->bounds->data.F32[binMedian+2],cumulative->bounds->data.F32[binMedian+3],
    1081                
    1082                cumulative->nums->data.F32[binMedian-3],cumulative->nums->data.F32[binMedian-2],
    1083                cumulative->nums->data.F32[binMedian-1],
    1084                cumulative->nums->data.F32[binMedian],
    1085                cumulative->nums->data.F32[binMedian+1],
    1086                cumulative->nums->data.F32[binMedian+2],cumulative->nums->data.F32[binMedian+3]);
    1087         //      PS_VECTOR_PRINT_F32(histogram->bounds);
    1088         //      PS_VECTOR_PRINT_F32(histogram->nums);
    1089         //      PS_VECTOR_PRINT_F32(cumulative->bounds);
    1090         //      PS_VECTOR_PRINT_F32(cumulative->nums);
     1207        //      printf("CZW: bad sigma?: %f %f  %f %f  %f %f  %f %f %f  %f\n",
     1208        //             binH2F32,binL2F32,binHiF32,binLoF32,binH4F32,binL4F32,
     1209        //             sigma1,sigma2,sigma4,sigma);
     1210
     1211        printf("CZW Robust (%d): median %f sigma %f delta: %f \n\t %f %f %f %f %f %f %f \n\t %f %f %f %f %f %f %f\n",
     1212               iterate,
     1213               stats->robustMedian, stats->robustStdev,
     1214               fabs(cumulative->bounds->data.F32[binMedian] - cumulative->bounds->data.F32[binMedian + 1]),
     1215
     1216               cumulative->bounds->data.F32[binMedian - 3], cumulative->bounds->data.F32[binMedian - 2],
     1217               cumulative->bounds->data.F32[binMedian - 1],
     1218               cumulative->bounds->data.F32[binMedian],
     1219               cumulative->bounds->data.F32[binMedian + 1],
     1220               cumulative->bounds->data.F32[binMedian + 2], cumulative->bounds->data.F32[binMedian + 3],
     1221
     1222               cumulative->nums->data.F32[binMedian - 3], cumulative->nums->data.F32[binMedian - 2],
     1223               cumulative->nums->data.F32[binMedian - 1],
     1224               cumulative->nums->data.F32[binMedian],
     1225               cumulative->nums->data.F32[binMedian + 1],
     1226               cumulative->nums->data.F32[binMedian + 2], cumulative->nums->data.F32[binMedian + 3]);
     1227        //      PS_VECTOR_PRINT_F32(histogram->bounds);
     1228        //      PS_VECTOR_PRINT_F32(histogram->nums);
     1229        //      PS_VECTOR_PRINT_F32(cumulative->bounds);
     1230        //      PS_VECTOR_PRINT_F32(cumulative->nums);
    10911231#endif
    10921232
    10931233        // ADD step 6: If the measured SIGMA is less than 2 times the bin size, exclude points which are more
    10941234        // than 25 bins from the median, recalculate the bin size, and perform the algorithm again.
    1095         if (sigma < (3.0 * binSize)) {
     1235        if (sigma < (3.0 * binSize))
     1236        {
    10961237            psTrace(TRACE, 6, "*************: Do another iteration (%f %f).\n", sigma, binSize);
    10971238
    1098             // these limits are supposed to be 25 x the raw bin size, NOT 25 of the cumulative histogram bins
    1099             psF32 medianLo = stats->robustMedian - 25*binSize;
    1100             psF32 medianHi = stats->robustMedian + 25*binSize;
     1239            // these limits are supposed to be 25 x the raw bin size, NOT 25 of the cumulative histogram bins
     1240            psF32 medianLo = stats->robustMedian - 25 * binSize;
     1241            psF32 medianHi = stats->robustMedian + 25 * binSize;
    11011242
    11021243            // long maskLo = PS_MAX(0, (binMedian - 25)); // Low index for masking region
     
    11071248            // psTrace(TRACE, 6, "The median is at bin number %ld.  We mask bins outside the bin range (%ld:%ld)\n", binMedian, maskLo, maskHi);
    11081249            psTrace(TRACE, 6, "Masking data outside (%f %f)\n", medianLo, medianHi);
    1109             int Nmasked = 0;
    1110             for (long i = 0 ; i < myVector->n ; i++) {
    1111                 if ((myVector->data.F32[i] < medianLo) || (myVector->data.F32[i] > medianHi)) {
    1112                     if (mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & MASK_MARK) continue;
     1250            int Nmasked = 0;
     1251            for (long i = 0; i < myVector->n; i++)
     1252            {
     1253                if ((myVector->data.F32[i] < medianLo) || (myVector->data.F32[i] > medianHi))
     1254                {
     1255                    if (mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & MASK_MARK)
     1256                        continue;
    11131257                    mask->data.PS_TYPE_VECTOR_MASK_DATA[i] |= MASK_MARK;
    11141258                    psTrace(TRACE, 6, "Masking element %ld is %f\n", i, myVector->data.F32[i]);
    1115                     Nmasked ++;
     1259                    Nmasked++;
    11161260                }
    11171261            }
    11181262
    1119             if (Nmasked == 0) {
    1120                 // no significant change to the sigma & binsize -- we are done here
    1121                 iterate = -1;
    1122                 continue;
    1123             }
     1263            if (Nmasked == 0)
     1264            {
     1265                // no significant change to the sigma & binsize -- we are done here
     1266                iterate = -1;
     1267                continue;
     1268            }
    11241269
    11251270            // Free the histograms; they will be recreated on the next iteration, with new bounds
     
    11301275            cumulative = NULL;
    11311276
    1132             if (iterate >= PS_ROBUST_MAX_ITERATIONS) {
     1277            if (iterate >= PS_ROBUST_MAX_ITERATIONS)
     1278            {
    11331279                // This occurs when a large number of the values are identical --- a bin size cannot be found
    11341280                // that will spread out the distribution.  Therefore, set what we can, and fall over
     
    11471293                return true;
    11481294            }
    1149         } else {
     1295        }
     1296        else
     1297        {
    11501298            // We've got the bin size correct now
    11511299            psTrace(TRACE, 6, "*************: No more iteration.  sigma is %f\n", sigma);
     
    11531301        }
    11541302    }
    1155    
     1303
    11561304    // XXX test lines while studying algorithm errors
    11571305    // fprintf (stderr, "robust stats test %7.1f +/- %7.1f : %4ld %4ld %4ld %4ld %4ld  : %f %f %f\n",
     
    11611309    // ADD step 7: Find the bins which contains the 25% and 75% data points.
    11621310    long binLo25, binHi25;
    1163     PS_BIN_FOR_VALUE (binLo25, cumulative->nums, totalDataPoints * 0.25f, 0);
    1164     PS_BIN_FOR_VALUE (binHi25, cumulative->nums, totalDataPoints * 0.75f, 0);
     1311    PS_BIN_FOR_VALUE(binLo25, cumulative->nums, totalDataPoints * 0.25f, 0);
     1312    PS_BIN_FOR_VALUE(binHi25, cumulative->nums, totalDataPoints * 0.75f, 0);
    11651313    psTrace(TRACE, 6, "The 25-percent and 75-percent data point bins are (%ld, %ld).\n", binLo25, binHi25);
    11661314
     
    11691317    psF32 binLo25F32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binLo25, totalDataPoints * 0.25f);
    11701318    psF32 binHi25F32 = fitLinearSearchForYThenReturnBin(cumulative->bounds, cumulative->nums, binHi25, totalDataPoints * 0.75f);
    1171     if (isnan(binLo25F32) || isnan(binHi25F32)) {
     1319    if (isnan(binLo25F32) || isnan(binHi25F32))
     1320    {
    11721321        COUNT_WARNING(10, 100, "could not determine the robustUQ or LQ: fitLinearSearchForYThenReturnBin() returned a NAN.\n");
    11731322        goto escape;
     
    11791328            binLo25F32, binHi25F32);
    11801329    long N50 = 0;
    1181     for (long i = 0 ; i < myVector->n ; i++) {
     1330    for (long i = 0; i < myVector->n; i++)
     1331    {
    11821332        if (!mask->data.PS_TYPE_VECTOR_MASK_DATA[i] &&
    1183             (binLo25F32 <= myVector->data.F32[i]) && (binHi25F32 >= myVector->data.F32[i])) {
     1333            (binLo25F32 <= myVector->data.F32[i]) && (binHi25F32 >= myVector->data.F32[i]))
     1334        {
    11841335            N50++;
    11851336        }
     
    12261377 * version follows the upper portion of the distribution until it passes 0.5*peak
    12271378 ********************/
    1228 static bool vectorFittedStats (const psVector* myVector,
    1229                                   const psVector* errors,
    1230                                   psVector* mask,
    1231                                   psVectorMaskType maskVal,
    1232                                   psStats* stats)
     1379static bool vectorFittedStats(const psVector *myVector,
     1380                              const psVector *errors,
     1381                              psVector *mask,
     1382                              psVectorMaskType maskVal,
     1383                              psStats *stats)
    12331384{
    12341385
    12351386    // This procedure requires the mean.  If it has not been already
    12361387    // calculated, then call vectorSampleMean()
    1237     if (!(stats->results & PS_STAT_ROBUST_MEDIAN)) {
    1238         if (!vectorRobustStats(myVector, errors, mask, maskVal, stats)) {
     1388    if (!(stats->results & PS_STAT_ROBUST_MEDIAN))
     1389    {
     1390        if (!vectorRobustStats(myVector, errors, mask, maskVal, stats))
     1391        {
    12391392            psError(PS_ERR_UNKNOWN, false, "failure to measure robust stats\n");
    12401393            return false;
     
    12431396
    12441397    // If the mean is NAN, then generate a warning and set the stdev to NAN.
    1245     if (isnan(stats->robustMedian)) {
    1246         stats->fittedMean = NAN;
    1247         stats->fittedStdev = NAN;
    1248         stats->results |= PS_STAT_FITTED_MEAN;
    1249         stats->results |= PS_STAT_FITTED_STDEV;
     1398    if (isnan(stats->robustMedian))
     1399    {
     1400        stats->fittedMean = NAN;
     1401        stats->fittedStdev = NAN;
     1402        stats->results |= PS_STAT_FITTED_MEAN;
     1403        stats->results |= PS_STAT_FITTED_STDEV;
    12501404        return true;
    12511405    }
    12521406
    1253     if (stats->robustStdev <= FLT_EPSILON) {
    1254         stats->fittedMean = stats->robustMedian;
    1255         stats->fittedStdev = stats->robustStdev;
    1256         stats->results |= PS_STAT_FITTED_MEAN;
    1257         stats->results |= PS_STAT_FITTED_STDEV;
     1407    if (stats->robustStdev <= FLT_EPSILON)
     1408    {
     1409        stats->fittedMean = stats->robustMedian;
     1410        stats->fittedStdev = stats->robustStdev;
     1411        stats->results |= PS_STAT_FITTED_MEAN;
     1412        stats->results |= PS_STAT_FITTED_STDEV;
    12581413        return true;
    12591414    }
    1260     if (myVector->n < 1) { printf("There are no elements in this vector.\n"); abort(); }
    1261     float guessStdev = stats->robustStdev;  // pass the guess sigma
    1262     float guessMean = stats->robustMedian;  // pass the guess mean
     1415    if (myVector->n < 1)
     1416    {
     1417        printf("There are no elements in this vector.\n");
     1418        abort();
     1419    }
     1420    float guessStdev = stats->robustStdev; // pass the guess sigma
     1421    float guessMean = stats->robustMedian; // pass the guess mean
    12631422
    12641423    psTrace(TRACE, 6, "The ** starting ** guess mean  is %f.\n", guessMean);
     
    12661425
    12671426    bool done = false;
    1268     for (int iteration = 0; !done && (iteration < 2); iteration ++) {
     1427    for (int iteration = 0; !done && (iteration < 2); iteration++)
     1428    {
    12691429        psStats *statsMinMax = psStatsAlloc(PS_STAT_MIN | PS_STAT_MAX); // Statistics for min and max
    12701430
    12711431        psF32 binSize = 1;
    1272         if (stats->options & PS_STAT_USE_BINSIZE) {
     1432        if (stats->options & PS_STAT_USE_BINSIZE)
     1433        {
    12731434            // Set initial bin size to the specified value.
    12741435            binSize = stats->binsize;
    12751436            psTrace(TRACE, 6, "Setting initial robust bin size to %.2f\n", binSize);
    1276         } else {
     1437        }
     1438        else
     1439        {
    12771440            // construct a histogram with (sigma/2 < binsize < sigma)
    12781441            // set roughly so that the lowest bins have about 2 cnts
    12791442            // Nsmallest ~ N50 / (4*dN))
    1280           //            psF32 dN = PS_MAX (1, PS_MIN (4, stats->robustN50 / 8));
    1281 
    1282           // CZW 2013-11-20: We know that the histogram is going to be basically Gaussian.
    1283           // Furthermore, we only use the inner +/- 2 sigma parts.  Therefore, define the
    1284           // binsize such that the bin at 2 sigma contains ~50 points (S/N ~ 7).  robustN50
    1285           // contains half the total points, so 2 * robustN50 / 50 is the fraction of all
    1286           // points in the 2 sigma bin.  Dance the erf() relations around, and it looks like
    1287           // there's a factor of about 1/20 to include.  Keep the PS_MAX to ensure we never bin
    1288           // wider than 1 sigma when the number of points is small.
    1289           psF32 dN = PS_MAX(1, (stats->robustN50 / 500.0));
    1290           binSize = guessStdev / dN;
     1443            //            psF32 dN = PS_MAX (1, PS_MIN (4, stats->robustN50 / 8));
     1444
     1445            // CZW 2013-11-20: We know that the histogram is going to be basically Gaussian.
     1446            // Furthermore, we only use the inner +/- 2 sigma parts.  Therefore, define the
     1447            // binsize such that the bin at 2 sigma contains ~50 points (S/N ~ 7).  robustN50
     1448            // contains half the total points, so 2 * robustN50 / 50 is the fraction of all
     1449            // points in the 2 sigma bin.  Dance the erf() relations around, and it looks like
     1450            // there's a factor of about 1/20 to include.  Keep the PS_MAX to ensure we never bin
     1451            // wider than 1 sigma when the number of points is small.
     1452            psF32 dN = PS_MAX(1, (stats->robustN50 / 500.0));
     1453            binSize = guessStdev / dN;
    12911454        }
    12921455
     
    12951458        float min = statsMinMax->min;
    12961459        float max = statsMinMax->max;
    1297         if (numValid == 0 || isnan(min) || isnan(max)) {
     1460        if (numValid == 0 || isnan(min) || isnan(max))
     1461        {
    12981462            COUNT_WARNING(10, 100, "Failed to calculate the min/max of the input vector.\n");
    12991463            psFree(statsMinMax);
     
    13021466
    13031467        // If all data points have the same value, then we set the appropriate members of stats and return.
    1304         if (fabs(max - min) <= FLT_EPSILON) {
     1468        if (fabs(max - min) <= FLT_EPSILON)
     1469        {
    13051470            COUNT_WARNING(10, 100, "All data points have the same value: %f.\n", min);
    13061471            stats->fittedMean = min;
     
    13141479        // XXX can we calculate the binMin, binMax **before** building this histogram?
    13151480        // if the range is too absurd, adjust numBins & binSize
    1316         // We no longer want to reset the binSize here, as it can cause odd things.  Better to select
    1317         // a number of bins, and then set the min/max values to put those bins sanely around the mean.
    1318         //        long numBins = PS_MAX (50, PS_MIN (10000, (max - min) / binSize));
    1319         //        binSize = (max - min) / (float) numBins;
     1481        // We no longer want to reset the binSize here, as it can cause odd things.  Better to select
     1482        // a number of bins, and then set the min/max values to put those bins sanely around the mean.
     1483        //        long numBins = PS_MAX (50, PS_MIN (10000, (max - min) / binSize));
     1484        //        binSize = (max - min) / (float) numBins;
    13201485        psTrace(TRACE, 6, "The new min/max values are (%f, %f).\n", min, max);
    13211486        psTrace(TRACE, 6, "The new bin size is %f.\n", binSize);
    1322         //        psTrace(TRACE, 6, "The numBins is %ld\n", numBins);
    1323 
     1487        //        psTrace(TRACE, 6, "The numBins is %ld\n", numBins);
    13241488
    13251489#define FITTED_CLIPPING_NUM 5.0
    1326         if (min < guessMean - FITTED_CLIPPING_NUM * guessStdev) {
    1327           min = guessMean - FITTED_CLIPPING_NUM * guessStdev;
    1328         }
    1329         if (max > guessMean + FITTED_CLIPPING_NUM * guessStdev) {
    1330           max = guessMean + FITTED_CLIPPING_NUM * guessStdev;
    1331         }
    1332         long numBins = PS_MAX (50, PS_MIN (10000, (max - min) / binSize));
    1333         if (CZW) { printf("I've clipped: %f %f => %f %f ; %f %ld\n",guessMean,guessStdev,min,max,binSize,stats->robustN50); }
     1490        if (min < guessMean - FITTED_CLIPPING_NUM * guessStdev)
     1491        {
     1492            min = guessMean - FITTED_CLIPPING_NUM * guessStdev;
     1493        }
     1494        if (max > guessMean + FITTED_CLIPPING_NUM * guessStdev)
     1495        {
     1496            max = guessMean + FITTED_CLIPPING_NUM * guessStdev;
     1497        }
     1498        long numBins = PS_MAX(50, PS_MIN(10000, (max - min) / binSize));
     1499        if (CZW)
     1500        {
     1501            printf("I've clipped: %f %f => %f %f ; %f %ld\n", guessMean, guessStdev, min, max, binSize, stats->robustN50);
     1502        }
    13341503        psHistogram *histogram = psHistogramAlloc(min, max, numBins); // A new histogram (without outliers)
    1335         if (!psVectorHistogram(histogram, myVector, errors, mask, maskVal)) {
     1504        if (!psVectorHistogram(histogram, myVector, errors, mask, maskVal))
     1505        {
    13361506            COUNT_WARNING(10, 100, "Unable to generate histogram for fitted statistics v4.\n");
    13371507            psFree(histogram);
     
    13391509            goto escape;
    13401510        }
    1341         if (psTraceGetLevel("psLib.math") >= 8) {
     1511        if (psTraceGetLevel("psLib.math") >= 8)
     1512        {
    13421513            PS_VECTOR_PRINT_F32(histogram->nums);
    13431514        }
     
    13471518        // set the full-range upper and lower limits
    13481519        psF32 maxFitSigma = 2.0;
    1349         if (isfinite(stats->clipSigma)) {
     1520        if (isfinite(stats->clipSigma))
     1521        {
    13501522            maxFitSigma = fabs(stats->clipSigma);
    13511523        }
    1352         if (isfinite(stats->max)) {
     1524        if (isfinite(stats->max))
     1525        {
    13531526            maxFitSigma = fabs(stats->max);
    13541527        }
    13551528
    13561529        psF32 minFitSigma = 2.0;
    1357         if (isfinite(stats->clipSigma)) {
     1530        if (isfinite(stats->clipSigma))
     1531        {
    13581532            minFitSigma = fabs(stats->clipSigma);
    13591533        }
    1360         if (isfinite(stats->min)) {
     1534        if (isfinite(stats->min))
     1535        {
    13611536            minFitSigma = fabs(stats->min);
    13621537        }
     
    13641539        // select the min and max bins, saturating on the lower and upper end-points
    13651540        long binMin, binMax;
    1366         PS_BIN_FOR_VALUE (binMin, histogram->bounds, guessMean - minFitSigma*guessStdev, 0);
    1367         PS_BIN_FOR_VALUE (binMax, histogram->bounds, guessMean + maxFitSigma*guessStdev, 0);
    1368 
    1369         if (binMin == binMax) {
     1541        PS_BIN_FOR_VALUE(binMin, histogram->bounds, guessMean - minFitSigma * guessStdev, 0);
     1542        PS_BIN_FOR_VALUE(binMax, histogram->bounds, guessMean + maxFitSigma * guessStdev, 0);
     1543
     1544        if (binMin == binMax)
     1545        {
    13701546            COUNT_WARNING(10, 100, "Failed to calculate the min/max of the input vector.\n");
    13711547            psFree(statsMinMax);
     
    13751551
    13761552        // search for mode (peak of histogram within range mean-2sigma - mean+2sigma
    1377         long  binPeak = binMin;
     1553        long binPeak = binMin;
    13781554        float valPeak = histogram->nums->data.F32[binPeak];
    1379         for (int i = binMin; i < binMax; i++) {
    1380             if (histogram->nums->data.F32[i] > valPeak) {
     1555        for (int i = binMin; i < binMax; i++)
     1556        {
     1557            if (histogram->nums->data.F32[i] > valPeak)
     1558            {
    13811559                binPeak = i;
    13821560                valPeak = histogram->nums->data.F32[binPeak];
    13831561            }
    1384             psTrace (TRACE, 6, "(%f = %.0f) ", histogram->bounds->data.F32[i], histogram->nums->data.F32[i]);
    1385             if (CZW) { printf("CENTERED_HISTOGRAM: %f %f\n",
    1386                               PS_BIN_MIDPOINT(histogram,i),
    1387                               histogram->nums->data.F32[i]); }
    1388         }
    1389         psTrace (TRACE, 6, "\n");
    1390 
    1391         if (CZW) { printf("Bin selection done: %ld %f %f %ld %f %f %ld %f %f\n",
    1392                           binMin,PS_BIN_MIDPOINT(histogram,binMin),histogram->nums->data.F32[binMin],
    1393                           binMax,PS_BIN_MIDPOINT(histogram,binMax),histogram->nums->data.F32[binMax],
    1394                           binPeak,PS_BIN_MIDPOINT(histogram,binPeak),histogram->nums->data.F32[binPeak]);
    1395         }
    1396        
     1562            psTrace(TRACE, 6, "(%f = %.0f) ", histogram->bounds->data.F32[i], histogram->nums->data.F32[i]);
     1563            if (CZW)
     1564            {
     1565                printf("CENTERED_HISTOGRAM: %f %f\n",
     1566                       PS_BIN_MIDPOINT(histogram, i),
     1567                       histogram->nums->data.F32[i]);
     1568            }
     1569        }
     1570        psTrace(TRACE, 6, "\n");
     1571
     1572        if (CZW)
     1573        {
     1574            printf("Bin selection done: %ld %f %f %ld %f %f %ld %f %f\n",
     1575                   binMin, PS_BIN_MIDPOINT(histogram, binMin), histogram->nums->data.F32[binMin],
     1576                   binMax, PS_BIN_MIDPOINT(histogram, binMax), histogram->nums->data.F32[binMax],
     1577                   binPeak, PS_BIN_MIDPOINT(histogram, binPeak), histogram->nums->data.F32[binPeak]);
     1578        }
     1579
    13971580        // assume a reasonably well-defined gaussian-like population; run from peak out until val < 0.25*peak
    13981581        psTrace(TRACE, 6, "The clipped numBins is %ld\n", binMax - binMin);
     
    14021585        psTrace(TRACE, 6, "The clipped peak value is %f\n", histogram->nums->data.F32[binPeak]);
    14031586
    1404        
    1405         float lowfitMean = NAN;
    1406         float lowfitStdev = NAN;
     1587        float lowfitMean = NAN;
     1588        float lowfitStdev = NAN;
    14071589        {
    14081590            // fit the lower half of the distribution
     
    14101592            // run up until we drop below 0.50*valPeak
    14111593            long binS = binMin;
    1412             long binE = PS_MIN (binPeak + 3, binMax);
    1413             for (int i = binPeak - 3; i >= binMin; i--) {
    1414                 if (histogram->nums->data.F32[i] < 0.25*valPeak) {
     1594            long binE = PS_MIN(binPeak + 3, binMax);
     1595            for (int i = binPeak - 3; i >= binMin; i--)
     1596            {
     1597                if (histogram->nums->data.F32[i] < 0.25 * valPeak)
     1598                {
    14151599                    binS = i;
    14161600                    break;
    14171601                }
    14181602            }
    1419             for (int i = binPeak + 3; i < binMax; i++) {
    1420                 if (histogram->nums->data.F32[i] < 0.50*valPeak) {
     1603            for (int i = binPeak + 3; i < binMax; i++)
     1604            {
     1605                if (histogram->nums->data.F32[i] < 0.50 * valPeak)
     1606                {
    14211607                    binE = i;
    14221608                    break;
     
    14311617            psVector *x = psVectorAllocEmpty(binE - binS, PS_TYPE_F32); // Vector of ordinates
    14321618            long j = 0;
    1433             for (long i = binS; i < binE; i++) {
     1619            for (long i = binS; i < binE; i++)
     1620            {
    14341621                if (histogram->nums->data.F32[i] <= 0.0)
    14351622                    continue;
     
    14401627            }
    14411628            y->n = x->n = j;
    1442            
     1629
    14431630            // fit 2nd order polynomial to ln(y) = -(x-xo)^2/2sigma^2
    14441631            // XXX this fit may fail with an error for an ill-conditioned matrix (bad data)
    14451632            // we probably should be able to handle the data errors gracefully
    14461633            psPolynomial1D *poly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, 2);
    1447             bool status = psVectorFitPolynomial1D (poly, NULL, 0, y, NULL, x);
     1634            bool status = psVectorFitPolynomial1D(poly, NULL, 0, y, NULL, x);
    14481635#if (CZW && 1)
    1449             printf("CZW: LowfitPoly: %f %f %f\n",poly->coeff[0],poly->coeff[1],poly->coeff[2]);
    1450             for (long i = 0; i < x->n; i++) {
    1451               printf("CZW: Lowfit: %d %ld %f %f %f\n",
    1452                      status,i,x->data.F32[i],y->data.F32[i],
    1453                      poly->coeff[0] + poly->coeff[1] * x->data.F32[i] +
    1454                      poly->coeff[2] * pow(x->data.F32[i],2));
    1455             }
     1636            printf("CZW: LowfitPoly: %f %f %f\n", poly->coeff[0], poly->coeff[1], poly->coeff[2]);
     1637            for (long i = 0; i < x->n; i++)
     1638            {
     1639                printf("CZW: Lowfit: %d %ld %f %f %f\n",
     1640                       status, i, x->data.F32[i], y->data.F32[i],
     1641                       poly->coeff[0] + poly->coeff[1] * x->data.F32[i] +
     1642                           poly->coeff[2] * pow(x->data.F32[i], 2));
     1643            }
    14561644#endif
    14571645            psFree(x);
    14581646            psFree(y);
    14591647
    1460             if (!status) {
     1648            if (!status)
     1649            {
    14611650                psErrorClear();
    14621651                COUNT_WARNING(10, 100, "Failed to fit a gaussian to the robust histogram.\n");
     
    14671656            }
    14681657
    1469             if (poly->coeff[2] >= 0.0) {
     1658            if (poly->coeff[2] >= 0.0)
     1659            {
    14701660                COUNT_WARNING(10, 100, "Failed parabolic fit: %f + %f x + %f x^2\n", poly->coeff[0], poly->coeff[1], poly->coeff[2]);
    14711661
     
    14771667                // tends to be found in a single bin.  make one attempt to recover by dropping the guessStdev
    14781668                // down by a jump and trying again
    1479                 if (iteration == 0) {
    1480                     guessStdev = 0.25*guessStdev;
     1669                if (iteration == 0)
     1670                {
     1671                    guessStdev = 0.25 * guessStdev;
    14811672                    psTrace(TRACE, 6, "*** retry, new stdev is %f.\n", guessStdev);
    14821673                    continue;
     
    14881679
    14891680            // calculate lower mean & stdev from parabolic fit -- use this as the result
    1490             lowfitStdev = sqrt(-0.5/poly->coeff[2]);
    1491             lowfitMean  = poly->coeff[1]*PS_SQR(lowfitStdev);
     1681            lowfitStdev = sqrt(-0.5 / poly->coeff[2]);
     1682            lowfitMean = poly->coeff[1] * PS_SQR(lowfitStdev);
    14921683
    14931684            psTrace(TRACE, 6, "Parabolic Lower fit results: %f + %f x + %f x^2\n", poly->coeff[0], poly->coeff[1], poly->coeff[2]);
     
    14981689        }
    14991690
    1500         float fullfitMean = NAN;
    1501         float fullfitStdev = NAN;
    1502         float minValueSym = NAN;
    1503         float maxValueSym = NAN;
    1504 
    1505         // try the full fit as well:
    1506         {
     1691        float fullfitMean = NAN;
     1692        float fullfitStdev = NAN;
     1693        float minValueSym = NAN;
     1694        float maxValueSym = NAN;
     1695
     1696        // try the full fit as well:
     1697        {
    15071698            // fit a symmetric distribution
    15081699            // run up until we drop below 0.15*valPeak
     
    15101701            long binS = binMin;
    15111702            long binE = binMax;
    1512             for (int i = binPeak - 3; i >= binMin; i--) {
    1513                 if (histogram->nums->data.F32[i] < 0.15*valPeak) {
     1703            for (int i = binPeak - 3; i >= binMin; i--)
     1704            {
     1705                if (histogram->nums->data.F32[i] < 0.15 * valPeak)
     1706                {
    15141707                    binS = i;
    15151708                    break;
    15161709                }
    15171710            }
    1518             for (int i = binPeak + 3; i < binMax; i++) {
    1519                 if (histogram->nums->data.F32[i] < 0.15*valPeak) {
     1711            for (int i = binPeak + 3; i < binMax; i++)
     1712            {
     1713                if (histogram->nums->data.F32[i] < 0.15 * valPeak)
     1714                {
    15201715                    binE = i;
    15211716                    break;
     
    15311726            psVector *x = psVectorAllocEmpty(binE - binS, PS_TYPE_F32); // Vector of ordinates
    15321727            long j = 0;
    1533             for (long i = binS; i < binE; i++) {
     1728            for (long i = binS; i < binE; i++)
     1729            {
    15341730                if (histogram->nums->data.F32[i] <= 0.0)
    15351731                    continue;
     
    15431739            // fit 2nd order polynomial to ln(y) = -(x-xo)^2/2sigma^2
    15441740            psPolynomial1D *poly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, 2);
    1545             bool status = psVectorFitPolynomial1D (poly, NULL, 0, y, NULL, x);
     1741            bool status = psVectorFitPolynomial1D(poly, NULL, 0, y, NULL, x);
    15461742#if (CZW && 1)
    1547             printf("CZW: FullfitPoly: %f %f %f\n",poly->coeff[0],poly->coeff[1],poly->coeff[2]);
    1548             for (long i = 0; i < x->n; i++) {
    1549               printf("CZW: Fullfit: %d %ld %f %f %f\n",
    1550                      status,i,x->data.F32[i],y->data.F32[i],
    1551                      poly->coeff[0] + poly->coeff[1] * x->data.F32[i] +
    1552                      poly->coeff[2] * pow(x->data.F32[i],2));
    1553             }
     1743            printf("CZW: FullfitPoly: %f %f %f\n", poly->coeff[0], poly->coeff[1], poly->coeff[2]);
     1744            for (long i = 0; i < x->n; i++)
     1745            {
     1746                printf("CZW: Fullfit: %d %ld %f %f %f\n",
     1747                       status, i, x->data.F32[i], y->data.F32[i],
     1748                       poly->coeff[0] + poly->coeff[1] * x->data.F32[i] +
     1749                           poly->coeff[2] * pow(x->data.F32[i], 2));
     1750            }
    15541751#endif
    15551752            psFree(x);
    15561753            psFree(y);
    15571754
    1558             if (!status) {
     1755            if (!status)
     1756            {
    15591757                psErrorClear();
    15601758                COUNT_WARNING(10, 100, "Failed to fit a gaussian to the robust histogram.\n");
     
    15661764
    15671765            // calculate upper mean & stdev from parabolic fit -- ignore this value
    1568             fullfitStdev = sqrt(-0.5/poly->coeff[2]);
    1569             fullfitMean = poly->coeff[1]*PS_SQR(fullfitStdev);
     1766            fullfitStdev = sqrt(-0.5 / poly->coeff[2]);
     1767            fullfitMean = poly->coeff[1] * PS_SQR(fullfitStdev);
    15701768
    15711769#ifndef PS_NO_TRACE
     
    15801778
    15811779            // saturate on min or max value
    1582             if (fullfitMean < minValueSym) {
     1780            if (fullfitMean < minValueSym)
     1781            {
    15831782                fullfitMean = minValueSym;
    15841783                psTrace(TRACE, 6, "The symmetric mean is out of bounds, saturating to %f.\n", guessMean);
     
    15861785
    15871786            // saturate on min or max value
    1588             if (fullfitMean > maxValueSym) {
     1787            if (fullfitMean > maxValueSym)
     1788            {
    15891789                fullfitMean = maxValueSym;
    15901790                psTrace(TRACE, 6, "The symmetric mean is out of bounds, saturating to %f.\n", guessMean);
    15911791            }
    15921792
    1593            
    1594             psFree (poly);
    1595         }
    1596 
    1597         // we now have the fullfit and the lowfit mean and stdev values
    1598         // accept the fullfit unless minValueSym < lowfitMean < fullfitMean
    1599 
    1600         if (isfinite(lowfitMean) && isfinite(lowfitStdev) && (lowfitMean < fullfitMean) && (lowfitMean > minValueSym)) {
    1601             guessMean  = lowfitMean;
    1602             guessStdev = lowfitStdev;
    1603         } else {
    1604             guessMean  = fullfitMean;
    1605             guessStdev = fullfitStdev;
    1606         }
    1607 
    1608         if (!isfinite(guessMean) || !isfinite(guessStdev)) {
    1609             guessMean  = stats->robustMedian;
    1610             guessStdev = stats->robustStdev;
    1611         }
    1612 
    1613         if (guessStdev > 0.75*stats->robustStdev) {
    1614             done = true;
    1615         }
    1616 
    1617        
     1793            psFree(poly);
     1794        }
     1795
     1796        // we now have the fullfit and the lowfit mean and stdev values
     1797        // accept the fullfit unless minValueSym < lowfitMean < fullfitMean
     1798
     1799        if (isfinite(lowfitMean) && isfinite(lowfitStdev) && (lowfitMean < fullfitMean) && (lowfitMean > minValueSym))
     1800        {
     1801            guessMean = lowfitMean;
     1802            guessStdev = lowfitStdev;
     1803        }
     1804        else
     1805        {
     1806            guessMean = fullfitMean;
     1807            guessStdev = fullfitStdev;
     1808        }
     1809
     1810        if (!isfinite(guessMean) || !isfinite(guessStdev))
     1811        {
     1812            guessMean = stats->robustMedian;
     1813            guessStdev = stats->robustStdev;
     1814        }
     1815
     1816        if (guessStdev > 0.75 * stats->robustStdev)
     1817        {
     1818            done = true;
     1819        }
     1820
    16181821#if (CZW && 1)
    1619         printf("CZW IN FITTED: iter   %d %f \n"
    1620                "               low    %f %f \n"
    1621                "               full   %f %f \n"
    1622                "               robust %f %f \n"
    1623                "               final  %f %f\n",
    1624                iteration,minValueSym,
    1625                lowfitMean,lowfitStdev,
    1626                fullfitMean,fullfitStdev,
    1627                stats->robustMedian,stats->robustStdev,
    1628                guessMean,guessStdev);
     1822        printf("CZW IN FITTED: iter   %d %f \n"
     1823               "               low    %f %f \n"
     1824               "               full   %f %f \n"
     1825               "               robust %f %f \n"
     1826               "               final  %f %f\n",
     1827               iteration, minValueSym,
     1828               lowfitMean, lowfitStdev,
     1829               fullfitMean, fullfitStdev,
     1830               stats->robustMedian, stats->robustStdev,
     1831               guessMean, guessStdev);
    16291832#endif
    16301833
    16311834        // Clean up after fitting
    1632         psFree (histogram);
    1633         psFree (statsMinMax);
     1835        psFree(histogram);
     1836        psFree(statsMinMax);
    16341837    }
    16351838
     
    16551858    return true;
    16561859}
    1657 
    16581860
    16591861/******************************************************************************
     
    16681870{
    16691871    psTrace(TRACE, 4, "---- %s() begin ----\n", __func__);
    1670     psTrace(TRACE, 5, "(histogram->nums->n, sigma) is (%d, %.2f\n", (int) histogram->nums->n, sigma);
     1872    psTrace(TRACE, 5, "(histogram->nums->n, sigma) is (%d, %.2f\n", (int)histogram->nums->n, sigma);
    16711873    PS_ASSERT_PTR_NON_NULL(histogram, NULL);
    16721874    PS_ASSERT_PTR_NON_NULL(histogram->bounds, NULL);
    16731875    PS_ASSERT_PTR_NON_NULL(histogram->nums, NULL);
    1674     if (psTraceGetLevel("psLib.math") >= 8) {
     1876    if (psTraceGetLevel("psLib.math") >= 8)
     1877    {
    16751878        PS_VECTOR_PRINT_F32(histogram->nums);
    16761879    }
    16771880
    1678     long numBins = histogram->nums->n;  // Number of histogram bins
     1881    long numBins = histogram->nums->n;                      // Number of histogram bins
    16791882    psVector *smooth = psVectorAlloc(numBins, PS_TYPE_F32); // Smoothed version of histogram bins
    1680     const psVector *bounds = histogram->bounds; // The bounds for the histogram bins
    1681 
    1682     if (!histogram->uniform) {
     1883    const psVector *bounds = histogram->bounds;             // The bounds for the histogram bins
     1884
     1885    if (!histogram->uniform)
     1886    {
    16831887        //
    16841888        // We get here if the histogram is non-uniform.  This code is not tested.
     
    16881892                  "histograms has not been tested or used.\n");
    16891893
    1690         for (long i = 0; i < numBins; i++) {
     1894        for (long i = 0; i < numBins; i++)
     1895        {
    16911896            // Determine the midpoint of bin i.
    16921897            float iMid = PS_BIN_MIDPOINT(histogram, i);
     
    17081913            //
    17091914            smooth->data.F32[i] = 0.0;
    1710             for (long j = jMin ; j <= jMax ; j++) {
     1915            for (long j = jMin; j <= jMax; j++)
     1916            {
    17111917                float jMid = PS_BIN_MIDPOINT(histogram, j);
    17121918                smooth->data.F32[i] +=
     
    17141920            }
    17151921        }
    1716     } else {
     1922    }
     1923    else
     1924    {
    17171925        //
    17181926        // We get here if the histogram is uniform.
    17191927        //
    1720         for (long i = 0; i < numBins; i++) {
     1928        for (long i = 0; i < numBins; i++)
     1929        {
    17211930            psF32 binSize = bounds->data.F32[1] - bounds->data.F32[0];
    17221931            psS32 gaussWidth = ((PS_GAUSS_WIDTH * sigma) / binSize);
     
    17451954            smooth->data.F32[i] = 0.0;
    17461955            float iMid = PS_BIN_MIDPOINT(histogram, i);
    1747             for (long j = jMin ; j <= jMax ; j++) {
     1956            for (long j = jMin; j <= jMax; j++)
     1957            {
    17481958                float jMid = PS_BIN_MIDPOINT(histogram, j);
    17491959                smooth->data.F32[i] +=
     
    17531963    }
    17541964
    1755     if (psTraceGetLevel("psLib.math") >= 8) {
     1965    if (psTraceGetLevel("psLib.math") >= 8)
     1966    {
    17561967        PS_VECTOR_PRINT_F32(smooth);
    17571968    }
    17581969    psTrace(TRACE, 4, "---- %s() end ----\n", __func__);
    1759     return(smooth);
     1970    return (smooth);
    17601971}
    17611972
     
    17691980static void statsFree(psStats *stats)
    17701981{
    1771     if (!stats) return;
    1772     psFree (stats->tmpData);
    1773     psFree (stats->tmpMask);
     1982    if (!stats)
     1983        return;
     1984    psFree(stats->tmpData);
     1985    psFree(stats->tmpMask);
    17741986    return;
    17751987}
     
    17781990    psStatsAlloc(): This routine must create a new psStats data structure.
    17791991*****************************************************************************/
    1780 psStats* p_psStatsAlloc(const char *file, unsigned int lineno, const char *func, psStatsOptions options)
     1992psStats *p_psStatsAlloc(const char *file, unsigned int lineno, const char *func, psStatsOptions options)
    17811993{
    17821994    psStats *stats = p_psAlloc(file, lineno, func, sizeof(psStats));
     
    17841996
    17851997    // set initial, default values
    1786     psStatsInit (stats);
     1998    psStatsInit(stats);
    17871999
    17882000    // these values are can be set as desired by the user.  they are not affected by
     
    18182030    stats->clippedMean = NAN;
    18192031    stats->clippedStdev = NAN;
    1820     stats->clippedNvalues = -1;     // XXX: This is never used
     2032    stats->clippedNvalues = -1; // XXX: This is never used
    18212033    stats->min = NAN;
    18222034    stats->max = NAN;
     
    18252037}
    18262038
    1827 
    18282039bool psMemCheckStats(psPtr ptr)
    18292040{
    18302041    PS_ASSERT_PTR(ptr, false);
    1831     return ( psMemGetDeallocator(ptr) == (psFreeFunc)statsFree );
     2042    return (psMemGetDeallocator(ptr) == (psFreeFunc)statsFree);
    18322043}
    18332044
     
    18472058XXX: Should we free stats if the asserts fail? NO; we don't own it (RHL).
    18482059*****************************************************************************/
    1849 bool psVectorStats(psStats* stats,
    1850                    const psVector* in,
    1851                    const psVector* errors,
    1852                    const psVector* mask,
     2060bool psVectorStats(psStats *stats,
     2061                   const psVector *in,
     2062                   const psVector *errors,
     2063                   const psVector *mask,
    18532064                   psVectorMaskType maskVal)
    18542065{
     
    18562067    PS_ASSERT_VECTOR_NON_NULL(in, false);
    18572068    PS_ASSERT_VECTOR_NON_EMPTY(in, false);
    1858     if (mask) {
     2069    if (mask)
     2070    {
    18592071        PS_ASSERT_VECTORS_SIZE_EQUAL(mask, in, false);
    18602072        PS_ASSERT_VECTOR_TYPE(mask, PS_TYPE_VECTOR_MASK, false);
    18612073    }
    1862     if (errors) {
     2074    if (errors)
     2075    {
    18632076        PS_ASSERT_VECTORS_SIZE_EQUAL(errors, in, false);
    18642077        PS_ASSERT_VECTOR_TYPE(errors, in->type.type, false);
     
    18662079
    18672080    // Convert types, as necessary
    1868     psVector *inF32 = NULL;             // Input vector of values, F32 version
    1869     if (in->type.type == PS_TYPE_F32) {
     2081    psVector *inF32 = NULL; // Input vector of values, F32 version
     2082    if (in->type.type == PS_TYPE_F32)
     2083    {
    18702084        inF32 = psMemIncrRefCounter((psPtr)in);
    1871     } else {
     2085    }
     2086    else
     2087    {
    18722088        inF32 = psVectorCopy(NULL, in, PS_TYPE_F32);
    18732089    }
    1874     psVector *errorsF32 = NULL;         // Input vector of errors, F32 version
    1875     if (errors) {
    1876         if (errors->type.type == PS_TYPE_F32) {
     2090    psVector *errorsF32 = NULL; // Input vector of errors, F32 version
     2091    if (errors)
     2092    {
     2093        if (errors->type.type == PS_TYPE_F32)
     2094        {
    18772095            errorsF32 = psMemIncrRefCounter((psPtr)errors);
    1878         } else {
     2096        }
     2097        else
     2098        {
    18792099            errorsF32 = psVectorCopy(NULL, errors, PS_TYPE_F32);
    18802100        }
    18812101    }
    1882     psVector *maskVector = NULL;            // Input mask vector, U8 version
    1883     if (mask) {
    1884         if (mask->type.type == PS_TYPE_VECTOR_MASK) {
     2102    psVector *maskVector = NULL; // Input mask vector, U8 version
     2103    if (mask)
     2104    {
     2105        if (mask->type.type == PS_TYPE_VECTOR_MASK)
     2106        {
    18852107            maskVector = psMemIncrRefCounter((psPtr)mask);
    1886         } else {
     2108        }
     2109        else
     2110        {
    18872111            maskVector = psVectorCopy(NULL, mask, PS_TYPE_VECTOR_MASK);
    18882112        }
    18892113    }
    18902114
    1891     if ((stats->options & PS_STAT_USE_RANGE) && (stats->min >= stats->max)) {
     2115    if ((stats->options & PS_STAT_USE_RANGE) && (stats->min >= stats->max))
     2116    {
    18922117        PS_ASSERT_FLOAT_LARGER_THAN_OR_EQUAL(stats->max, stats->min, false);
    18932118    }
    18942119
    1895     if ((stats->options & PS_STAT_USE_BINSIZE) && (stats->min >= stats->max)) {
     2120    if ((stats->options & PS_STAT_USE_BINSIZE) && (stats->min >= stats->max))
     2121    {
    18962122        PS_ASSERT_FLOAT_LARGER_THAN_OR_EQUAL(stats->binsize, 0.0, false);
    18972123    }
     
    19032129
    19042130    // ************************************************************************
    1905     if (stats->options & PS_STAT_SAMPLE_MEAN) {
    1906         // NOTE: vectorSampleMean cannot return 'false'
    1907         if (!vectorSampleMean(inF32, errorsF32, maskVector, maskVal, stats)) {
     2131    if (stats->options & PS_STAT_SAMPLE_MEAN)
     2132    {
     2133        // NOTE: vectorSampleMean cannot return 'false'
     2134        if (!vectorSampleMean(inF32, errorsF32, maskVector, maskVal, stats))
     2135        {
    19082136            psError(PS_ERR_UNKNOWN, false, "Failed to calculate vector sample mean");
    19092137            status &= false;
     
    19122140
    19132141    // ************************************************************************
    1914     if (stats->options & (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_QUARTILE)) {
    1915         // NOTE: vectorSampleMedian only returns 'false' for very bad cases:
    1916         // NULL input vector, psVectorCopy failure, invalid vector type (likely programming errors)
    1917         if (!vectorSampleMedian(inF32, maskVector, maskVal, stats)) {
    1918             psError(PS_ERR_UNKNOWN, false, "Failed to calculate sample median");
    1919             status &= false;
    1920         }
     2142    if (stats->options & (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_QUARTILE))
     2143    {
     2144        // NOTE: vectorSampleMedian only returns 'false' for very bad cases:
     2145        // NULL input vector, psVectorCopy failure, invalid vector type (likely programming errors)
     2146        if (!vectorSampleMedian(inF32, maskVector, maskVal, stats))
     2147        {
     2148            psError(PS_ERR_UNKNOWN, false, "Failed to calculate sample median");
     2149            status &= false;
     2150        }
    19212151    }
    19222152
    19232153    // ************************************************************************
    1924     if (stats->options & PS_STAT_SAMPLE_STDEV) {
    1925         // NOTE: vectorSampleStdev cannot return 'false'
    1926         if (!vectorSampleStdev(inF32, errorsF32, maskVector, maskVal, stats)) {
     2154    if (stats->options & PS_STAT_SAMPLE_STDEV)
     2155    {
     2156        // NOTE: vectorSampleStdev cannot return 'false'
     2157        if (!vectorSampleStdev(inF32, errorsF32, maskVector, maskVal, stats))
     2158        {
    19272159            psError(PS_ERR_UNKNOWN, false, "Failed to calculate sample stdev");
    19282160            status &= false;
     
    19302162    }
    19312163
    1932     if (stats->options & (PS_STAT_SAMPLE_SKEWNESS | PS_STAT_SAMPLE_KURTOSIS)) {
    1933         // NOTE: vectorSampleMoments cannot return 'false'
    1934         if (!vectorSampleMoments(inF32, maskVector, maskVal, stats)) {
     2164    if (stats->options & (PS_STAT_SAMPLE_SKEWNESS | PS_STAT_SAMPLE_KURTOSIS))
     2165    {
     2166        // NOTE: vectorSampleMoments cannot return 'false'
     2167        if (!vectorSampleMoments(inF32, maskVector, maskVal, stats))
     2168        {
    19352169            psError(PS_ERR_UNKNOWN, false, "Failed to calculate sample moments");
    19362170            status &= false;
     
    19392173
    19402174    // ************************************************************************
    1941     if (stats->options & (PS_STAT_MAX | PS_STAT_MIN)) {
    1942         // NOTE: vectorMinMax returns 0 if there are no valid values,
    1943         // but this is not an error condition.  stats.min,max are set to NAN.
    1944         // vectorMinMax cannot raise an error
     2175    if (stats->options & (PS_STAT_MAX | PS_STAT_MIN))
     2176    {
     2177        // NOTE: vectorMinMax returns 0 if there are no valid values,
     2178        // but this is not an error condition.  stats.min,max are set to NAN.
     2179        // vectorMinMax cannot raise an error
    19452180        vectorMinMax(inF32, maskVector, maskVal, stats);
    19462181    }
    19472182
    19482183    // ************************************************************************
    1949     if (stats->options & (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV | PS_STAT_ROBUST_QUARTILE)) {
    1950         if (!vectorRobustStats(inF32, errorsF32, maskVector, maskVal, stats)) {
     2184    if (stats->options & (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV | PS_STAT_ROBUST_QUARTILE))
     2185    {
     2186        if (!vectorRobustStats(inF32, errorsF32, maskVector, maskVal, stats))
     2187        {
    19512188            psError(PS_ERR_UNKNOWN, false, _("Failed to calculate robust statistics"));
    19522189            status &= false;
     
    19552192
    19562193    // ************************************************************************
    1957     if (stats->options & (PS_STAT_FITTED_MEAN | PS_STAT_FITTED_STDEV)) {
    1958         if (!vectorFittedStats(inF32, errorsF32, maskVector, maskVal, stats)) {
     2194    if (stats->options & (PS_STAT_FITTED_MEAN | PS_STAT_FITTED_STDEV))
     2195    {
     2196        if (!vectorFittedStats(inF32, errorsF32, maskVector, maskVal, stats))
     2197        {
    19592198            psError(PS_ERR_UNKNOWN, false, _("Failed to calculate fitted statistics"));
    19602199            status &= false;
     
    19632202
    19642203    // ************************************************************************
    1965     if ((stats->options & PS_STAT_CLIPPED_MEAN) || (stats->options & PS_STAT_CLIPPED_STDEV)) {
    1966         if (!vectorClippedStats(inF32, errorsF32, maskVector, maskVal, stats)) {
     2204    if ((stats->options & PS_STAT_CLIPPED_MEAN) || (stats->options & PS_STAT_CLIPPED_MEDIAN) || (stats->options & PS_STAT_CLIPPED_STDEV))
     2205    {
     2206        if (!vectorClippedStats(inF32, errorsF32, maskVector, maskVal, stats))
     2207        {
    19672208            psError(PS_ERR_UNKNOWN, false, "Failed to calculate clipped statistics\n");
    19682209            status &= false;
     
    19802221    PS_ASSERT_STRING_NON_EMPTY(string, PS_STAT_NONE);
    19812222
    1982 #define READ_STAT(NAME, SYMBOL) \
    1983     if (strcasecmp(string, NAME) == 0) { \
    1984         return SYMBOL; \
    1985     }
    1986 
    1987     READ_STAT("MEAN",       PS_STAT_SAMPLE_MEAN);
    1988     READ_STAT("STDEV",      PS_STAT_SAMPLE_STDEV);
    1989     READ_STAT("SKEWNESS",   PS_STAT_SAMPLE_SKEWNESS);
    1990     READ_STAT("KURTOSIS",   PS_STAT_SAMPLE_KURTOSIS);
    1991     READ_STAT("MEDIAN",     PS_STAT_SAMPLE_MEDIAN);
    1992     READ_STAT("QUARTILE",   PS_STAT_SAMPLE_QUARTILE);
    1993     READ_STAT("SAMPLE_MEAN",     PS_STAT_SAMPLE_MEAN);
    1994     READ_STAT("SAMPLE_STDEV",    PS_STAT_SAMPLE_STDEV);
    1995     READ_STAT("SAMPLE_MEDIAN",   PS_STAT_SAMPLE_MEDIAN);
     2223#define READ_STAT(NAME, SYMBOL)        \
     2224    if (strcasecmp(string, NAME) == 0) \
     2225    {                                  \
     2226        return SYMBOL;                 \
     2227    }
     2228
     2229    READ_STAT("MEAN", PS_STAT_SAMPLE_MEAN);
     2230    READ_STAT("STDEV", PS_STAT_SAMPLE_STDEV);
     2231    READ_STAT("SKEWNESS", PS_STAT_SAMPLE_SKEWNESS);
     2232    READ_STAT("KURTOSIS", PS_STAT_SAMPLE_KURTOSIS);
     2233    READ_STAT("MEDIAN", PS_STAT_SAMPLE_MEDIAN);
     2234    READ_STAT("QUARTILE", PS_STAT_SAMPLE_QUARTILE);
     2235    READ_STAT("SAMPLE_MEAN", PS_STAT_SAMPLE_MEAN);
     2236    READ_STAT("SAMPLE_STDEV", PS_STAT_SAMPLE_STDEV);
     2237    READ_STAT("SAMPLE_MEDIAN", PS_STAT_SAMPLE_MEDIAN);
    19962238    READ_STAT("SAMPLE_QUARTILE", PS_STAT_SAMPLE_QUARTILE);
    19972239    READ_STAT("SAMPLE_SKEWNESS", PS_STAT_SAMPLE_SKEWNESS);
    19982240    READ_STAT("SAMPLE_KURTOSIS", PS_STAT_SAMPLE_KURTOSIS);
    1999     READ_STAT("ROBUST",          PS_STAT_ROBUST_MEDIAN);
    2000     READ_STAT("ROBUST_MEDIAN",   PS_STAT_ROBUST_MEDIAN);
    2001     READ_STAT("ROBUST_STDEV",    PS_STAT_ROBUST_STDEV);
     2241    READ_STAT("ROBUST", PS_STAT_ROBUST_MEDIAN);
     2242    READ_STAT("ROBUST_MEDIAN", PS_STAT_ROBUST_MEDIAN);
     2243    READ_STAT("ROBUST_STDEV", PS_STAT_ROBUST_STDEV);
    20022244    READ_STAT("ROBUST_QUARTILE", PS_STAT_ROBUST_QUARTILE);
    2003     READ_STAT("FITTED",          PS_STAT_FITTED_MEAN);
    2004     READ_STAT("FITTED_MEAN",     PS_STAT_FITTED_MEAN);
    2005     READ_STAT("FITTED_STDEV",    PS_STAT_FITTED_STDEV);
    2006     READ_STAT("FITTED_V2",       PS_STAT_FITTED_MEAN);
    2007     READ_STAT("FITTED_MEAN_V2",  PS_STAT_FITTED_MEAN);
     2245    READ_STAT("FITTED", PS_STAT_FITTED_MEAN);
     2246    READ_STAT("FITTED_MEAN", PS_STAT_FITTED_MEAN);
     2247    READ_STAT("FITTED_STDEV", PS_STAT_FITTED_STDEV);
     2248    READ_STAT("FITTED_V2", PS_STAT_FITTED_MEAN);
     2249    READ_STAT("FITTED_MEAN_V2", PS_STAT_FITTED_MEAN);
    20082250    READ_STAT("FITTED_STDEV_V2", PS_STAT_FITTED_STDEV);
    2009     READ_STAT("FITTED_V3",       PS_STAT_FITTED_MEAN);
    2010     READ_STAT("FITTED_MEAN_V3",  PS_STAT_FITTED_MEAN);
     2251    READ_STAT("FITTED_V3", PS_STAT_FITTED_MEAN);
     2252    READ_STAT("FITTED_MEAN_V3", PS_STAT_FITTED_MEAN);
    20112253    READ_STAT("FITTED_STDEV_V3", PS_STAT_FITTED_STDEV);
    2012     READ_STAT("FITTED_V4",       PS_STAT_FITTED_MEAN);
    2013     READ_STAT("FITTED_MEAN_V4",  PS_STAT_FITTED_MEAN);
     2254    READ_STAT("FITTED_V4", PS_STAT_FITTED_MEAN);
     2255    READ_STAT("FITTED_MEAN_V4", PS_STAT_FITTED_MEAN);
    20142256    READ_STAT("FITTED_STDEV_V4", PS_STAT_FITTED_STDEV);
    2015     READ_STAT("CLIPPED",         PS_STAT_CLIPPED_MEAN);
    2016     READ_STAT("CLIPPED_MEAN",    PS_STAT_CLIPPED_MEAN);
    2017     READ_STAT("CLIPPED_STDEV",   PS_STAT_CLIPPED_STDEV);
     2257    READ_STAT("CLIPPED", PS_STAT_CLIPPED_MEAN);
     2258    READ_STAT("CLIPPED_MEAN", PS_STAT_CLIPPED_MEAN);
     2259    READ_STAT("CLIPPED_MEDIAN", PS_STAT_CLIPPED_MEDIAN);
     2260    READ_STAT("CLIPPED_STDEV", PS_STAT_CLIPPED_STDEV);
    20182261
    20192262    psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unable to parse statistic: %s\n", string);
     
    20232266psString psStatsOptionToString(psStatsOptions option)
    20242267{
    2025     psString string = NULL;             // String to return
    2026 
    2027 #define WRITE_STAT(NAME, SYMBOL) \
    2028     if (option & SYMBOL) { \
     2268    psString string = NULL; // String to return
     2269
     2270#define WRITE_STAT(NAME, SYMBOL)              \
     2271    if (option & SYMBOL)                      \
     2272    {                                         \
    20292273        psStringAppend(&string, "%s ", NAME); \
    20302274    }
    20312275
    20322276    // Same list as above (for psStatsFromString), but with repeat symbols removed
    2033     WRITE_STAT("SAMPLE_MEAN",     PS_STAT_SAMPLE_MEAN);
    2034     WRITE_STAT("SAMPLE_STDEV",    PS_STAT_SAMPLE_STDEV);
    2035     WRITE_STAT("SAMPLE_MEDIAN",   PS_STAT_SAMPLE_MEDIAN);
     2277    WRITE_STAT("SAMPLE_MEAN", PS_STAT_SAMPLE_MEAN);
     2278    WRITE_STAT("SAMPLE_STDEV", PS_STAT_SAMPLE_STDEV);
     2279    WRITE_STAT("SAMPLE_MEDIAN", PS_STAT_SAMPLE_MEDIAN);
    20362280    WRITE_STAT("SAMPLE_QUARTILE", PS_STAT_SAMPLE_QUARTILE);
    20372281    WRITE_STAT("SAMPLE_SKEWNESS", PS_STAT_SAMPLE_SKEWNESS);
    20382282    WRITE_STAT("SAMPLE_KURTOSIS", PS_STAT_SAMPLE_KURTOSIS);
    2039     WRITE_STAT("ROBUST_MEDIAN",   PS_STAT_ROBUST_MEDIAN);
    2040     WRITE_STAT("ROBUST_STDEV",    PS_STAT_ROBUST_STDEV);
     2283    WRITE_STAT("ROBUST_MEDIAN", PS_STAT_ROBUST_MEDIAN);
     2284    WRITE_STAT("ROBUST_STDEV", PS_STAT_ROBUST_STDEV);
    20412285    WRITE_STAT("ROBUST_QUARTILE", PS_STAT_ROBUST_QUARTILE);
    2042     WRITE_STAT("FITTED_MEAN",     PS_STAT_FITTED_MEAN);
    2043     WRITE_STAT("FITTED_STDEV",    PS_STAT_FITTED_STDEV);
    2044     WRITE_STAT("CLIPPED_MEAN",    PS_STAT_CLIPPED_MEAN);
    2045     WRITE_STAT("CLIPPED_STDEV",   PS_STAT_CLIPPED_STDEV);
     2286    WRITE_STAT("FITTED_MEAN", PS_STAT_FITTED_MEAN);
     2287    WRITE_STAT("FITTED_STDEV", PS_STAT_FITTED_STDEV);
     2288    WRITE_STAT("CLIPPED_MEAN", PS_STAT_CLIPPED_MEAN);
     2289    WRITE_STAT("CLIPPED_MEDIAN", PS_STAT_CLIPPED_MEDIAN);
     2290    WRITE_STAT("CLIPPED_STDEV", PS_STAT_CLIPPED_STDEV);
    20462291
    20472292    return string;
     
    20512296{
    20522297    psList *subStrings = psStringSplit(string, " ,;", false); // List of sub-strings
    2053     if (!subStrings || psListLength(subStrings) == 0) {
     2298    if (!subStrings || psListLength(subStrings) == 0)
     2299    {
    20542300        // Nothing here
    20552301        psError(PS_ERR_BAD_PARAMETER_VALUE, false, "No string to parse for statistics: %s\n", string);
     
    20572303        return NULL;
    20582304    }
    2059     psStats *stats = psStatsAlloc(0);   // Generate empty stats structure
     2305    psStats *stats = psStatsAlloc(0);                                                // Generate empty stats structure
    20602306    psListIterator *iterator = psListIteratorAlloc(subStrings, PS_LIST_HEAD, false); // Iterator
    2061     psString statString;                // Statistic string, from iteration
    2062     while ((statString = psListGetAndIncrement(iterator))) {
     2307    psString statString;                                                             // Statistic string, from iteration
     2308    while ((statString = psListGetAndIncrement(iterator)))
     2309    {
    20632310        psStatsOptions option = psStatsOptionFromString(statString);
    2064         if (option == 0) {
     2311        if (option == 0)
     2312        {
    20652313            psWarning("Unable to interpret statistic option: %s --- ignored.\n", statString);
    20662314            continue;
     
    20802328psStatsOptions psStatsSingleOption(psStatsOptions option)
    20812329{
    2082     switch (option & ~(PS_STAT_USE_RANGE | PS_STAT_USE_BINSIZE)) {
    2083       case PS_STAT_SAMPLE_MEAN:
    2084       case PS_STAT_SAMPLE_MEDIAN:
    2085       case PS_STAT_SAMPLE_STDEV:
    2086       case PS_STAT_SAMPLE_QUARTILE:
    2087       case PS_STAT_SAMPLE_SKEWNESS:
    2088       case PS_STAT_SAMPLE_KURTOSIS:
    2089       case PS_STAT_ROBUST_MEDIAN:
    2090       case PS_STAT_ROBUST_STDEV:
    2091       case PS_STAT_ROBUST_QUARTILE:
    2092       case PS_STAT_FITTED_MEAN:
    2093       case PS_STAT_FITTED_STDEV:
    2094       case PS_STAT_CLIPPED_MEAN:
    2095       case PS_STAT_CLIPPED_STDEV:
    2096       case PS_STAT_MAX:
    2097       case PS_STAT_MIN:
     2330    switch (option & ~(PS_STAT_USE_RANGE | PS_STAT_USE_BINSIZE))
     2331    {
     2332    case PS_STAT_SAMPLE_MEAN:
     2333    case PS_STAT_SAMPLE_MEDIAN:
     2334    case PS_STAT_SAMPLE_STDEV:
     2335    case PS_STAT_SAMPLE_QUARTILE:
     2336    case PS_STAT_SAMPLE_SKEWNESS:
     2337    case PS_STAT_SAMPLE_KURTOSIS:
     2338    case PS_STAT_ROBUST_MEDIAN:
     2339    case PS_STAT_ROBUST_STDEV:
     2340    case PS_STAT_ROBUST_QUARTILE:
     2341    case PS_STAT_FITTED_MEAN:
     2342    case PS_STAT_FITTED_STDEV:
     2343    case PS_STAT_CLIPPED_MEAN:
     2344    case PS_STAT_CLIPPED_MEDIAN:
     2345    case PS_STAT_CLIPPED_STDEV:
     2346    case PS_STAT_MAX:
     2347    case PS_STAT_MIN:
    20982348        return option & ~(PS_STAT_USE_RANGE | PS_STAT_USE_BINSIZE);
    2099       default:
     2349    default:
    21002350        return 0;
    21012351    }
     
    21072357{
    21082358    return options & (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_MEDIAN | PS_STAT_ROBUST_MEDIAN |
    2109                       PS_STAT_CLIPPED_MEAN | PS_STAT_FITTED_MEAN);
     2359                      PS_STAT_CLIPPED_MEAN | PS_STAT_CLIPPED_MEDIAN | PS_STAT_FITTED_MEAN);
    21102360}
    21112361
     
    21162366}
    21172367
    2118 
    21192368double psStatsGetValue(const psStats *stats, psStatsOptions option)
    21202369{
    21212370    // We could call psStatsSingle to check, but it would be a waste since we effectively do it anyway
    2122     switch (option & ~(PS_STAT_USE_RANGE | PS_STAT_USE_BINSIZE)) {
    2123       case PS_STAT_SAMPLE_MEAN:
     2371    switch (option & ~(PS_STAT_USE_RANGE | PS_STAT_USE_BINSIZE))
     2372    {
     2373    case PS_STAT_SAMPLE_MEAN:
    21242374        return stats->sampleMean;
    2125       case PS_STAT_SAMPLE_MEDIAN:
     2375    case PS_STAT_SAMPLE_MEDIAN:
    21262376        return stats->sampleMedian;
    2127       case PS_STAT_SAMPLE_STDEV:
     2377    case PS_STAT_SAMPLE_STDEV:
    21282378        return stats->sampleStdev;
    2129       case PS_STAT_SAMPLE_SKEWNESS:
     2379    case PS_STAT_SAMPLE_SKEWNESS:
    21302380        return stats->sampleSkewness;
    2131       case PS_STAT_SAMPLE_KURTOSIS:
     2381    case PS_STAT_SAMPLE_KURTOSIS:
    21322382        return stats->sampleKurtosis;
    2133       case PS_STAT_ROBUST_MEDIAN:
     2383    case PS_STAT_ROBUST_MEDIAN:
    21342384        return stats->robustMedian;
    2135       case PS_STAT_ROBUST_STDEV:
     2385    case PS_STAT_ROBUST_STDEV:
    21362386        return stats->robustStdev;
    2137       case PS_STAT_FITTED_MEAN:
     2387    case PS_STAT_FITTED_MEAN:
    21382388        return stats->fittedMean;
    2139       case PS_STAT_FITTED_STDEV:
     2389    case PS_STAT_FITTED_STDEV:
    21402390        return stats->fittedStdev;
    2141       case PS_STAT_CLIPPED_MEAN:
     2391    case PS_STAT_CLIPPED_MEAN:
    21422392        return stats->clippedMean;
    2143       case PS_STAT_CLIPPED_STDEV:
     2393    case PS_STAT_CLIPPED_MEDIAN:
     2394        return stats->clippedMedian;
     2395    case PS_STAT_CLIPPED_STDEV:
    21442396        return stats->clippedStdev;
    2145       case PS_STAT_MAX:
     2397    case PS_STAT_MAX:
    21462398        return stats->max;
    2147       case PS_STAT_MIN:
     2399    case PS_STAT_MIN:
    21482400        return stats->min;
    2149       case PS_STAT_SAMPLE_QUARTILE:
    2150       case PS_STAT_ROBUST_QUARTILE:
     2401    case PS_STAT_SAMPLE_QUARTILE:
     2402    case PS_STAT_ROBUST_QUARTILE:
    21512403        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Cannot return a single quartile value; "
    2152                 "get them yourself.\n");
     2404                                                  "get them yourself.\n");
    21532405        return NAN;
    2154       default:
     2406    default:
    21552407        return NAN;
    21562408    }
     
    21612413// other private functions used above
    21622414
    2163 # if (0)
     2415#if (0)
    21642416static psF32 QuadraticInverse(psF32 a,
    21652417                              psF32 b,
     
    21672419                              psF32 y,
    21682420                              psF32 xLo,
    2169                               psF32 xHi
    2170     )
     2421                              psF32 xHi)
    21712422{
    2172     psF64 tmp = sqrt((y - c)/a + (b*b)/(4.0 * a * a));
    2173 
    2174     psF64 x1 = -b/(2.0*a) + tmp;
    2175     psF64 x2 = -b/(2.0*a) - tmp;
    2176 
    2177     if (xLo <= x1 && x1 <= xHi) {
     2423    psF64 tmp = sqrt((y - c) / a + (b * b) / (4.0 * a * a));
     2424
     2425    psF64 x1 = -b / (2.0 * a) + tmp;
     2426    psF64 x2 = -b / (2.0 * a) - tmp;
     2427
     2428    if (xLo <= x1 && x1 <= xHi)
     2429    {
    21782430        return x1;
    21792431    }
    2180     if (xLo <= x2 && x2 <= xHi) {
     2432    if (xLo <= x2 && x2 <= xHi)
     2433    {
    21812434        return x2;
    21822435    }
     
    21852438
    21862439static psF32 LinearInverse(psF32 a,
    2187                            psF32 b,
    2188                            psF32 y,
    2189                            psF32 xLo,
    2190                            psF32 xHi
    2191     )
     2440                           psF32 b,
     2441                           psF32 y,
     2442                           psF32 xLo,
     2443                           psF32 xHi)
    21922444{
    21932445    psF64 x = (y - b) / a;
    21942446
    2195     if (xLo <= x && x <= xHi) {
     2447    if (xLo <= x && x <= xHi)
     2448    {
    21962449        return x;
    21972450    }
    21982451    return 0.5 * (xLo + xHi);
    21992452}
    2200 # endif
    2201 
    2202 # if (0)
     2453#endif
     2454
     2455#if (0)
    22032456/******************************************************************************
    22042457fitQuadraticSearchForYThenReturnX(*xVec, *yVec, binNum, yVal): A general
     
    22142467                                               psVector *yVec,
    22152468                                               psS32 binNum,
    2216                                                psF32 yVal
    2217     )
     2469                                               psF32 yVal)
    22182470{
    22192471    psTrace(TRACE, 4, "---- %s() begin ----\n", __func__);
    22202472    psTrace(TRACE, 5, "binNum, yVal is (%d, %f)\n", binNum, yVal);
    2221     if (psTraceGetLevel("psLib.math") >= 8) {
     2473    if (psTraceGetLevel("psLib.math") >= 8)
     2474    {
    22222475        PS_VECTOR_PRINT_F32(xVec);
    22232476        PS_VECTOR_PRINT_F32(yVec);
     
    22362489    psF32 tmpFloat = 0.0f;
    22372490
    2238     if ((binNum >= 1) && (binNum < (yVec->n - 2)) && (binNum < (xVec->n - 2))) {
     2491    if ((binNum >= 1) && (binNum < (yVec->n - 2)) && (binNum < (xVec->n - 2)))
     2492    {
    22392493        // The general case.  We have all three points.
    2240         x->data.F64[0] = (psF64) (0.5 * (xVec->data.F32[binNum - 1] + xVec->data.F32[binNum]));
    2241         x->data.F64[1] = (psF64) (0.5 * (xVec->data.F32[binNum] + xVec->data.F32[binNum+1]));
    2242         x->data.F64[2] = (psF64) (0.5 * (xVec->data.F32[binNum+1] + xVec->data.F32[binNum+2]));
     2494        x->data.F64[0] = (psF64)(0.5 * (xVec->data.F32[binNum - 1] + xVec->data.F32[binNum]));
     2495        x->data.F64[1] = (psF64)(0.5 * (xVec->data.F32[binNum] + xVec->data.F32[binNum + 1]));
     2496        x->data.F64[2] = (psF64)(0.5 * (xVec->data.F32[binNum + 1] + xVec->data.F32[binNum + 2]));
    22432497        y->data.F64[0] = yVec->data.F32[binNum - 1];
    22442498        y->data.F64[1] = yVec->data.F32[binNum];
    22452499        y->data.F64[2] = yVec->data.F32[binNum + 1];
    22462500        psTrace(TRACE, 6, "x vec (orig) is (%f %f %f %f)\n", xVec->data.F32[binNum - 1],
    2247                 xVec->data.F32[binNum], xVec->data.F32[binNum+1], xVec->data.F32[binNum+2]);
     2501                xVec->data.F32[binNum], xVec->data.F32[binNum + 1], xVec->data.F32[binNum + 2]);
    22482502        psTrace(TRACE, 6, "x data is (%f %f %f)\n", x->data.F64[0], x->data.F64[1], x->data.F64[2]);
    22492503        psTrace(TRACE, 6, "y data is (%f %f %f)\n", y->data.F64[0], y->data.F64[1], y->data.F64[2]);
     
    22522506        // Ensure that the y value lies within range of the y values.
    22532507        //
    2254         if (! (((y->data.F64[0] <= yVal) && (yVal <= y->data.F64[2])) ||
    2255                ((y->data.F64[2] <= yVal) && (yVal <= y->data.F64[0]))) ) {
     2508        if (!(((y->data.F64[0] <= yVal) && (yVal <= y->data.F64[2])) ||
     2509              ((y->data.F64[2] <= yVal) && (yVal <= y->data.F64[0]))))
     2510        {
    22562511            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    22572512                    _("Specified yVal, %g, is not within y-range, %g to %g."),
     
    22632518        //
    22642519        if (((y->data.F64[0] < y->data.F64[1]) && !(y->data.F64[1] <= y->data.F64[2])) ||
    2265             ((y->data.F64[0] > y->data.F64[1]) && !(y->data.F64[1] >= y->data.F64[2]))) {
     2520            ((y->data.F64[0] > y->data.F64[1]) && !(y->data.F64[1] >= y->data.F64[2])))
     2521        {
    22662522            psError(PS_ERR_UNKNOWN, true,
    22672523                    "This routine must be called with monotonically increasing or decreasing data points.\n");
     
    22742530        // Determine the coefficients of the polynomial.
    22752531        psPolynomial1D *myPoly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, 2);
    2276         if (!psVectorFitPolynomial1D(myPoly, NULL, 0, y, NULL, x)) {
     2532        if (!psVectorFitPolynomial1D(myPoly, NULL, 0, y, NULL, x))
     2533        {
    22772534            psError(PS_ERR_UNEXPECTED_NULL, false,
    22782535                    _("Failed to fit a 1-dimensional polynomial to the three specified data points.  "
     
    22872544        psTrace(TRACE, 6, "myPoly->coeff[2] is %f\n", myPoly->coeff[2]);
    22882545        psTrace(TRACE, 6, "Fitted y vec is (%f %f %f)\n",
    2289                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[0]),
    2290                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[1]),
    2291                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[2]));
     2546                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[0]),
     2547                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[1]),
     2548                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[2]));
    22922549
    22932550        psTrace(TRACE, 6, "We fit the polynomial, now find x such that f(x) equals %f\n", yVal);
     
    22962553        psFree(myPoly);
    22972554
    2298         if (isnan(tmpFloat)) {
     2555        if (isnan(tmpFloat))
     2556        {
    22992557            psError(PS_ERR_UNEXPECTED_NULL,
    23002558                    false, _("Failed to determine the median of the fitted polynomial.  Returning NAN."));
     
    23022560            psFree(y);
    23032561            psTrace(TRACE, 5, "---- %s(NAN) end ----\n", __func__);
    2304             return(NAN);
    2305         }
    2306     } else {
     2562            return (NAN);
     2563        }
     2564    }
     2565    else
     2566    {
    23072567        // These are special cases where the bin is at the beginning or end of the vector.
    2308         if (binNum == 0) {
     2568        if (binNum == 0)
     2569        {
    23092570            // We have two points only at the beginning of the vectors x and y.
    23102571            tmpFloat = 0.5 * (xVec->data.F32[binNum] +
    23112572                              xVec->data.F32[binNum + 1]);
    2312         } else if (binNum == (xVec->n - 1)) {
     2573        }
     2574        else if (binNum == (xVec->n - 1))
     2575        {
    23132576            // The special case where we have two points only at the end of
    23142577            // the vectors x and y.
    23152578            // XXX: Is this right?
    23162579            tmpFloat = xVec->data.F32[binNum];
    2317         } else if (binNum == (xVec->n - 2)) {
     2580        }
     2581        else if (binNum == (xVec->n - 2))
     2582        {
    23182583            // XXX: Is this right?
    23192584            tmpFloat = 0.5 * (xVec->data.F32[binNum] + xVec->data.F32[binNum + 1]);
     
    23412606                                                          psVector *yVec,
    23422607                                                          psS32 binNum,
    2343                                                           psF32 yVal
    2344     )
     2608                                                          psF32 yVal)
    23452609{
    23462610    psTrace(TRACE, 4, "---- %s() begin ----\n", __func__);
    23472611    psTrace(TRACE, 5, "binNum, yVal is (%d, %f)\n", binNum, yVal);
    2348     if (psTraceGetLevel("psLib.math") >= 8) {
     2612    if (psTraceGetLevel("psLib.math") >= 8)
     2613    {
    23492614        PS_VECTOR_PRINT_F32(xVec);
    23502615        PS_VECTOR_PRINT_F32(yVec);
     
    23622627    psF32 tmpFloat = 0.0f;
    23632628
    2364     if ((binNum >= 1) && (binNum < (yVec->n - 2)) && (binNum < (xVec->n - 2))) {
     2629    if ((binNum >= 1) && (binNum < (yVec->n - 2)) && (binNum < (xVec->n - 2)))
     2630    {
    23652631        // The general case.  We have all three points.
    23662632        x->data.F64[0] = xVec->data.F32[binNum - 1];
    23672633        x->data.F64[1] = xVec->data.F32[binNum];
    2368         x->data.F64[2] = xVec->data.F32[binNum+1];
     2634        x->data.F64[2] = xVec->data.F32[binNum + 1];
    23692635        y->data.F64[0] = yVec->data.F32[binNum - 1];
    23702636        y->data.F64[1] = yVec->data.F32[binNum];
    23712637        y->data.F64[2] = yVec->data.F32[binNum + 1];
    23722638        psTrace(TRACE, 6, "x vec (orig) is (%f %f %f %f)\n", xVec->data.F32[binNum - 1],
    2373                 xVec->data.F32[binNum], xVec->data.F32[binNum+1], xVec->data.F32[binNum+2]);
     2639                xVec->data.F32[binNum], xVec->data.F32[binNum + 1], xVec->data.F32[binNum + 2]);
    23742640        psTrace(TRACE, 6, "x data is (%f %f %f)\n", x->data.F64[0], x->data.F64[1], x->data.F64[2]);
    23752641        psTrace(TRACE, 6, "y data is (%f %f %f)\n", y->data.F64[0], y->data.F64[1], y->data.F64[2]);
     
    23782644        // Ensure that the y value lies within range of the y values.
    23792645        //
    2380         if (! (((y->data.F64[0] <= yVal) && (yVal <= y->data.F64[2])) ||
    2381                ((y->data.F64[2] <= yVal) && (yVal <= y->data.F64[0]))) ) {
     2646        if (!(((y->data.F64[0] <= yVal) && (yVal <= y->data.F64[2])) ||
     2647              ((y->data.F64[2] <= yVal) && (yVal <= y->data.F64[0]))))
     2648        {
    23822649            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    23832650                    _("Specified yVal, %g, is not within y-range, %g to %g."),
     
    23892656        //
    23902657        if (((y->data.F64[0] < y->data.F64[1]) && !(y->data.F64[1] <= y->data.F64[2])) ||
    2391             ((y->data.F64[0] > y->data.F64[1]) && !(y->data.F64[1] >= y->data.F64[2]))) {
     2658            ((y->data.F64[0] > y->data.F64[1]) && !(y->data.F64[1] >= y->data.F64[2])))
     2659        {
    23922660            psError(PS_ERR_UNKNOWN, true,
    23932661                    "This routine must be called with monotonically increasing or decreasing data points.\n");
     
    24002668        // Determine the coefficients of the polynomial.
    24012669        psPolynomial1D *myPoly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, 2);
    2402         if (!psVectorFitPolynomial1D(myPoly, NULL, 0, y, NULL, x)) {
     2670        if (!psVectorFitPolynomial1D(myPoly, NULL, 0, y, NULL, x))
     2671        {
    24032672            psError(PS_ERR_UNEXPECTED_NULL, false,
    24042673                    _("Failed to fit a 1-dimensional polynomial to the three specified data points.  "
     
    24132682        psTrace(TRACE, 6, "myPoly->coeff[2] is %f\n", myPoly->coeff[2]);
    24142683        psTrace(TRACE, 6, "Fitted y vec is (%f %f %f)\n",
    2415                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[0]),
    2416                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[1]),
    2417                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[2]));
     2684                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[0]),
     2685                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[1]),
     2686                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[2]));
    24182687
    24192688        psTrace(TRACE, 6, "We fit the polynomial, now find x such that f(x) equals %f\n", yVal);
     
    24222691        psFree(myPoly);
    24232692
    2424         if (isnan(tmpFloat)) {
     2693        if (isnan(tmpFloat))
     2694        {
    24252695            psError(PS_ERR_UNEXPECTED_NULL,
    24262696                    false, _("Failed to determine the median of the fitted polynomial.  Returning NAN."));
     
    24282698            psFree(y);
    24292699            psTrace(TRACE, 5, "---- %s(NAN) end ----\n", __func__);
    2430             return(NAN);
    2431         }
    2432     } else {
     2700            return (NAN);
     2701        }
     2702    }
     2703    else
     2704    {
    24332705        // These are special cases where the bin is at the beginning or end of the vector.
    2434         if (binNum == 0) {
     2706        if (binNum == 0)
     2707        {
    24352708            // We have two points only at the beginning of the vectors x and y.
    24362709            // XXX this does not seem to be doing the linear interpolation / extrapolation
    24372710            tmpFloat = 0.5 * (xVec->data.F32[binNum] +
    24382711                              xVec->data.F32[binNum + 1]);
    2439         } else if (binNum == (xVec->n - 1)) {
     2712        }
     2713        else if (binNum == (xVec->n - 1))
     2714        {
    24402715            // The special case where we have two points only at the end of
    24412716            // the vectors x and y.
    24422717            // XXX: Is this right?
    24432718            tmpFloat = xVec->data.F32[binNum];
    2444         } else if (binNum == (xVec->n - 2)) {
     2719        }
     2720        else if (binNum == (xVec->n - 2))
     2721        {
    24452722            // XXX: Is this right?
    24462723            tmpFloat = 0.5 * (xVec->data.F32[binNum] + xVec->data.F32[binNum + 1]);
     
    24722749                                                 psVector *yVec,
    24732750                                                 psS32 binNum,
    2474                                                  psF32 yVal
    2475     )
     2751                                                 psF32 yVal)
    24762752{
    24772753    psTrace(TRACE, 5, "binNum, yVal is (%d, %f)\n", binNum, yVal);
    2478     if (psTraceGetLevel("psLib.math") >= 8) {
     2754    if (psTraceGetLevel("psLib.math") >= 8)
     2755    {
    24792756        PS_VECTOR_PRINT_F32(xVec);
    24802757        PS_VECTOR_PRINT_F32(yVec);
     
    24952772
    24962773    //    if ((binNum >= 1) && (binNum <= (yVec->n - 2)) && (binNum <= (xVec->n - 2))) {
    2497     if ((binNum >= 2) && (binNum <= (yVec->n - 3)) && (binNum <= (xVec->n - 3))) {
     2774    if ((binNum >= 2) && (binNum <= (yVec->n - 3)) && (binNum <= (xVec->n - 3)))
     2775    {
    24982776        // The general case.  We have all three points.
    2499       //        x->data.F64[0] = binNum - 1;
    2500       //        x->data.F64[1] = binNum;
    2501       //        x->data.F64[2] = binNum + 1;
    2502       x->data.F64[0] = xVec->data.F32[binNum - 2];
    2503       x->data.F64[1] = xVec->data.F32[binNum - 1];
    2504       x->data.F64[2] = xVec->data.F32[binNum + 0];
    2505       x->data.F64[3] = xVec->data.F32[binNum + 1];
    2506       x->data.F64[4] = xVec->data.F32[binNum + 2];
     2777        //        x->data.F64[0] = binNum - 1;
     2778        //        x->data.F64[1] = binNum;
     2779        //        x->data.F64[2] = binNum + 1;
     2780        x->data.F64[0] = xVec->data.F32[binNum - 2];
     2781        x->data.F64[1] = xVec->data.F32[binNum - 1];
     2782        x->data.F64[2] = xVec->data.F32[binNum + 0];
     2783        x->data.F64[3] = xVec->data.F32[binNum + 1];
     2784        x->data.F64[4] = xVec->data.F32[binNum + 2];
    25072785        y->data.F64[0] = yVec->data.F32[binNum - 2];
    25082786        y->data.F64[1] = yVec->data.F32[binNum - 1];
    25092787        y->data.F64[2] = yVec->data.F32[binNum + 0];
    2510         y->data.F64[3] = yVec->data.F32[binNum + 1];
    2511         y->data.F64[4] = yVec->data.F32[binNum + 2];
    2512         psTrace(TRACE, 6, "x vec (orig) is (%f %f %f %f)\n", xVec->data.F32[binNum - 1], xVec->data.F32[binNum], xVec->data.F32[binNum+1], xVec->data.F32[binNum+2]);
     2788        y->data.F64[3] = yVec->data.F32[binNum + 1];
     2789        y->data.F64[4] = yVec->data.F32[binNum + 2];
     2790        psTrace(TRACE, 6, "x vec (orig) is (%f %f %f %f)\n", xVec->data.F32[binNum - 1], xVec->data.F32[binNum], xVec->data.F32[binNum + 1], xVec->data.F32[binNum + 2]);
    25132791        psTrace(TRACE, 6, "x data is (%f %f %f)\n", x->data.F64[0], x->data.F64[1], x->data.F64[2]);
    25142792        psTrace(TRACE, 6, "y data is (%f %f %f)\n", y->data.F64[0], y->data.F64[1], y->data.F64[2]);
    25152793
    2516 
    25172794        // Ensure that the y value lies within range of the y values.
    2518         if (! (((y->data.F64[0] <= yVal) && (yVal <= y->data.F64[4])) ||
    2519                ((y->data.F64[4] <= yVal) && (yVal <= y->data.F64[0]))) ) {
     2795        if (!(((y->data.F64[0] <= yVal) && (yVal <= y->data.F64[4])) ||
     2796              ((y->data.F64[4] <= yVal) && (yVal <= y->data.F64[0]))))
     2797        {
    25202798            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    25212799                    _("Specified yVal, %g, is not within y-range, %g to %g."),
     
    25262804        // Ensure that the y values are monotonic.
    25272805        if (((y->data.F64[0] < y->data.F64[1]) && !(y->data.F64[1] <= y->data.F64[2])) ||
    2528             ((y->data.F64[0] > y->data.F64[1]) && !(y->data.F64[1] >= y->data.F64[2]))) {
     2806            ((y->data.F64[0] > y->data.F64[1]) && !(y->data.F64[1] >= y->data.F64[2])))
     2807        {
    25292808            psError(PS_ERR_UNKNOWN, true,
    25302809                    "This routine must be called with monotonically increasing or decreasing data points.\n");
     
    25362815        // Determine the coefficients of the polynomial.
    25372816        psPolynomial1D *myPoly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, 2);
    2538         if (!psVectorFitPolynomial1D(myPoly, NULL, 0, y, NULL, x)) {
     2817        if (!psVectorFitPolynomial1D(myPoly, NULL, 0, y, NULL, x))
     2818        {
    25392819            psError(PS_ERR_UNEXPECTED_NULL, false,
    25402820                    _("Failed to fit a 1-dimensional polynomial to the three specified data points.  "
     
    25492829        psTrace(TRACE, 6, "myPoly->coeff[2] is %f\n", myPoly->coeff[2]);
    25502830        psTrace(TRACE, 6, "Fitted y vec is (%f %f %f)\n",
    2551                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[0]),
    2552                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[1]),
    2553                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[2]));
     2831                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[0]),
     2832                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[1]),
     2833                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[2]));
    25542834
    25552835        psTrace(TRACE, 6, "We fit the polynomial, now find x such that f(x) equals %f\n", yVal);
     
    25572837        psFree(myPoly);
    25582838
    2559         if (isnan(binValue)) {
     2839        if (isnan(binValue))
     2840        {
    25602841            psError(PS_ERR_UNEXPECTED_NULL,
    25612842                    false, _("Failed to determine the median of the fitted polynomial.  Returning NAN."));
    25622843            psFree(x);
    25632844            psFree(y);
    2564             return(NAN);
    2565         }
    2566        
     2845            return (NAN);
     2846        }
     2847
    25672848        // I believe that mathematically the fitted bin position must be between binNum - 1 and binNum + 1
    2568         //      assert (binValue >= binNum - 1);
    2569         //      assert (binValue <= binNum + 1);
    2570 
    2571         //      int fitBin = binValue;
    2572         //        float dX = xVec->data.F32[fitBin+1] - xVec->data.F32[fitBin];
    2573         //        float dY = binValue - fitBin;
    2574         //        tmpFloat = xVec->data.F32[fitBin] + dY * dX;
    2575         tmpFloat = binValue;
    2576        
    2577     } else {
     2849        //      assert (binValue >= binNum - 1);
     2850        //      assert (binValue <= binNum + 1);
     2851
     2852        //      int fitBin = binValue;
     2853        //        float dX = xVec->data.F32[fitBin+1] - xVec->data.F32[fitBin];
     2854        //        float dY = binValue - fitBin;
     2855        //        tmpFloat = xVec->data.F32[fitBin] + dY * dX;
     2856        tmpFloat = binValue;
     2857    }
     2858    else
     2859    {
    25782860        // These are special cases where the bin is at the beginning or end of the vector.
    2579         if (binNum == 0) {
     2861        if (binNum == 0)
     2862        {
    25802863            // We have two points only at the beginning of the vectors x and y.
    25812864            // X = (dX/dY)(Y - Yo) + Xo
    25822865            float dX = xVec->data.F32[1] - xVec->data.F32[0];
    25832866            float dY = yVec->data.F32[1] - yVec->data.F32[0];
    2584             if (dY == 0.0) {
     2867            if (dY == 0.0)
     2868            {
    25852869                tmpFloat = xVec->data.F32[0];
    2586             } else {
     2870            }
     2871            else
     2872            {
    25872873                tmpFloat = (yVal - yVec->data.F32[0]) * (dX / dY) + xVec->data.F32[0];
    25882874            }
    2589         } else if (binNum == (xVec->n - 1)) {
     2875        }
     2876        else if (binNum == (xVec->n - 1))
     2877        {
    25902878            // We have two points only at the end of the vectors x and y.
    25912879            // X = (dX/dY)(Y - Yo) + Xo
    2592             float dX = xVec->data.F32[binNum] - xVec->data.F32[binNum-1];
    2593             float dY = yVec->data.F32[binNum] - yVec->data.F32[binNum-1];
    2594             if (dY == 0.0) {
    2595                 tmpFloat = xVec->data.F32[binNum-1];
    2596             } else {
    2597                 tmpFloat = (yVal - yVec->data.F32[binNum-1]) * (dX / dY) + xVec->data.F32[binNum-1];
     2880            float dX = xVec->data.F32[binNum] - xVec->data.F32[binNum - 1];
     2881            float dY = yVec->data.F32[binNum] - yVec->data.F32[binNum - 1];
     2882            if (dY == 0.0)
     2883            {
     2884                tmpFloat = xVec->data.F32[binNum - 1];
     2885            }
     2886            else
     2887            {
     2888                tmpFloat = (yVal - yVec->data.F32[binNum - 1]) * (dX / dY) + xVec->data.F32[binNum - 1];
    25982889            }
    25992890        }
     
    26062897    return tmpFloat;
    26072898}
    2608 # endif
    2609 
     2899#endif
    26102900
    26112901/******************************************************************************
     
    26232913*****************************************************************************/
    26242914static psF32 fitLinearSearchForYThenReturnBin(const psVector *xVec,
    2625                                               psVector *yVec,
    2626                                               psS32 binNum,
    2627                                               psF32 yVal
    2628     )
     2915                                              psVector *yVec,
     2916                                              psS32 binNum,
     2917                                              psF32 yVal)
    26292918{
    26302919
    2631 # if (1)
    2632 # define HALF_SIZE 2
    2633   double Sx = 0.0;
    2634 
    2635   double Sy = 0.0;
    2636   double Sxx = 0.0;
    2637   double Sxy = 0.0;
    2638   double deltaY = 0.0;
    2639   int N = 0;
    2640 
    2641   for (int u = binNum - HALF_SIZE; u <= binNum + HALF_SIZE; u++) {
    2642     if ((u >= 0)&&(u < yVec->n)) {
    2643       if (u+1 < xVec->n) {
    2644         Sx += yVec->data.F32[u];
    2645         Sxx += PS_SQR(yVec->data.F32[u]);
    2646 
    2647         deltaY = xVec->data.F32[u];
    2648         //deltaY = 0.5 * (xVec->data.F32[u] + xVec->data.F32[u+1]);
    2649         Sy += deltaY;
    2650         Sxy += yVec->data.F32[u] * deltaY;
    2651         N += 1;
    2652       }
    2653     }
    2654   }
    2655   double Det = N * Sxx - Sx * Sx;
    2656   if (Det == 0.0) return NAN;
    2657   if (N == 0) return NAN;
    2658 
    2659   double C0 = (Sy*Sxx - Sx*Sxy) / Det;
    2660   double C1 = (Sxy*N - Sx*Sy) / Det;
    2661  
    2662   double value = C0 + yVal*C1;
    2663   return value;
    2664  
    2665  
    2666 # else
     2920#if (1)
     2921#define HALF_SIZE 2
     2922    double Sx = 0.0;
     2923
     2924    double Sy = 0.0;
     2925    double Sxx = 0.0;
     2926    double Sxy = 0.0;
     2927    double deltaY = 0.0;
     2928    int N = 0;
     2929
     2930    for (int u = binNum - HALF_SIZE; u <= binNum + HALF_SIZE; u++)
     2931    {
     2932        if ((u >= 0) && (u < yVec->n))
     2933        {
     2934            if (u + 1 < xVec->n)
     2935            {
     2936                Sx += yVec->data.F32[u];
     2937                Sxx += PS_SQR(yVec->data.F32[u]);
     2938
     2939                deltaY = xVec->data.F32[u];
     2940                // deltaY = 0.5 * (xVec->data.F32[u] + xVec->data.F32[u+1]);
     2941                Sy += deltaY;
     2942                Sxy += yVec->data.F32[u] * deltaY;
     2943                N += 1;
     2944            }
     2945        }
     2946    }
     2947    double Det = N * Sxx - Sx * Sx;
     2948    if (Det == 0.0)
     2949        return NAN;
     2950    if (N == 0)
     2951        return NAN;
     2952
     2953    double C0 = (Sy * Sxx - Sx * Sxy) / Det;
     2954    double C1 = (Sxy * N - Sx * Sy) / Det;
     2955
     2956    double value = C0 + yVal * C1;
     2957    return value;
     2958
     2959#else
    26672960    psTrace(TRACE, 5, "binNum, yVal is (%d, %f)\n", binNum, yVal);
    2668     if (psTraceGetLevel("psLib.math") >= 8) {
     2961    if (psTraceGetLevel("psLib.math") >= 8)
     2962    {
    26692963        PS_VECTOR_PRINT_F32(xVec);
    26702964        PS_VECTOR_PRINT_F32(yVec);
     
    26842978    psF32 tmpFloat = 0.0f;
    26852979
    2686     if ((binNum >= 2) && (binNum <= (yVec->n - 3)) && (binNum <= (xVec->n - 3))) {
    2687         x->data.F64[0] = xVec->data.F32[binNum - 2];
    2688         x->data.F64[1] = xVec->data.F32[binNum - 1];
    2689         x->data.F64[2] = xVec->data.F32[binNum + 0];
    2690         x->data.F64[3] = xVec->data.F32[binNum + 1];
    2691         x->data.F64[4] = xVec->data.F32[binNum + 2];
    2692 
    2693         y->data.F64[0] = yVec->data.F32[binNum - 2];
    2694         y->data.F64[1] = yVec->data.F32[binNum - 1];
    2695         y->data.F64[2] = yVec->data.F32[binNum + 0];
    2696         y->data.F64[3] = yVec->data.F32[binNum + 1];
    2697         y->data.F64[4] = yVec->data.F32[binNum + 2];
    2698         psTrace(TRACE, 6, "x vec (orig) is (%f %f %f %f)\n", xVec->data.F32[binNum - 1], xVec->data.F32[binNum], xVec->data.F32[binNum+1], xVec->data.F32[binNum+2]);
    2699         psTrace(TRACE, 6, "x data is (%f %f %f)\n", x->data.F64[0], x->data.F64[1], x->data.F64[2]);
    2700         psTrace(TRACE, 6, "y data is (%f %f %f)\n", y->data.F64[0], y->data.F64[1], y->data.F64[2]);
    2701 
    2702         // Ensure that the y value lies within range of the y values.
    2703         if (! (((y->data.F64[0] <= yVal) && (yVal <= y->data.F64[4])) ||
    2704                ((y->data.F64[4] <= yVal) && (yVal <= y->data.F64[0]))) ) {
    2705             psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    2706                     _("Specified yVal, %g, is not within y-range, %g to %g."),
     2980    if ((binNum >= 2) && (binNum <= (yVec->n - 3)) && (binNum <= (xVec->n - 3)))
     2981    {
     2982        x->data.F64[0] = xVec->data.F32[binNum - 2];
     2983        x->data.F64[1] = xVec->data.F32[binNum - 1];
     2984        x->data.F64[2] = xVec->data.F32[binNum + 0];
     2985        x->data.F64[3] = xVec->data.F32[binNum + 1];
     2986        x->data.F64[4] = xVec->data.F32[binNum + 2];
     2987
     2988        y->data.F64[0] = yVec->data.F32[binNum - 2];
     2989        y->data.F64[1] = yVec->data.F32[binNum - 1];
     2990        y->data.F64[2] = yVec->data.F32[binNum + 0];
     2991        y->data.F64[3] = yVec->data.F32[binNum + 1];
     2992        y->data.F64[4] = yVec->data.F32[binNum + 2];
     2993        psTrace(TRACE, 6, "x vec (orig) is (%f %f %f %f)\n", xVec->data.F32[binNum - 1], xVec->data.F32[binNum], xVec->data.F32[binNum + 1], xVec->data.F32[binNum + 2]);
     2994        psTrace(TRACE, 6, "x data is (%f %f %f)\n", x->data.F64[0], x->data.F64[1], x->data.F64[2]);
     2995        psTrace(TRACE, 6, "y data is (%f %f %f)\n", y->data.F64[0], y->data.F64[1], y->data.F64[2]);
     2996
     2997        // Ensure that the y value lies within range of the y values.
     2998        if (!(((y->data.F64[0] <= yVal) && (yVal <= y->data.F64[4])) ||
     2999              ((y->data.F64[4] <= yVal) && (yVal <= y->data.F64[0]))))
     3000        {
     3001            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     3002                    _("Specified yVal, %g, is not within y-range, %g to %g."),
    27073003                    (psF64)yVal, y->data.F64[0], y->data.F64[2]);
    27083004            return NAN;
     
    27113007        // Ensure that the y values are monotonic.
    27123008        if (((y->data.F64[0] < y->data.F64[1]) && !(y->data.F64[1] <= y->data.F64[2])) ||
    2713             ((y->data.F64[0] > y->data.F64[1]) && !(y->data.F64[1] >= y->data.F64[2]))) {
     3009            ((y->data.F64[0] > y->data.F64[1]) && !(y->data.F64[1] >= y->data.F64[2])))
     3010        {
    27143011            psError(PS_ERR_UNKNOWN, true,
    27153012                    "This routine must be called with monotonically increasing or decreasing data points.\n");
     
    27213018        // Determine the coefficients of the polynomial.
    27223019        psPolynomial1D *myPoly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, 1);
    2723         if (!psVectorFitPolynomial1D(myPoly, NULL, 0, y, NULL, x)) {
     3020        if (!psVectorFitPolynomial1D(myPoly, NULL, 0, y, NULL, x))
     3021        {
    27243022            psError(PS_ERR_UNEXPECTED_NULL, false,
    27253023                    _("Failed to fit a 1-dimensional polynomial to the three specified data points.  "
     
    27333031        psTrace(TRACE, 6, "myPoly->coeff[1] is %f\n", myPoly->coeff[1]);
    27343032        psTrace(TRACE, 6, "Fitted y vec is (%f %f)\n",
    2735                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[0]),
    2736                 (psF32) psPolynomial1DEval(myPoly, (psF64) x->data.F64[1]));
     3033                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[0]),
     3034                (psF32)psPolynomial1DEval(myPoly, (psF64)x->data.F64[1]));
    27373035
    27383036        psTrace(TRACE, 6, "We fit the polynomial, now find x such that f(x) equals %f\n", yVal);
     
    27403038        psFree(myPoly);
    27413039
    2742         if (isnan(binValue)) {
     3040        if (isnan(binValue))
     3041        {
    27433042            psError(PS_ERR_UNEXPECTED_NULL,
    27443043                    false, _("Failed to determine the median of the fitted polynomial.  Returning NAN."));
    27453044            psFree(x);
    27463045            psFree(y);
    2747             return(NAN);
    2748         }
    2749        
     3046            return (NAN);
     3047        }
     3048
    27503049        // I believe that mathematically the fitted bin position must be between binNum - 1 and binNum + 1
    2751         //      assert (binValue >= binNum - 1);
    2752         //      assert (binValue <= binNum + 1);
    2753 
    2754         //      int fitBin = binValue;
    2755         //        float dX = xVec->data.F32[fitBin+1] - xVec->data.F32[fitBin];
    2756         //        float dY = binValue - fitBin;
    2757         //        tmpFloat = xVec->data.F32[fitBin] + dY * dX;
    2758         tmpFloat = binValue;
    2759                
    2760        
    2761     } else {
     3050        //      assert (binValue >= binNum - 1);
     3051        //      assert (binValue <= binNum + 1);
     3052
     3053        //      int fitBin = binValue;
     3054        //        float dX = xVec->data.F32[fitBin+1] - xVec->data.F32[fitBin];
     3055        //        float dY = binValue - fitBin;
     3056        //        tmpFloat = xVec->data.F32[fitBin] + dY * dX;
     3057        tmpFloat = binValue;
     3058    }
     3059    else
     3060    {
    27623061        // These are special cases where the bin is at the beginning or end of the vector.
    2763         if (binNum == 0) {
     3062        if (binNum == 0)
     3063        {
    27643064            // We have two points only at the beginning of the vectors x and y.
    27653065            // X = (dX/dY)(Y - Yo) + Xo
    27663066            float dX = xVec->data.F32[1] - xVec->data.F32[0];
    27673067            float dY = yVec->data.F32[1] - yVec->data.F32[0];
    2768             if (dY == 0.0) {
     3068            if (dY == 0.0)
     3069            {
    27693070                tmpFloat = xVec->data.F32[0];
    2770             } else {
     3071            }
     3072            else
     3073            {
    27713074                tmpFloat = (yVal - yVec->data.F32[0]) * (dX / dY) + xVec->data.F32[0];
    27723075            }
    2773         } else if (binNum == (xVec->n - 1)) {
     3076        }
     3077        else if (binNum == (xVec->n - 1))
     3078        {
    27743079            // We have two points only at the end of the vectors x and y.
    27753080            // X = (dX/dY)(Y - Yo) + Xo
    2776             float dX = xVec->data.F32[binNum] - xVec->data.F32[binNum-1];
    2777             float dY = yVec->data.F32[binNum] - yVec->data.F32[binNum-1];
    2778             if (dY == 0.0) {
    2779                 tmpFloat = xVec->data.F32[binNum-1];
    2780             } else {
    2781                 tmpFloat = (yVal - yVec->data.F32[binNum-1]) * (dX / dY) + xVec->data.F32[binNum-1];
     3081            float dX = xVec->data.F32[binNum] - xVec->data.F32[binNum - 1];
     3082            float dY = yVec->data.F32[binNum] - yVec->data.F32[binNum - 1];
     3083            if (dY == 0.0)
     3084            {
     3085                tmpFloat = xVec->data.F32[binNum - 1];
     3086            }
     3087            else
     3088            {
     3089                tmpFloat = (yVal - yVec->data.F32[binNum - 1]) * (dX / dY) + xVec->data.F32[binNum - 1];
    27823090            }
    27833091        }
     
    27893097
    27903098    return tmpFloat;
    2791 # endif
     3099#endif
    27923100}
Note: See TracChangeset for help on using the changeset viewer.