IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 27, 2004, 2:17:33 PM (22 years ago)
Author:
gusciora
Message:

I made changes to reflect the new SDRS.

File:
1 edited

Legend:

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

    r729 r796  
    1515
    1616#include "float.h"
    17 #include <math.h>
    1817#define ROBUST_SIZE_THRESHOLD 10000   // Vectors that are large than this
    1918// will use robust statistical methods.
     
    2524#define CLIPPED_SIGMA_LB 1.0
    2625#define CLIPPED_SIGMA_UB 10.0
    27 
     26#define true 1
     27#define false 0
     28#define MYMAXFLOAT 1e99
    2829/******************************************************************************
    2930    psStatsAlloc(): This routine must create a new psStats data structure.
     
    3940    newStruct->sampleUQ = NAN;
    4041    newStruct->sampleLQ = NAN;
     42    newStruct->sampleLimit = NAN;
    4143    newStruct->robustMean = NAN;
    42     newStruct->robustMeanNvalues = -1;
    4344    newStruct->robustMedian = NAN;
    44     newStruct->robustMedianNvalues = -1;
    4545    newStruct->robustMode = NAN;
    46     newStruct->robustModeNvalues = -1;
    4746    newStruct->robustStdev = NAN;
    4847    newStruct->robustUQ = NAN;
    4948    newStruct->robustLQ = NAN;
     49    newStruct->robustN50 = NAN;
     50    newStruct->robustNfit = NAN;
    5051    newStruct->clippedMean = NAN;
    51     newStruct->clippedMeanNvalues = -1;
    5252    newStruct->clippedStdev = NAN;
    5353    newStruct->clipSigma = NAN;
     
    5555    newStruct->min = NAN;
    5656    newStruct->max = NAN;
    57     newStruct->nValues = -1;
     57    newStruct->binsize = NAN;
    5858    newStruct->options = options;
    5959
     
    7474psHistogram *psHistogramAlloc(float lower,
    7575                              float upper,
    76                               float size )
    77 {
     76                              int n)
     77{
     78    int i = 0;
    7879    psHistogram *newHist = NULL;
    79     int numBins = 0;
    80 
    81 
    82     numBins = 1 + ((upper - lower) / size);
     80    float binSize = 0.0;
     81
    8382    newHist = (psHistogram *) psAlloc(sizeof(psHistogram));
    84     newHist->lower = psVectorAlloc(PS_TYPE_FLOAT, numBins);
    85     newHist->upper = psVectorAlloc(PS_TYPE_FLOAT, numBins);
    86     newHist->nums =  psVectorAlloc(PS_TYPE_INT32, numBins);
    87     newHist->minVal = lower;
    88     newHist->maxVal = upper;
     83    newHist->bounds = psVectorAlloc(PS_TYPE_FLOAT, n+1);
     84    binSize = (upper - lower) / (float) n;
     85    for (i=0;i<n+1;i++) {
     86        newHist->bounds->vec.f[i] = lower + (binSize * (float) i);
     87    }
     88    newHist->nums =  psVectorAlloc(PS_TYPE_INT32, n);
    8989    newHist->minNum = 0;
    9090    newHist->maxNum = 0;
    91     newHist->numBins = numBins;
     91    newHist->uniform = true;
     92
    9293    return(newHist);
    9394}
    9495
    95 psHistogram *psHistogramAllocGeneric(const psVector *restrict lower,
    96                                      const psVector *restrict upper,
    97                                      float minVal,
    98                                      float maxVal)
     96
     97psHistogram *psHistogramAllocGeneric(const psVector *restrict bounds)
    9998{
    10099    psHistogram *newHist = NULL;
    101     int numBins = 0;
    102100    int i;
    103101
    104     if (lower->n != upper->n) {
    105         psError(__func__, "There is a different number of upper/lower values");
    106     }
    107     numBins = lower->n;
    108102    newHist = (psHistogram *) psAlloc(sizeof(psHistogram));
    109     newHist->lower = psVectorAlloc(PS_TYPE_FLOAT, numBins);
    110     newHist->upper = psVectorAlloc(PS_TYPE_FLOAT, numBins);
    111     for (i=0;i<numBins;i++) {
    112         newHist->lower->vec.f[i] = lower->vec.f[i];
    113         newHist->upper->vec.f[i] = upper->vec.f[i];
    114     }
    115     newHist->nums = psVectorAlloc(PS_TYPE_INT32, numBins);
    116     newHist->minVal = minVal;
    117     newHist->maxVal = maxVal;
     103    newHist->bounds = psVectorAlloc(PS_TYPE_FLOAT, bounds->n);
     104    for (i=0;i<bounds->n;i++) {
     105        newHist->bounds->vec.f[i] = bounds->vec.f[i];
     106    }
     107    newHist->nums = psVectorAlloc(PS_TYPE_INT32, (bounds->n)-1);
     108
    118109    newHist->minNum = 0;
    119110    newHist->maxNum = 0;
     111    newHist->uniform = false;
    120112
    121113    return(newHist);
     
    141133        myHist->maxNum
    142134 *****************************************************************************/
    143 psHistogram *psGetArrayHistogram(psHistogram *restrict myHist,
    144                                  const psVector *restrict myVector)
    145 {
    146     int i = 0;
     135psHistogram *psHistogramVector(psHistogram *out,
     136                               psVector *in,
     137                               psVector *mask,
     138                               int maskVal)
     139{
     140    int i = 0;
     141    int j = 0;
    147142    float binSize = 0.0;
    148143    int binNum = 0;
    149 
    150     binSize = (myHist->maxVal - myHist->minVal) / (float) myHist->nums->n;
    151     for (i=0;i<myVector->n;i++) {
    152         if (myVector->vec.f[i] < myHist->minVal) {
    153             myHist->minNum++;
    154         } else if (myVector->vec.f[i] > myHist->maxVal) {
    155             myHist->maxNum++;
    156         } else {
    157             binNum = (int) ((myVector->vec.f[i] - myHist->minVal) / binSize);
    158             if ((myVector->vec.f[i] >= myHist->lower->vec.f[i]) &&
    159                     (myVector->vec.f[i] <= myHist->upper->vec.f[i])) {
    160                 myHist->nums->vec.i32[i]++;
     144    int numBins = 0;
     145
     146    numBins = out->nums->n;
     147    for (i=0;i<in->n;i++) {
     148        // Check if this pixel is masked, and if so, skip it.
     149        if (!(mask->vec.i32[i] & maskVal)) {
     150            // Check if this pixel is below the minimum value, and if so
     151            // count it, then skip it.
     152            if (in->vec.f[i] < out->bounds->vec.f[0]) {
     153                out->minNum++;
     154
     155                // Check if this pixel is above the maximum value, and if so
     156                // count it, then skip it.
     157            } else if (in->vec.f[i] > out->bounds->vec.f[numBins]) {
     158                out->maxNum++;
    161159            } else {
    162                 psError(__func__, "data value was not within the bounds of the bin it should habe been in.");
    163             }
    164         }
    165     }
    166     return(myHist);
     160                // If this is a uniform histogram, determining the correct
     161                // number is trivial.
     162                if (out->uniform == true) {
     163                    binSize = out->bounds->vec.f[1] - out->bounds->vec.f[0];
     164
     165                    binNum = (int) ((in->vec.f[i] - out->bounds->vec.f[0]) /
     166                                    binSize);
     167                    (out->nums->vec.i32[binNum])++;
     168                    // If this is a non-uniform histogram, determining the correct
     169                    // bin number requires a bit more work.
     170                } else {
     171                    // GUS: This is slow.  Put a smarter algorithm here to
     172                    // find the correct bin number (bin search, probably)
     173                    for (j=0;j<(out->bounds->n)-1;j++) {
     174                        if ((out->bounds->vec.i32[j] <= in->vec.f[i]) &&
     175                                (in->vec.f[i] <= out->bounds->vec.i32[j+1])) {
     176                            (out->nums->vec.i32[j])++;
     177                        }
     178                    }
     179                }
     180            }
     181        }
     182    }
     183    return(out);
    167184}
    168185
     
    184201
    185202/******************************************************************************
     203 ******************************************************************************
     204 ******************************************************************************
    186205    MISC STATISTICAL FUNCTIONS
    187  *****************************************************************************/
    188 void p_psArraySampleMean(const psVector *restrict myVector,
    189                          const psVector *restrict maskVector,
    190                          unsigned int maskVal,
    191                          psStats *newStruct)
     206 ******************************************************************************
     207 ******************************************************************************
     208 *****************************************************************************/
     209void p_psVectorSampleMean(const psVector *restrict myVector,
     210                          const psVector *restrict maskVector,
     211                          unsigned int maskVal,
     212                          psStats *stats)
    192213{
    193214    int i = 0;
    194215    float mean = 0.0;
    195216    int count = 0;
    196 
    197     if (maskVector != NULL) {
    198         for (i=0;i<myVector->n;i++) {
    199             if (!(maskVal & maskVector->vec.ui8[i])) {
     217    float rangeMin = 0.0;
     218    float rangeMax = 0.0;
     219
     220    if (stats->options & PS_STAT_USE_RANGE) {
     221        rangeMin = stats->min;
     222        rangeMax = stats->max;
     223        if (maskVector != NULL) {
     224            for (i=0;i<myVector->n;i++) {
     225                if (!(maskVal & maskVector->vec.ui8[i]) &&
     226                        (rangeMin <= myVector->vec.f[i]) &&
     227                        (myVector->vec.f[i] <= rangeMax)) {
     228                    mean+= myVector->vec.f[i];
     229                    count++;
     230                }
     231            }
     232            mean/= (float) count;
     233        } else {
     234            for (i=0;i<myVector->n;i++) {
     235                if ((rangeMin <= myVector->vec.f[i]) &&
     236                        (myVector->vec.f[i] <= rangeMax)) {
     237                    mean+= myVector->vec.f[i];
     238                    count++;
     239                }
     240            }
     241            mean/= (float) count;
     242        }
     243    } else {
     244        if (maskVector != NULL) {
     245            for (i=0;i<myVector->n;i++) {
     246                if (!(maskVal & maskVector->vec.ui8[i])) {
     247                    mean+= myVector->vec.f[i];
     248                    count++;
     249                }
     250            }
     251            mean/= (float) count;
     252        } else {
     253            for (i=0;i<myVector->n;i++) {
    200254                mean+= myVector->vec.f[i];
    201                 count++;
    202             }
    203         }
    204         mean/= (float) count;
     255            }
     256            mean/= (float) myVector->n;
     257        }
     258    }
     259
     260    stats->sampleMean = mean;
     261}
     262
     263void p_psVectorMax(const psVector *restrict myVector,
     264                   const psVector *restrict maskVector,
     265                   unsigned int maskVal,
     266                   psStats *stats)
     267{
     268    int i = 0;
     269    float max = -MYMAXFLOAT;
     270    float rangeMin = 0.0;
     271    float rangeMax = 0.0;
     272
     273    if (stats->options & PS_STAT_USE_RANGE) {
     274        rangeMin = stats->min;
     275        rangeMax = stats->max;
     276        if (maskVector != NULL) {
     277            for (i=0;i<myVector->n;i++) {
     278                if (!(maskVal & maskVector->vec.ui8[i])) {
     279                    if ((myVector->vec.f[i] > max) &&
     280                            (rangeMin <= myVector->vec.f[i]) &&
     281                            (myVector->vec.f[i] <= rangeMax)) {
     282                        max = myVector->vec.f[i];
     283                    }
     284                }
     285            }
     286        } else {
     287            for (i=0;i<myVector->n;i++) {
     288                if ((myVector->vec.f[i] > max) &&
     289                        (rangeMin <= myVector->vec.f[i]) &&
     290                        (myVector->vec.f[i] <= rangeMax)) {
     291                    max = myVector->vec.f[i];
     292                }
     293            }
     294        }
    205295    } else {
    206         for (i=0;i<myVector->n;i++) {
    207             mean+= myVector->vec.f[i];
    208         }
    209         mean/= (float) myVector->n;
    210     }
    211     newStruct->sampleMean = mean;
    212 }
    213 
    214 void p_psArrayMax(const psVector *restrict myVector,
    215                   const psVector *restrict maskVector,
    216                   unsigned int maskVal,
    217                   psStats *newStruct)
    218 {
    219     int i = 0;
    220     float max = -1e99;
    221 
    222     if (maskVector != NULL) {
    223         for (i=0;i<myVector->n;i++) {
    224             if (!(maskVal & maskVector->vec.ui8[i])) {
     296        if (maskVector != NULL) {
     297            for (i=0;i<myVector->n;i++) {
     298                if (!(maskVal & maskVector->vec.ui8[i])) {
     299                    if (myVector->vec.f[i] > max) {
     300                        max = myVector->vec.f[i];
     301                    }
     302                }
     303            }
     304        } else {
     305            for (i=0;i<myVector->n;i++) {
    225306                if (myVector->vec.f[i] > max) {
    226307                    max = myVector->vec.f[i];
     
    228309            }
    229310        }
     311    }
     312
     313    stats->max = max;
     314}
     315
     316void p_psVectorMin(const psVector *restrict myVector,
     317                   const psVector *restrict maskVector,
     318                   unsigned int maskVal,
     319                   psStats *stats)
     320{
     321    int i = 0;
     322    float min = MYMAXFLOAT;
     323    float rangeMin = 0.0;
     324    float rangeMax = 0.0;
     325
     326    if (stats->options & PS_STAT_USE_RANGE) {
     327        rangeMin = stats->min;
     328        rangeMax = stats->max;
     329        if (maskVector != NULL) {
     330            for (i=0;i<myVector->n;i++) {
     331                if (!(maskVal & maskVector->vec.ui8[i])) {
     332                    if ((myVector->vec.f[i] < min) &&
     333                            (rangeMin <= myVector->vec.f[i]) &&
     334                            (myVector->vec.f[i] <= rangeMax)) {
     335                        min = myVector->vec.f[i];
     336                    }
     337                }
     338            }
     339        } else {
     340            for (i=0;i<myVector->n;i++) {
     341                if ((myVector->vec.f[i] < min) &&
     342                        (rangeMin <= myVector->vec.f[i]) &&
     343                        (myVector->vec.f[i] <= rangeMax)) {
     344                    min = myVector->vec.f[i];
     345                }
     346            }
     347        }
    230348    } else {
    231         for (i=0;i<myVector->n;i++) {
    232             if (myVector->vec.f[i] > max) {
    233                 max = myVector->vec.f[i];
    234             }
    235         }
    236     }
    237     newStruct->max = max;
    238 }
    239 
    240 void p_psArrayMin(const psVector *restrict myVector, /* FLOATS */
    241                   const psVector *restrict maskVector, /* INTS */
    242                   unsigned int maskVal,
    243                   psStats *newStruct)
    244 {
    245     int i = 0;
    246     float min = 1e99;
    247 
    248     if (maskVector != NULL) {
    249         for (i=0;i<myVector->n;i++) {
    250             if (!(maskVal & maskVector->vec.ui8[i])) {
     349        if (maskVector != NULL) {
     350            for (i=0;i<myVector->n;i++) {
     351                if (!(maskVal & maskVector->vec.ui8[i])) {
     352                    if (myVector->vec.f[i] < min) {
     353                        min = myVector->vec.f[i];
     354                    }
     355                }
     356            }
     357        } else {
     358            for (i=0;i<myVector->n;i++) {
    251359                if (myVector->vec.f[i] < min) {
    252360                    min = myVector->vec.f[i];
     
    254362            }
    255363        }
    256     } else {
    257         for (i=0;i<myVector->n;i++) {
    258             if (myVector->vec.f[i] < min) {
    259                 min = myVector->vec.f[i];
    260             }
    261         }
    262     }
    263     newStruct->min = min;
     364    }
     365
     366    stats->min = min;
    264367}
    265368
    266369/******************************************************************************
    267  
    268  *****************************************************************************/
    269 void p_psArrayNValues(const psVector *restrict myVector,
     370 This routine calculates the number of non-masked pixels in the vector.
     371 *****************************************************************************/
     372int p_psVectorNValues(const psVector *restrict myVector,
    270373                      const psVector *restrict maskVector,
    271374                      unsigned int maskVal,
     
    284387        numData = myVector->n;
    285388    }
    286     newStruct->nValues = numData;
    287 }
    288 
    289 
    290 
    291 void p_psArraySampleMedian(const psVector *restrict myVector,
    292                            const psVector *restrict maskVector,
    293                            unsigned int maskVal,
    294                            psStats *newStruct)
     389    return(numData);
     390}
     391
     392
     393
     394void p_psVectorSampleMedian(const psVector *restrict myVector,
     395                            const psVector *restrict maskVector,
     396                            unsigned int maskVal,
     397                            psStats *newStruct)
    295398{
    296399    psVector *unsortedVector = NULL;
     
    299402    int i = 0;
    300403    float median = 0.0;
    301 
    302     if (-1 == newStruct->nValues) {
    303         p_psArrayNValues(myVector, maskVector, maskVal, newStruct);
    304     }
    305     unsortedVector = psVectorAlloc(PS_TYPE_FLOAT, newStruct->nValues);
     404    int nValues = 0;
     405
     406    nValues = p_psVectorNValues(myVector, maskVector, maskVal, newStruct);
     407    unsortedVector = psVectorAlloc(PS_TYPE_FLOAT, nValues);
    306408    unsortedVector->n = unsortedVector->nalloc;
    307     sortedVector   = psVectorAlloc(PS_TYPE_FLOAT, newStruct->nValues);
     409    sortedVector   = psVectorAlloc(PS_TYPE_FLOAT, nValues);
    308410    sortedVector->n = sortedVector->nalloc;
    309411
     
    320422    }
    321423
    322     if (0 == (newStruct->nValues % 2)) {
    323         median = 0.5 * (sortedVector->vec.f[(newStruct->nValues/2)-1] +
    324                         sortedVector->vec.f[newStruct->nValues/2]);
     424    if (0 == (nValues % 2)) {
     425        median = 0.5 * (sortedVector->vec.f[(nValues/2)-1] +
     426                        sortedVector->vec.f[nValues/2]);
    325427    } else {
    326         median = sortedVector->vec.f[newStruct->nValues/2];
     428        median = sortedVector->vec.f[nValues/2];
    327429    }
    328430
     
    332434}
    333435
    334 void p_psArraysmoothHistGaussian(psHistogram *robustHistogram,
    335                                  float sigma)
     436void p_psVectorsmoothHistGaussian(psHistogram *robustHistogram,
     437                                  float sigma)
    336438{
    337439    int i = 0;
     
    365467    }
    366468
    367     for(i=0;i<robustHistogram->numBins;i++) {
     469    for(i=0;i<robustHistogram->nums->n;i++) {
    368470        for (j=-GAUSS_WIDTH;j<=+GAUSS_WIDTH;j++) {
    369             if (((j+i) >= 0) && ((j+i) < robustHistogram->numBins)) {
     471            if (((j+i) >= 0) && ((j+i) < robustHistogram->nums->n)) {
    370472                robustHistogram->nums->vec.i32[j+i]+=
    371473                    (gaussianCoefs[j+GAUSS_WIDTH] *
     
    377479
    378480/******************************************************************************
    379     p_psArraySampleQuartiles()
     481    p_psVectorSampleQuartiles()
    380482 This procedure calculates the upper and/or lower quartiles of the
    381483 data set.  It is assumed that the data set is small enough that we
    382484 can sort all the data points and calculate the quartiles exactly.
    383485 *****************************************************************************/
    384 void p_psArraySampleQuartiles(const psVector *restrict myVector,
    385                               const psVector *restrict maskVector,
    386                               unsigned int maskVal,
    387                               psStats *newStruct)
     486void p_psVectorSampleQuartiles(const psVector *restrict myVector,
     487                               const psVector *restrict maskVector,
     488                               unsigned int maskVal,
     489                               psStats *newStruct)
    388490{
    389491    psVector *unsortedVector = NULL;
     
    392494    int ind = 0;
    393495    int i = 0;
     496    int nValues = 0;
    394497
    395498    // return is we have already calculated both quartile points.
     
    399502    }
    400503
    401     if (-1 == newStruct->nValues) {
    402         p_psArrayNValues(myVector, maskVector, maskVal, newStruct);
    403     }
    404 
    405 
    406     unsortedVector = psVectorAlloc(PS_TYPE_FLOAT, newStruct->nValues);
    407     sortedVector   = psVectorAlloc(PS_TYPE_FLOAT, newStruct->nValues);
     504    nValues = p_psVectorNValues(myVector, maskVector, maskVal, newStruct);
     505
     506    unsortedVector = psVectorAlloc(PS_TYPE_FLOAT, nValues);
     507    sortedVector   = psVectorAlloc(PS_TYPE_FLOAT, nValues);
    408508
    409509    count = 0;
     
    419519    }
    420520
    421     if (newStruct->options & PS_STAT_SAMPLE_LQ) {
    422         ind = 3 * (newStruct->nValues / 4);
    423         newStruct->sampleUQ = sortedVector->vec.f[ind];
    424     }
    425 
    426     if (newStruct->options & PS_STAT_SAMPLE_UQ) {
    427         ind = (newStruct->nValues / 4);
    428         newStruct->sampleLQ = sortedVector->vec.f[ind];
    429     }
     521    ind = 3 * (nValues / 4);
     522    newStruct->sampleUQ = sortedVector->vec.f[ind];
     523    ind = (nValues / 4);
     524    newStruct->sampleLQ = sortedVector->vec.f[ind];
    430525
    431526    psVectorFree(unsortedVector);
     
    435530
    436531/******************************************************************************
    437     p_psArrayRobustStats(): this procedure calcualtes a variety of robust
     532    p_psVectorRobustStats(): this procedure calcualtes a variety of robust
    438533    stat measures:
    439534 PS_STAT_ROBUST_MEAN
    440         PS_STAT_ROBUST_MEAN_NVALUES
    441535        PS_STAT_ROBUST_MEDIAN
    442         PS_STAT_ROBUST_MEDIAN_NVALUES
    443536        PS_STAT_ROBUST_MODE
    444         PS_STAT_ROBUST_MODE_NVALUES
    445537        PS_STAT_ROBUST_STDEV
    446538    I have included all that computation in a single function, as opposed to
     
    452544    processing would be duplicated.
    453545 *****************************************************************************/
    454 void p_psArrayRobustStats(const psVector *restrict myVector,
    455                           const psVector *restrict maskVector,
    456                           unsigned int maskVal,
    457                           psStats *newStruct)
     546void p_psVectorRobustStats(const psVector *restrict myVector,
     547                           const psVector *restrict maskVector,
     548                           unsigned int maskVal,
     549                           psStats *newStruct)
    458550{
    459551    psHistogram *robustHistogram = NULL;
     
    474566
    475567    if (0.0 == newStruct->sampleUQ) {
    476         newStruct->options = newStruct->options | PS_STAT_SAMPLE_UQ;
    477         p_psArraySampleQuartiles(myVector,
    478                                  maskVector,
    479                                  maskVal,
    480                                  newStruct);
     568        // GUS: fix this
     569        //        newStruct->options = newStruct->options | PS_STAT_SAMPLE_UQ;
     570        p_psVectorSampleQuartiles(myVector,
     571                                  maskVector,
     572                                  maskVal,
     573                                  newStruct);
    481574    }
    482575
    483576    if (isnan(newStruct->sampleLQ)) {
    484         newStruct->options = newStruct->options | PS_STAT_SAMPLE_LQ;
    485         p_psArraySampleQuartiles(myVector,
    486                                  maskVector,
    487                                  maskVal,
    488                                  newStruct);
     577        // GUS: fix this
     578        //        newStruct->options = newStruct->options | PS_STAT_SAMPLE_LQ;
     579        p_psVectorSampleQuartiles(myVector,
     580                                  maskVector,
     581                                  maskVal,
     582                                  newStruct);
    489583    }
    490584
     
    495589    // Detemine minimum and maximum values in the data vector.
    496590    if (isnan(newStruct->min)) {
    497         p_psArrayMin(myVector, maskVector, maskVal, newStruct);
     591        p_psVectorMin(myVector, maskVector, maskVal, newStruct);
    498592    }
    499593    if (isnan(newStruct->max)) {
    500         p_psArrayMax(myVector, maskVector, maskVal, newStruct);
     594        p_psVectorMax(myVector, maskVector, maskVal, newStruct);
    501595    }
    502596
     
    506600                                       binSize);
    507601    // Populate the histogram arrat.
    508     robustHistogram = psGetArrayHistogram(robustHistogram, myVector);
     602    // GUS: fix this
     603    //    robustHistogram = psHistogramVector(robustHistogram, myVector);
     604    //
    509605
    510606    // Smooth the histogram.
    511     p_psArraysmoothHistGaussian(robustHistogram, sigmaE/4.0f);
     607    p_psVectorsmoothHistGaussian(robustHistogram, sigmaE/4.0f);
    512608
    513609    LQBinNum = -1;
    514610    UQBinNum = -1;
    515     for (i=0;i<robustHistogram->numBins;i++) {
     611    for (i=0;i<robustHistogram->nums->n;i++) {
    516612        if ((robustHistogram->nums->vec.i32[i] <= newStruct->sampleLQ) &&
    517613                (newStruct->sampleLQ <= robustHistogram->nums->vec.i32[i])) {
     
    546642        newStruct->robustMean = 0.0;
    547643    }
    548     if  (newStruct->options & PS_STAT_ROBUST_MEAN_NVALUES) {
    549         newStruct->robustMeanNvalues = 0.0;
    550     }
     644
    551645    if  (newStruct->options & PS_STAT_ROBUST_MEDIAN) {
    552646        newStruct->robustMedian = 0.0;
    553647    }
    554     if  (newStruct->options & PS_STAT_ROBUST_MEDIAN_NVALUES) {
    555         newStruct->robustMedianNvalues = 0.0;
    556     }
    557648    if  (newStruct->options & PS_STAT_ROBUST_MODE) {
    558649        newStruct->robustMode = maxBinNum;
    559650    }
    560     if  (newStruct->options & PS_STAT_ROBUST_MODE_NVALUES) {
    561         newStruct->robustModeNvalues = 0.0;
    562     }
    563651    if  (newStruct->options & PS_STAT_ROBUST_STDEV) {
    564652        newStruct->robustStdev = 0.0;
    565653    }
    566     if  (newStruct->options & PS_STAT_ROBUST_UQ) {
     654    if  (newStruct->options & PS_STAT_ROBUST_QUARTILE) {
    567655        newStruct->robustUQ = 0.0;
    568     }
    569     if  (newStruct->options & PS_STAT_ROBUST_LQ) {
    570656        newStruct->robustLQ = 0.0;
    571657    }
    572658}
    573659
    574 void p_psArraySampleStdev(const psVector *restrict myVector,
    575                           const psVector *restrict maskVector,
    576                           unsigned int maskVal,
    577                           psStats *newStruct)
     660/*****************************************************************************
     661    NOTE: This function assumes that p_psVectorMean() has already been called
     662    and the correct value is stored in stats->sampleMean.
     663 *****************************************************************************/
     664void p_psVectorSampleStdev(const psVector *restrict myVector,
     665                           const psVector *restrict maskVector,
     666                           unsigned int maskVal,
     667                           psStats *stats)
    578668{
    579669    int i            = 0;
     
    584674    float sumSquares = 0.0;
    585675    float sumDiffs = 0.0;
    586 
    587     if (0 != isnan(newStruct->sampleMean)) {
    588         p_psArraySampleMean(myVector, maskVector, maskVal, newStruct);
    589     }
    590     mean = newStruct->sampleMean;
    591 
    592     if (maskVector != NULL) {
    593         for (i=0;i<myVector->n;i++) {
    594             if (!(maskVal & maskVector->vec.ui8[i])) {
     676    float rangeMin = 0.0;
     677    float rangeMax = 0.0;
     678
     679    if (0 != isnan(stats->sampleMean)) {
     680        psAbort(__func__, "stats->sampleMean == NAN");
     681    }
     682    mean = stats->sampleMean;
     683
     684    if (stats->options & PS_STAT_USE_RANGE) {
     685        if (maskVector != NULL) {
     686            for (i=0;i<myVector->n;i++) {
     687                if (!(maskVal & maskVector->vec.ui8[i]) &&
     688                        (rangeMin <= myVector->vec.f[i]) &&
     689                        (myVector->vec.f[i] <= rangeMax)) {
     690                    diff = myVector->vec.f[i] - mean;
     691                    sumSquares+= (diff * diff);
     692                    sumDiffs+= diff;
     693                    countInt++;
     694                }
     695            }
     696        } else {
     697            for (i=0;i<myVector->n;i++) {
     698                if ((rangeMin <= myVector->vec.f[i]) &&
     699                        (myVector->vec.f[i] <= rangeMax)) {
     700                    diff = myVector->vec.f[i] - mean;
     701                    sumSquares+= (diff * diff);
     702                    sumDiffs+= diff;
     703                    countInt++;
     704                }
     705            }
     706            countInt = myVector->n;
     707        }
     708    } else {
     709        if (maskVector != NULL) {
     710            for (i=0;i<myVector->n;i++) {
     711                if (!(maskVal & maskVector->vec.ui8[i])) {
     712                    diff = myVector->vec.f[i] - mean;
     713                    sumSquares+= (diff * diff);
     714                    sumDiffs+= diff;
     715                    countInt++;
     716                }
     717            }
     718        } else {
     719            for (i=0;i<myVector->n;i++) {
    595720                diff = myVector->vec.f[i] - mean;
    596721                sumSquares+= (diff * diff);
    597722                sumDiffs+= diff;
    598723                countInt++;
    599 
    600             }
    601         }
    602     } else {
    603         for (i=0;i<myVector->n;i++) {
    604             diff = myVector->vec.f[i] - mean;
    605             sumSquares+= (diff * diff);
    606             sumDiffs+= diff;
    607             countInt++;
    608         }
    609         countInt = myVector->n;
     724            }
     725            countInt = myVector->n;
     726        }
    610727    }
    611728    countFloat = (float) countInt;
     
    613730    #ifdef DARWIN
    614731
    615     newStruct->sampleStdev = (float) sqrt( (sumSquares-(sumDiffs *
    616                                             sumDiffs/countFloat))/ (countFloat-1));
     732    stats->sampleStdev = (float) sqrt( (sumSquares-(sumDiffs *
     733                                        sumDiffs/countFloat))/ (countFloat-1));
    617734    #else
    618735
    619     newStruct->sampleStdev = sqrtf( (sumSquares-(sumDiffs *
    620                                      sumDiffs/countFloat))/ (countFloat-1));
     736    stats->sampleStdev = sqrtf( (sumSquares-(sumDiffs *
     737                                 sumDiffs/countFloat))/ (countFloat-1));
    621738    #endif
    622739}
    623740
    624 void p_psArrayClippedStats(const psVector *restrict myVector,
    625                            const psVector *restrict maskVector,
    626                            unsigned int maskVal,
    627                            psStats *newStruct)
     741void p_psVectorClippedStats(const psVector *restrict myVector,
     742                            const psVector *restrict maskVector,
     743                            unsigned int maskVal,
     744                            psStats *newStruct)
    628745{
    629746    int i = 0;
     
    653770
    654771    // 1. Compute the sample median.
    655     p_psArraySampleMedian(myVector, maskVector, maskVal, newStruct);
     772    p_psVectorSampleMedian(myVector, maskVector, maskVal, newStruct);
    656773
    657774    // 2. Compute the sample standard deviation.
    658     p_psArraySampleStdev(myVector, maskVector, maskVal, newStruct);
     775    p_psVectorSampleStdev(myVector, maskVector, maskVal, newStruct);
    659776
    660777    // 3. Use the sample median as the first estimator of the mean X.
     
    676793            // GUS: I should probably create a new struct here since the
    677794            // following calls will overwrite any old values in sampleMean.
    678             p_psArraySampleMedian(myVector, tmpMask, maskVal, newStruct);
    679             p_psArraySampleStdev(myVector, tmpMask, maskVal, newStruct);
     795            p_psVectorSampleMedian(myVector, tmpMask, maskVal, newStruct);
     796            p_psVectorSampleStdev(myVector, tmpMask, maskVal, newStruct);
    680797
    681798            // c) Use the new mean for x
     
    695812    if (newStruct->options & PS_STAT_CLIPPED_STDEV) {
    696813        newStruct->clippedStdev = clippedStdev;
    697     }
    698 
    699     if (newStruct->options & PS_STAT_CLIPPED_MEAN_NVALUES) {
    700         p_psArrayNValues(myVector, tmpMask, maskVal, newStruct);
    701     }
    702 
    703     if (newStruct->options & PS_STAT_CLIPPED_MEAN_NSIGMA) {
    704         // GUS: What to do here?
    705814    }
    706815
     
    716825 
    717826 *****************************************************************************/
    718 psStats *psArrayStats(const psVector *restrict myVector,
    719                       const psVector *restrict maskVector,
    720                       unsigned int maskVal,
    721                       psStats *stats)
    722 {
    723     psStats *newStruct = NULL;
    724 
    725     if (myVector == NULL) {
    726         psAbort(__func__,
    727                 "Input data array (myVector) was NULL.");
    728     }
    729 
    730     if (myVector->type.type != PS_TYPE_FLOAT) {
     827psStats *psVectorStats(psStats *stats,
     828                       psVector *in,
     829                       psVector *mask,
     830                       unsigned int maskVal)
     831{
     832    if (in == NULL) {
     833        psAbort(__func__, "Input data vector (in) was NULL.");
     834    }
     835
     836    if (in->type.type != PS_TYPE_FLOAT) {
    731837        psAbort(__func__,
    732838                "Only data type PS_TYPE_FLOAT is currently supported.");
    733839    }
    734     if (maskVector != NULL) {
    735         if (myVector->n != maskVector->n) {
     840    if (mask != NULL) {
     841        if (in->n != mask->n) {
    736842            psAbort(__func__,
    737843                    "Vector data and vector mask are of different sizes.");
    738844        }
    739         if (maskVector->type.type != PS_TYPE_UINT8) {
     845        if (mask->type.type != PS_TYPE_UINT8) {
    740846            psAbort(__func__,
    741847                    "Vector mask must be type PS_TYPE_UINT8");
    742848        }
    743849    }
    744     newStruct = psStatsAlloc(stats->options);
    745850
    746851    // ************************************************************************
    747852    if (stats->options & PS_STAT_SAMPLE_MEAN) {
    748         p_psArraySampleMean(myVector, maskVector, maskVal, newStruct);
     853        p_psVectorSampleMean(in, mask, maskVal, stats);
     854    }
     855
     856    // ************************************************************************
     857    if (stats->options & PS_STAT_SAMPLE_MEDIAN) {
     858        p_psVectorSampleMedian(in, mask, maskVal, stats);
     859    }
     860
     861    // ************************************************************************
     862    if (stats->options & PS_STAT_SAMPLE_STDEV) {
     863        p_psVectorSampleStdev(in, mask, maskVal, stats);
     864    }
     865
     866    // ************************************************************************
     867    if (stats->options & PS_STAT_SAMPLE_QUARTILE) {
     868        p_psVectorSampleQuartiles(in, mask, maskVal, stats);
     869    }
     870
     871    if ((stats->options & PS_STAT_ROBUST_MEAN) ||
     872            (stats->options & PS_STAT_ROBUST_MEDIAN) ||
     873            (stats->options & PS_STAT_ROBUST_MODE) ||
     874            (stats->options & PS_STAT_ROBUST_STDEV) ||
     875            (stats->options & PS_STAT_ROBUST_QUARTILE)) {
     876        p_psVectorRobustStats(in, mask, maskVal, stats);
     877    }
     878
     879    if ((stats->options & PS_STAT_CLIPPED_MEAN) ||
     880            (stats->options & PS_STAT_CLIPPED_STDEV)) {
     881        p_psVectorClippedStats(in, mask, maskVal, stats);
    749882    }
    750883
    751884    // ************************************************************************
    752885    if (stats->options & PS_STAT_MAX) {
    753         p_psArrayMax(myVector, maskVector, maskVal, newStruct);
     886        p_psVectorMax(in, mask, maskVal, stats);
    754887    }
    755888
    756889    // ************************************************************************
    757890    if (stats->options & PS_STAT_MIN) {
    758         p_psArrayMin(myVector, maskVector, maskVal, newStruct);
    759     }
    760 
    761     // ************************************************************************
    762     if (stats->options & PS_STAT_NVALUES) {
    763         p_psArrayNValues(myVector, maskVector, maskVal, newStruct);
    764     }
    765 
    766     // ************************************************************************
    767     if (stats->options & PS_STAT_SAMPLE_MEDIAN) {
    768         p_psArraySampleMedian(myVector, maskVector, maskVal, newStruct);
    769     }
    770 
    771     // ************************************************************************
    772     if (stats->options & PS_STAT_SAMPLE_STDEV) {
    773         p_psArraySampleStdev(myVector, maskVector, maskVal, newStruct);
    774     }
    775 
    776     // ************************************************************************
    777     if ((stats->options & PS_STAT_SAMPLE_UQ) ||
    778             (stats->options & PS_STAT_SAMPLE_LQ)) {
    779         p_psArraySampleQuartiles(myVector, maskVector, maskVal, newStruct);
    780     }
    781 
    782     if ((stats->options & PS_STAT_ROBUST_MEAN) ||
    783             (stats->options & PS_STAT_ROBUST_MEAN_NVALUES) ||
    784             (stats->options & PS_STAT_ROBUST_MEDIAN) ||
    785             (stats->options & PS_STAT_ROBUST_MEDIAN_NVALUES) ||
    786             (stats->options & PS_STAT_ROBUST_MODE) ||
    787             (stats->options & PS_STAT_ROBUST_MODE_NVALUES) ||
    788             (stats->options & PS_STAT_ROBUST_STDEV) ||
    789             (stats->options & PS_STAT_ROBUST_UQ) ||
    790             (stats->options & PS_STAT_ROBUST_LQ)) {
    791         p_psArrayClippedStats(myVector, maskVector, maskVal, newStruct);
    792     }
    793 
    794     if ((stats->options & PS_STAT_CLIPPED_MEAN) ||
    795             (stats->options & PS_STAT_CLIPPED_MEAN_NVALUES) ||
    796             (stats->options & PS_STAT_CLIPPED_MEAN_NSIGMA) ||
    797             (stats->options & PS_STAT_CLIPPED_STDEV)) {
    798         p_psArrayClippedStats(myVector, maskVector, maskVal, newStruct);
     891        p_psVectorMin(in, mask, maskVal, stats);
    799892    }
    800893
     
    803896    //        psAbort(__func__, "Unknown options 0x%x.\n", stats->options);
    804897
    805     return(newStruct);
    806 }
     898    return(stats);
     899}
Note: See TracChangeset for help on using the changeset viewer.