IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Nov 12, 2004, 9:08:17 AM (22 years ago)
Author:
gusciora
Message:

...

File:
1 edited

Legend:

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

    r2339 r2340  
    99 *  @author GLG, MHPCC
    1010 *
    11  *  @version $Revision: 1.90 $ $Name: not supported by cvs2svn $
    12  *  @date $Date: 2004-11-11 20:13:57 $
     11 *  @version $Revision: 1.91 $ $Name: not supported by cvs2svn $
     12 *  @date $Date: 2004-11-12 19:08:17 $
    1313 *
    1414 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    2929#include "psVector.h"
    3030#include "psTrace.h"
     31#include "psLogMsg.h"
    3132#include "psError.h"
    3233#include "psStats.h"
     
    142143/******************************************************************************
    143144p_psVectorSampleMean(myVector, maskVector, maskVal, stats): calculates the
    144 mean of the input vector.
    145 Inputs
    146     myVector
    147     maskVector
    148     maskVal
    149     stats
    150 Returns
    151     NULL
    152  
     145mean of the input vector.  If there was a problem with the mean calculation,
     146this routine sets stats->sampleMean to NAN.
    153147 *****************************************************************************/
    154148void p_psVectorSampleMean(const psVector* restrict myVector,
     
    220214/******************************************************************************
    221215p_psVectorSampleMax(myVector, maskVector, maskVal, stats): calculates the
    222 max of the input vector.
    223 Inputs
    224     myVector
    225     maskVector
    226     maskVal
    227     stats
    228 Returns
    229     NULL
     216max of the input vector.  If there was a problem with the max calculation,
     217this routine sets stats->max to NAN.
    230218 *****************************************************************************/
    231219void p_psVectorMax(const psVector* restrict myVector,
     
    289277/******************************************************************************
    290278p_psVectorSampleMin(myVector, maskVector, maskVal, stats): calculates the
    291 minimum of the input vector.
    292 Inputs
    293     myVector
    294     maskVector
    295     maskVal
    296     stats
    297 Returns
    298     NULL
     279minimum of the input vector.  If there was a problem with the min calculation,
     280this routine sets stats->min to NAN.
    299281 *****************************************************************************/
    300282void p_psVectorMin(const psVector* restrict myVector,
     
    357339
    358340/******************************************************************************
     341p_psVectorNValues(myVector, maskVector, maskVal, stats): This routine returns
     342"true" if the inputPsVector as 1 or more valid elements (a valid element is an
     343unmasked element within the specifined min/max range).  Otherwise, return
     344"false".
     345 *****************************************************************************/
     346bool p_psVectorCheckNonEmpty(const psVector* restrict myVector,
     347                             const psVector* restrict maskVector,
     348                             psU32 maskVal,
     349                             psStats* stats)
     350{
     351    PS_VECTOR_CHECK_NULL(myVector, -1);
     352    PS_PTR_CHECK_NULL(stats, -1);
     353    psS32 i = 0;                // Loop index variable
     354
     355    if (stats->options & PS_STAT_USE_RANGE) {
     356        if (maskVector != NULL) {
     357            for (i = 0; i < myVector->n; i++) {
     358                if (!(maskVal & maskVector->data.U8[i]) &&
     359                        (stats->min <= myVector->data.F32[i]) &&
     360                        (myVector->data.F32[i] <= stats->max)) {
     361                    return(true);
     362                }
     363            }
     364        } else {
     365            for (i = 0; i < myVector->n; i++) {
     366                if ((stats->min <= myVector->data.F32[i]) &&
     367                        (myVector->data.F32[i] <= stats->max)) {
     368                    return(true);
     369                }
     370            }
     371        }
     372    } else {
     373        if (maskVector != NULL) {
     374            for (i = 0; i < myVector->n; i++) {
     375                if (!(maskVal & maskVector->data.U8[i])) {
     376                    return(true);
     377                }
     378            }
     379        } else {
     380            if (myVector->n > 0) {
     381                return(true);
     382            }
     383        }
     384    }
     385    return(false);
     386}
     387
     388
     389/******************************************************************************
    359390p_psVectorNValues(myVector, maskVector, maskVal, stats): calculates the
    360391number of non-masked pixels in the vector that fall within the min/max
    361392range, if specified.
    362 Inputs
    363     myVector
    364     maskVector
    365     maskVal
    366     stats
    367 Returns
    368     int
    369393 *****************************************************************************/
    370394psS32 p_psVectorNValues(const psVector* restrict myVector,
     
    412436/******************************************************************************
    413437p_psVectorSampleMedian(myVector, maskVector, maskVal, stats): calculates the
    414 median of the input vector.
    415 Inputs
    416     myVector
    417     maskVector
    418     maskVal
    419     stats
    420 Returns
    421     NULL
     438median of the input vector.  Returns true on success (including if there were
     439no valid input vector elements).
    422440 *****************************************************************************/
    423441bool p_psVectorSampleMedian(const psVector* restrict myVector,
     
    429447    psVector* sortedVector = NULL;      // Temporary vector
    430448    psS32 i = 0;                        // Loop index variable
    431     psS32 count = 0;                    // # of points in this mean?
    432     psS32 nValues = 0;                  // # of points in vector
     449    psS32 count = 0;
     450    psS32 nValues = 0;
    433451
    434452    // Determine how many data points fit inside this min/max range
    435     // and are not masked, if the maskVector is not NULL>
     453    // and are not masked, if the maskVector is not NULL.
    436454    nValues = p_psVectorNValues(myVector, maskVector, maskVal, stats);
    437455
     
    439457    // sampleMedian to?  Should we generate an error?
    440458    if (nValues <= 0) {
    441         printf("WARNING: p_psVectorSampleMedian(): no valid elements in input vector.\n");
     459        psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleMedian(): no valid elements in input vector.\n");
    442460        return(true);
    443         stats->sampleMedian = 0;
     461        stats->sampleMedian = NAN;
    444462    }
    445463
     
    569587        } else if (x.data.F32 >= lastBound) {
    570588            jMin = robustHistogram->bounds->n - 1;
    571 
    572589        }
    573590
     
    575592        if ((x.data.F32 >= firstBound) && (x.data.F32 <= lastBound)) {
    576593            jMax = p_psVectorBinDisect(robustHistogram->bounds, &x);
     594            if (jMax < 0) {
     595                psError(PS_ERR_UNEXPECTED_NULL,
     596                        false,
     597                        PS_ERRORTEXT_psStats_STATS_VECTOR_BIN_DISECT_PROBLEM);
     598                return(NULL);
     599            }
    577600        } else if (x.data.F32 <= firstBound) {
    578601            jMax = 0;
    579602        } else if (x.data.F32 >= lastBound) {
    580603            jMax = robustHistogram->bounds->n - 1;
    581 
    582604        }
    583605
     
    606628    NULL
    607629 *****************************************************************************/
    608 void p_psVectorSampleQuartiles(const psVector* restrict myVector,
     630bool p_psVectorSampleQuartiles(const psVector* restrict myVector,
    609631                               const psVector* restrict maskVector,
    610632                               psU32 maskVal,
     
    616638    psS32 count = 0;              // # of points in this mean.
    617639    psS32 nValues = 0;            // # data points
    618     float rangeMin = 0.0;       // Exclude data below this
    619     float rangeMax = 0.0;       // Exclude date above this
    620640
    621641    // Determine how many data points fit inside this min/max range
    622     // and are not maxed, IF the maskVector is not NULL>
     642    // and are not maxed, IF the maskVector is not NULL.
    623643    nValues = p_psVectorNValues(myVector, maskVector, maskVal, stats);
    624644
    625645    // Allocate temporary vectors for the data.
    626646    unsortedVector = psVectorAlloc(nValues, PS_TYPE_F32);
    627     sortedVector = psVectorAlloc(nValues, PS_TYPE_F32);
    628647
    629648    // Determine if we must only use data points within a min/max range.
    630649    if (stats->options & PS_STAT_USE_RANGE) {
    631         rangeMin = stats->min;
    632         rangeMax = stats->max;
    633650        // Store all non-masked data points within the min/max range
    634651        // into the temporary vectors.
     
    637654            for (i = 0; i < myVector->n; i++) {
    638655                if (!(maskVal & maskVector->data.U8[i]) &&
    639                         (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
     656                        (stats->min <= myVector->data.F32[i]) && (myVector->data.F32[i] <= stats->max)) {
    640657                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
    641658                }
     
    643660        } else {
    644661            for (i = 0; i < myVector->n; i++) {
    645                 if ((rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
     662                if ((stats->min <= myVector->data.F32[i]) && (myVector->data.F32[i] <= stats->max)) {
    646663                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
    647664                }
     
    665682
    666683    // Sort the temporary vectors.
    667     psVectorSort(sortedVector, unsortedVector);
     684    sortedVector = psVectorSort(sortedVector, unsortedVector);
     685    if (sortedVector == NULL) {
     686        psError(PS_ERR_UNEXPECTED_NULL,
     687                false,
     688                PS_ERRORTEXT_psStats_STATS_SAMPLE_MEDIAN_SORT_PROBLEM);
     689        return(false);
     690    }
    668691
    669692    // Calculate the quartile points exactly.
     693    // XXX: We should probably do a bin-midpoint if the quartile is not an
     694    // integer.
    670695    stats->sampleUQ = sortedVector->data.F32[3 * (nValues / 4)];
    671696    stats->sampleLQ = sortedVector->data.F32[nValues / 4];
     
    674699    psFree(unsortedVector);
    675700    psFree(sortedVector);
     701    return(true);
    676702}
    677703
     
    700726    float sumSquares = 0.0;     // temporary variable
    701727    float sumDiffs = 0.0;       // temporary variable
    702     float rangeMin = 0.0;       // Exclude data below this
    703     float rangeMax = 0.0;       // Exclude date above this
    704728
    705729    // This procedure requires the mean.  If it has not been already
     
    708732        p_psVectorSampleMean(myVector, maskVector, maskVal, stats);
    709733    }
     734    // If the mean is NAN, then generate a warning and set the stdev to NAN.
     735    if (0 != isnan(stats->sampleMean)) {
     736        stats->sampleStdev = NAN;
     737        psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleStdev(): p_psVectorSampleMean() reported a NAN mean.\n");
     738        return;
     739    }
     740
    710741    mean = stats->sampleMean;
    711 
    712742    if (stats->options & PS_STAT_USE_RANGE) {
    713743        if (maskVector != NULL) {
    714744            for (i = 0; i < myVector->n; i++) {
    715745                if (!(maskVal & maskVector->data.U8[i]) &&
    716                         (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
     746                        (stats->min <= myVector->data.F32[i]) &&
     747                        (myVector->data.F32[i] <= stats->max)) {
    717748                    diff = myVector->data.F32[i] - mean;
    718749                    sumSquares += (diff * diff);
     
    723754        } else {
    724755            for (i = 0; i < myVector->n; i++) {
    725                 if ((rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
     756                if ((stats->min <= myVector->data.F32[i]) &&
     757                        (myVector->data.F32[i] <= stats->max)) {
    726758                    diff = myVector->data.F32[i] - mean;
    727759                    sumSquares += (diff * diff);
     
    752784        }
    753785    }
    754     if (countInt < 2) {
     786    if (countInt <= 1) {
    755787        stats->sampleStdev = NAN;
    756         // XXX PS WARNING
     788        psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleStdev(): no valid psVector elements.  Setting stats->sampleStdev = NAN.\n");
    757789    } else {
    758790        countFloat = (float)countInt;
    759791        #ifdef DARWIN
    760792
    761         stats->sampleStdev = (float)sqrt((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
     793        stats->sampleStdev = (float)sqrt((sumSquares -
     794                                          (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
    762795        #else
    763796
    764         stats->sampleStdev = sqrtf((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
     797        stats->sampleStdev = sqrtf((sumSquares -
     798                                    (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
    765799        #endif
    766800
     
    779813Returns
    780814    0 for success.
     815    -1: error
     816    -2: warning
    781817 *****************************************************************************/
    782818int p_psVectorClippedStats(const psVector* restrict myVector,
     
    794830
    795831    // Ensure that stats->clipIter is within the proper range.
    796     PS_INT_CHECK_RANGE(stats->clipIter,PS_CLIPPED_NUM_ITER_LB,PS_CLIPPED_NUM_ITER_UB,-1);
     832    PS_INT_CHECK_RANGE(stats->clipIter,
     833                       PS_CLIPPED_NUM_ITER_LB,
     834                       PS_CLIPPED_NUM_ITER_UB, -1);
    797835
    798836    // Ensure that stats->clipSigma is within the proper range.
    799     PS_INT_CHECK_RANGE(stats->clipSigma,PS_CLIPPED_SIGMA_LB,PS_CLIPPED_SIGMA_UB,-1);
     837    PS_INT_CHECK_RANGE(stats->clipSigma,
     838                       PS_CLIPPED_SIGMA_LB,
     839                       PS_CLIPPED_SIGMA_UB, -1);
    800840
    801841    // We allocate a temporary mask vector since during the iterative
     
    803843    // However, we do no want to modify the original mask vector.
    804844    tmpMask = psVectorAlloc(myVector->n, PS_TYPE_U8);
    805     tmpMask->n = myVector->n;
    806845
    807846    // If we were called with a mask vector, then initialize the temporary
     
    814853    // 1. Compute the sample median.
    815854    p_psVectorSampleMedian(myVector, maskVector, maskVal, stats);
     855    if (isnan(stats->sampleMean)) {
     856        psLogMsg(__func__, PS_LOG_WARN, "Call to p_psVectorSampleMean returned NAN\n");
     857        stats->clippedMean = NAN;
     858        stats->clippedStdev = NAN;
     859        return(-2);
     860    }
    816861
    817862    // 2. Compute the sample standard deviation.
    818863    p_psVectorSampleStdev(myVector, maskVector, maskVal, stats);
     864    if (isnan(stats->sampleStdev)) {
     865        psLogMsg(__func__, PS_LOG_WARN, "Call to p_psVectorSampleStdev returned NAN\n");
     866        stats->clippedMean = NAN;
     867        stats->clippedStdev = NAN;
     868        return(-2);
     869    }
    819870
    820871    // 3. Use the sample median as the first estimator of the mean X.
     
    836887                tmpMask->data.U8[i] = 0xff;
    837888            }
    838             // b) compute new mean and stdev
    839             p_psVectorSampleMedian(myVector, tmpMask, maskVal, stats);
    840             p_psVectorSampleStdev(myVector, tmpMask, maskVal, stats);
    841 
    842             // c) Use the new mean for x
     889        }
     890
     891        // b) compute new mean and stdev
     892        p_psVectorSampleMean(myVector, tmpMask, maskVal, stats);
     893        p_psVectorSampleStdev(myVector, tmpMask, maskVal, stats);
     894
     895        // If the new mean and stdev are not NAN, then we use them.
     896        // Otherwise, keep the old ones, and exit the loop.
     897        if (! (isnan(stats->sampleMean) || isnan(stats->sampleStdev))) {
    843898            clippedMean = stats->sampleMean;
    844 
    845             // d) Use the new stdev for stdev
    846899            clippedStdev = stats->sampleStdev;
    847         }
    848 
    849     }
     900
     901            // Exit loop
     902            i = stats->clipIter;
     903        }
     904    }
     905
    850906    stats->sampleMean = oldStanMean;
    851907    stats->sampleStdev = oldStanStdev;
     
    865921
    866922/*****************************************************************************
    867  *****************************************************************************/
    868 void p_psNormalizeVectorRangeF32(psVector* myData,
    869                                  float outLow,
    870                                  float outHigh)
    871 {
    872     float min = PS_MAX_F32;
    873     float max = -PS_MAX_F32;
    874     psS32 i = 0;
    875 
    876     for (i = 0; i < myData->n; i++) {
    877         if (myData->data.F32[i] < min) {
    878             min = myData->data.F32[i];
    879         }
    880         if (myData->data.F32[i] > max) {
    881             max = myData->data.F32[i];
    882         }
    883     }
    884 
    885     // Ensure that max!=min before we divide by (max-min)
    886     if (FLT_EPSILON < fabs(max - min)) {
    887         for (i = 0; i < myData->n; i++) {
    888             myData->data.F32[i] = outLow + (myData->data.F32[i] - min) *
    889                                   (outHigh - outLow) / (max - min);
    890         }
    891     } else {
    892         // XXX: PS_WARNING
    893         for (i = 0; i < myData->n; i++) {
    894             myData->data.F32[i] = outLow;
    895         }
    896     }
    897 
    898     for (i = 0; i < myData->n; i++) {
    899         myData->data.F32[i] = outLow + (myData->data.F32[i] - min) * (outHigh - outLow) / (max - min);
    900     }
    901 }
    902 void p_psNormalizeVectorRangeF64(psVector* myData,
    903                                  float outLow,
    904                                  float outHigh)
    905 {
    906     float min = PS_MAX_F32;
    907     float max = -PS_MAX_F32;
    908     psS32 i = 0;
    909 
    910     for (i = 0; i < myData->n; i++) {
    911         if (myData->data.F32[i] < min) {
    912             min = myData->data.F64[i];
    913         }
    914         if (myData->data.F32[i] > max) {
    915             max = myData->data.F64[i];
    916         }
    917     }
    918 
    919     // Ensure that max!=min before we divide by (max-min)
    920     if (FLT_EPSILON < fabs(max - min)) {
    921         for (i = 0; i < myData->n; i++) {
    922             myData->data.F64[i] = outLow + (myData->data.F64[i] - min) * (outHigh - outLow) / (max - min);
    923         }
    924     } else {
    925         // XXX: PS_WARNING
    926         for (i = 0; i < myData->n; i++) {
    927             myData->data.F64[i] = outLow;
    928         }
    929     }
    930 }
    931 
    932 /*****************************************************************************
    933 psNormalizeVectorRange(myData, low, high): this is a private function which
     923psNormalizeVectorRange##TYPE(myData, low, high): this is a private function which
    934924normalizes the elements of a vector to a range between low and high.
    935  *****************************************************************************/
    936 void psNormalizeVectorRange(psVector* myData,
    937                             float low,
    938                             float high)
    939 {
    940     if (myData->type.type == PS_TYPE_F32) {
    941         p_psNormalizeVectorRangeF32(myData, low, high);
    942     } else if (myData->type.type == PS_TYPE_F64) {
    943         p_psNormalizeVectorRangeF64(myData, low, high);
    944     } else {
    945         char* strType;
    946         PS_TYPE_NAME(strType,myData->type.type);
    947         psError(PS_ERR_BAD_PARAMETER_TYPE, true,
    948                 PS_ERRORTEXT_psStats_NOT_F32_F64,
    949                 strType);
    950     }
    951 }
     925 
     926XXX: Should we make the arguments psScalars?
     927 *****************************************************************************/
     928#define PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(TYPE) \
     929void p_psNormalizeVectorRange##TYPE(psVector* myData, \
     930                                    ps##TYPE outLow, \
     931                                    ps##TYPE outHigh) \
     932{ \
     933    ps##TYPE min = (ps##TYPE) PS_MAX_##TYPE; \
     934    ps##TYPE max = (ps##TYPE) -PS_MAX_##TYPE; \
     935    psS32 i = 0; \
     936    \
     937    for (i = 0; i < myData->n; i++) { \
     938        if (myData->data.TYPE[i] < min) { \
     939            min = myData->data.TYPE[i]; \
     940        } \
     941        if (myData->data.TYPE[i] > max) { \
     942            max = myData->data.TYPE[i]; \
     943        } \
     944    } \
     945    \
     946    /* Ensure that max!=min before we divide by (max-min) */ \
     947    if (max != min) { \
     948        for (i = 0; i < myData->n; i++) { \
     949            myData->data.TYPE[i] = (outLow + (myData->data.TYPE[i] - min) * \
     950                                    (outHigh - outLow) / (max - min)); \
     951        } \
     952    } else { \
     953        psLogMsg(__func__, PS_LOG_WARN, "WARNING: (max==min).  Setting all elements to min.\n");
     954        for (i = 0; i < myData->n; i++)
     955        {
     956            \
     957            myData->data.TYPE[i] = outLow;
     958            \
     959        } \
     960    } \
     961} \
     962
     963PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(U8)
     964PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(U16)
     965PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(U32)
     966PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(U64)
     967PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(S8)
     968PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(S16)
     969PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(S32)
     970PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(S64)
     971PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(F32)
     972PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(F64)
    952973
    953974/******************************************************************************
     
    969990                       float getThisValue)
    970991{
     992    PS_FLOAT_COMPARE(rangeLow, rangeHigh, NAN);
    971993    psS32 numIterations = 0;
    972994    float midpoint = 0.0;
     
    10051027 
    10061028XXX: After you fit the polynomial, solve for X analytically.
     1029 
     1030XXX: Check for errors in psLib routines that we call.
    10071031*****************************************************************************/
    10081032float fitQuadraticSearchForYThenReturnX(psVector *xVec,
     
    10851109Returns
    10861110    0 on success.
     1111 
     1112XXX: Check for errors in psLib routines that we call.
    10871113*****************************************************************************/
    10881114int p_psVectorRobustStats(const psVector* restrict myVector,
     
    12561282    psVector *y = psVectorAlloc(robustHistogramVector->n, PS_TYPE_F32);
    12571283
    1258     psNormalizeVectorRange(robustHistogramVector, 0.0, 1.0);
     1284    psNormalizeVectorRangeF32(robustHistogramVector, 0.0, 1.0);
    12591285    for (i=0;i<robustHistogramVector->n;i++) {
    12601286        myCoords->data[i] = (psPtr *) psVectorAlloc(2, PS_TYPE_F32);
     
    12821308    if (stats->options & PS_STAT_ROBUST_MEAN) {
    12831309        if (fabs((myParams->data.F32[0] - myMean)/myMean) > 0.1) {
    1284             printf("WARNING: the fitted Gaussian has more than 10% error for the mean.\n");
    1285             printf("Using the calculated mean (calc, fit) is (%f, %f)\n", myMean, myParams->data.F32[0]);
     1310            psLogMsg(__func__, PS_LOG_WARN,
     1311                     "WARNING: the fitted Gaussian has more than 10% error for the mean.\n");
     1312            psLogMsg(__func__, PS_LOG_WARN,
     1313                     "WARNING: Using the calculated mean (calc, fit) is (%f, %f)\n",
     1314                     myMean, myParams->data.F32[0]);
    12861315            stats->robustMean = myMean;
    12871316        } else {
     
    12961325    if (stats->options & PS_STAT_ROBUST_STDEV) {
    12971326        if (fabs((myParams->data.F32[1] - myStdev)/myStdev) > 0.1) {
    1298             printf("WARNING: the fitted Gaussian has more than 10% error for the stdev.\n");
    1299             printf("Using the calculated stdev (calc, fit) is (%f, %f)\n", myStdev, myParams->data.F32[1]);
     1327            psLogMsg(__func__, PS_LOG_WARN,
     1328                     "WARNING: the fitted Gaussian has more than 10% error for the mean.\n");
     1329            psLogMsg(__func__, PS_LOG_WARN,
     1330                     "WARNING: Using the calculated mean (calc, fit) is (%f, %f)\n",
     1331                     myMean, myParams->data.F32[0]);
    13001332            stats->robustStdev = myStdev;
    13011333        } else {
     
    16911723            psError(PS_ERR_UNKNOWN, false,
    16921724                    PS_ERRORTEXT_psStats_STATS_FAILED);
     1725            // XXX: Set to NAN
    16931726        }
    16941727    }
    16951728
    16961729    if ((stats->options & PS_STAT_CLIPPED_MEAN) || (stats->options & PS_STAT_CLIPPED_STDEV)) {
    1697         if (0 != p_psVectorClippedStats(inF32, mask, maskVal, stats)) {
     1730        if (-1 == p_psVectorClippedStats(inF32, mask, maskVal, stats)) {
    16981731            psError(PS_ERR_UNKNOWN, false,
    1699                     "Failed to calculate statistics for input psVector.");
     1732                    "Failed to calculate clipped statistics for input psVector.");
     1733            stats->clippedMean = NAN;
     1734            stats->clippedStdev = NAN;
     1735        } else if (-2 == p_psVectorClippedStats(inF32, mask, maskVal, stats)) {
     1736            psLogMsg(__func__, PS_LOG_WARN, "Failed to calculate clipped statistics for input psVector.");
     1737            stats->clippedMean = NAN;
     1738            stats->clippedStdev = NAN;
    17001739        }
    17011740    }
Note: See TracChangeset for help on using the changeset viewer.