IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jun 23, 2004, 10:45:16 AM (22 years ago)
Author:
gusciora
Message:

Coded recent ADD changes into the robust stats. Still waiting on
minimization routines to be coded.

File:
1 edited

Legend:

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

    r1057 r1071  
    847847
    848848/******************************************************************************
     849p_psVectorSampleStdev(myVector, maskVector, maskVal, stats): calculates the
     850stdev of the input vector.
     851Inputs
     852    myVector
     853    maskVector
     854    maskVal
     855    stats
     856Returns
     857    NULL
     858 
     859NOTE: the mean is always calculated exactly.  Robust means are never
     860calculated in this routine.
     861 *****************************************************************************/
     862void p_psVectorSampleStdev(const psVector *restrict myVector,
     863                           const psVector *restrict maskVector,
     864                           unsigned int maskVal,
     865                           psStats *stats)
     866{
     867    int i = 0;                                  // Loop index variable
     868    int countInt = 0;                           // # of data points being used
     869    float countFloat = 0.0;                     // # of data points being used
     870    float mean = 0.0;                           // The mean
     871    float diff = 0.0;                           // Used in calculating stdev
     872    float sumSquares = 0.0;                     // temporary variable
     873    float sumDiffs = 0.0;                       // temporary variable
     874    float rangeMin = 0.0;                       // Exclude data below this
     875    float rangeMax = 0.0;                       // Exclude date above this
     876
     877    // This procedure requires the mean.  If it has not been already
     878    // calculated, then call p_psVectorSampleMean()
     879    if (0 != isnan(stats->sampleMean)) {
     880        p_psVectorSampleMean(myVector, maskVector, maskVal, stats);
     881    }
     882    mean = stats->sampleMean;
     883
     884    if (stats->options & PS_STAT_USE_RANGE) {
     885        if (maskVector != NULL) {
     886            for (i=0;i<myVector->n;i++) {
     887                if (!(maskVal & maskVector->data.U8[i]) &&
     888                        (rangeMin <= myVector->data.F32[i]) &&
     889                        (myVector->data.F32[i] <= rangeMax)) {
     890                    diff = myVector->data.F32[i] - mean;
     891                    sumSquares+= (diff * diff);
     892                    sumDiffs+= diff;
     893                    countInt++;
     894                }
     895            }
     896        } else {
     897            for (i=0;i<myVector->n;i++) {
     898                if ((rangeMin <= myVector->data.F32[i]) &&
     899                        (myVector->data.F32[i] <= rangeMax)) {
     900                    diff = myVector->data.F32[i] - mean;
     901                    sumSquares+= (diff * diff);
     902                    sumDiffs+= diff;
     903                    countInt++;
     904                }
     905            }
     906            countInt = myVector->n;
     907        }
     908    } else {
     909        if (maskVector != NULL) {
     910            for (i=0;i<myVector->n;i++) {
     911                if (!(maskVal & maskVector->data.U8[i])) {
     912                    diff = myVector->data.F32[i] - mean;
     913                    sumSquares+= (diff * diff);
     914                    sumDiffs+= diff;
     915                    countInt++;
     916                }
     917            }
     918        } else {
     919            for (i=0;i<myVector->n;i++) {
     920                diff = myVector->data.F32[i] - mean;
     921                sumSquares+= (diff * diff);
     922                sumDiffs+= diff;
     923                countInt++;
     924            }
     925            countInt = myVector->n;
     926        }
     927    }
     928    countFloat = (float) countInt;
     929
     930    #ifdef DARWIN
     931
     932    stats->sampleStdev = (float) sqrt( (sumSquares-(sumDiffs *
     933                                        sumDiffs/countFloat))/ (countFloat-1));
     934    #else
     935
     936    stats->sampleStdev = sqrtf( (sumSquares-(sumDiffs *
     937                                 sumDiffs/countFloat))/ (countFloat-1));
     938    #endif
     939}
     940
     941/******************************************************************************
     942p_psVectorClippedStats(myVector, maskVector, maskVal, stats): calculates the
     943clipped stats (mean or stdev) of the input vector.
     944 
     945Inputs
     946    myVector
     947    maskVector
     948    maskVal
     949    stats
     950Returns
     951    NULL
     952 *****************************************************************************/
     953void p_psVectorClippedStats(const psVector *restrict myVector,
     954                            const psVector *restrict maskVector,
     955                            unsigned int maskVal,
     956                            psStats *stats)
     957{
     958    int i = 0;                                  // Loop index variable
     959    int j = 0;                                  // Loop index variable
     960    float clippedMean = 0.0;                    // self-explanatory
     961    float clippedStdev = 0.0;                   // self-explanatory
     962    float oldStanMean = 0.0;                    // Temporary variable
     963    float oldStanStdev = 0.0;                   // Temporary variable
     964    psVector *tmpMask = NULL;                   // Temporary vector
     965
     966    // Endure that stats->clipIter is within the proper range.
     967    if (!((CLIPPED_NUM_ITER_LB <= stats->clipIter ) &&
     968            (stats->clipIter <= CLIPPED_NUM_ITER_UB))) {
     969        psAbort(__func__, "Unallowed value for clipIter (%d).\n",
     970                stats->clipIter);
     971    }
     972
     973    // Endure that stats->clipSigma is within the proper range.
     974    if (!((CLIPPED_SIGMA_LB <= stats->clipSigma ) &&
     975            (stats->clipSigma <= CLIPPED_SIGMA_UB))) {
     976        psAbort(__func__, "Unallowed value for clipSigma (%f).\n",
     977                stats->clipSigma);
     978    }
     979
     980    // We allocate a temporary mask vector since during the iterative
     981    // steps that follow, we will be masking off additional data points.
     982    // However, we do no want to modify the original mask vector.
     983    tmpMask = psVectorAlloc(myVector->n, PS_TYPE_U8);
     984    tmpMask->n = myVector->n;
     985
     986    // If we were called with a mask vector, then initialize the temporary
     987    // mask vector with those values.
     988    if (maskVector != NULL) {
     989        for (i=0;i<tmpMask->n;i++) {
     990            tmpMask->data.U8[i] = maskVector->data.U8[i];
     991        }
     992    }
     993
     994    // 1. Compute the sample median.
     995    // NOTE: This seems odd.  Verify with IfA that we want to calculate the
     996    // median here, not the mean.
     997    p_psVectorSampleMedian(myVector, maskVector, maskVal, stats);
     998
     999    // 2. Compute the sample standard deviation.
     1000    p_psVectorSampleStdev(myVector, maskVector, maskVal, stats);
     1001
     1002    // 3. Use the sample median as the first estimator of the mean X.
     1003    clippedMean = stats->sampleMean;
     1004
     1005    // 4. Use the sample stdev as the first estimator of the mean stdev.
     1006    clippedStdev = stats->sampleStdev;
     1007
     1008    // Must save the old sampleMean and sampleStdev since the following code
     1009    // block overwrites them.
     1010    oldStanMean = stats->sampleMean;
     1011    oldStanStdev = stats->sampleStdev;
     1012
     1013    // 5. Repeat N times:
     1014    for (i=0;i<stats->clipIter;i++) {
     1015        for (j=0;j<myVector->n;j++) {
     1016            // a) Exclude all values x_i for which |x_i - x| > K * stdev
     1017            if (fabs(myVector->data.F32[j] - clippedMean) >
     1018                    (stats->clipSigma * clippedStdev)) {
     1019                tmpMask->data.U8[i] = 0xff;
     1020            }
     1021            // b) compute new mean and stdev
     1022            p_psVectorSampleMedian(myVector, tmpMask, maskVal, stats);
     1023            p_psVectorSampleStdev(myVector, tmpMask, maskVal, stats);
     1024
     1025            // c) Use the new mean for x
     1026            clippedMean = stats->sampleMean;
     1027
     1028            // d) Use the new stdev for stdev
     1029            clippedStdev = stats->sampleStdev;
     1030        }
     1031    }
     1032    stats->sampleMean = oldStanMean;
     1033    stats->sampleStdev= oldStanStdev;
     1034
     1035    // 7. The last calcuated value of x is the cliped mean.
     1036    if (stats->options & PS_STAT_CLIPPED_MEAN) {
     1037        stats->clippedMean = clippedMean;
     1038    }
     1039
     1040    // 8. The last calcuated value of stdev is the cliped stdev.
     1041    if (stats->options & PS_STAT_CLIPPED_STDEV) {
     1042        stats->clippedStdev = clippedStdev;
     1043    }
     1044
     1045    psVectorFree(tmpMask);
     1046}
     1047
     1048
     1049/******************************************************************************
    8491050p_psVectorRobustStats(myVector, maskVector, maskVal, stats): this procedure
    8501051calculates a variety of robust stat measures:
     
    8841085    float dL = 0.0;
    8851086    int numBins = 0;
     1087    psStats *tmpStats = psStatsAlloc(PS_STAT_CLIPPED_STDEV|PS_STAT_CLIPPED_MEAN);
    8861088
    8871089    // NOTE: The SDRS states that the sample quartiles must be used to
     
    8901092    // size of the data set.  We should consult with IfA to ensure that this
    8911093    // is really required.
    892 
    893     if (isnan(stats->sampleUQ) ||
     1094    /*
     1095        if (isnan(stats->sampleUQ) ||
    8941096            isnan(stats->sampleLQ)) {
    895         stats->options = stats->options | PS_STAT_SAMPLE_QUARTILE;
    896         p_psVectorSampleQuartiles(myVector,
    897                                   maskVector,
    898                                   maskVal,
    899                                   stats);
    900     }
    901 
     1097            stats->options = stats->options | PS_STAT_SAMPLE_QUARTILE;
     1098            p_psVectorSampleQuartiles(myVector,
     1099                                      maskVector,
     1100                                      maskVal,
     1101                                      stats);
     1102        }
     1103    */
    9021104    // Compute the initial bin size of the robust histogram.
    903     sigmaE = (stats->sampleUQ - stats->sampleLQ) / 1.34f;
    904     binSize = sigmaE / 10.0f;
     1105    p_psVectorClippedStats(myVector, maskVector, maskVal, tmpStats);
     1106    binSize = stats->clippedStdev / 10.0f;
     1107
     1108    // If stats->clippedStdev == 0.0, then all data elements have the same
     1109    // value.  Therefore, we can set the appropiate results and return.
     1110    if (fabs(binSize) <= FLT_EPSILON) {
     1111        if (stats->options & PS_STAT_ROBUST_MEAN) {
     1112            stats->robustMean = stats->clippedMean;
     1113        }
     1114        if  (stats->options & PS_STAT_ROBUST_MEDIAN) {
     1115            stats->robustMedian = stats->clippedMean;
     1116        }
     1117        if  (stats->options & PS_STAT_ROBUST_MODE) {
     1118            stats->robustMode = stats->clippedMean;
     1119        }
     1120        if  (stats->options & PS_STAT_ROBUST_STDEV) {
     1121            stats->robustStdev = 0.0;
     1122        }
     1123        if  (stats->options & PS_STAT_ROBUST_QUARTILE) {
     1124            stats->robustUQ = stats->clippedMean;
     1125            stats->robustLQ = stats->clippedMean;
     1126        }
     1127        psStatsFree(tmpStats);
     1128        psHistogramFree(robustHistogram);
     1129        return;
     1130    }
    9051131
    9061132    // Detemine minimum and maximum values in the data vector.
     
    9121138    }
    9131139
    914     // Create the histogram structure (yes, 2 is necessary, not 1).
     1140    // Create the histogram structure (yes, 2 is necessary, not 1).  Also,
     1141    // if we get here, we know that binSize != 0.0.
    9151142    numBins = 2 + (int) ((stats->max - stats->min) / binSize);
    9161143
     
    9731200    stats->robustNfit = 0.0;
    9741201    stats->robustN50 = 0.0;
     1202    psStatsFree(tmpStats);
    9751203    psHistogramFree(robustHistogram);
    976 }
    977 
    978 /******************************************************************************
    979 p_psVectorSampleStdev(myVector, maskVector, maskVal, stats): calculates the
    980 stdev of the input vector.
    981 Inputs
    982     myVector
    983     maskVector
    984     maskVal
    985     stats
    986 Returns
    987     NULL
    988  
    989 NOTE: the mean is always calculated exactly.  Robust means are never
    990 calculated in this routine.
    991  *****************************************************************************/
    992 void p_psVectorSampleStdev(const psVector *restrict myVector,
    993                            const psVector *restrict maskVector,
    994                            unsigned int maskVal,
    995                            psStats *stats)
    996 {
    997     int i = 0;                                  // Loop index variable
    998     int countInt = 0;                           // # of data points being used
    999     float countFloat = 0.0;                     // # of data points being used
    1000     float mean = 0.0;                           // The mean
    1001     float diff = 0.0;                           // Used in calculating stdev
    1002     float sumSquares = 0.0;                     // temporary variable
    1003     float sumDiffs = 0.0;                       // temporary variable
    1004     float rangeMin = 0.0;                       // Exclude data below this
    1005     float rangeMax = 0.0;                       // Exclude date above this
    1006 
    1007     // This procedure requires the mean.  If it has not been already
    1008     // calculated, then call p_psVectorSampleMean()
    1009     if (0 != isnan(stats->sampleMean)) {
    1010         p_psVectorSampleMean(myVector, maskVector, maskVal, stats);
    1011     }
    1012     mean = stats->sampleMean;
    1013 
    1014     if (stats->options & PS_STAT_USE_RANGE) {
    1015         if (maskVector != NULL) {
    1016             for (i=0;i<myVector->n;i++) {
    1017                 if (!(maskVal & maskVector->data.U8[i]) &&
    1018                         (rangeMin <= myVector->data.F32[i]) &&
    1019                         (myVector->data.F32[i] <= rangeMax)) {
    1020                     diff = myVector->data.F32[i] - mean;
    1021                     sumSquares+= (diff * diff);
    1022                     sumDiffs+= diff;
    1023                     countInt++;
    1024                 }
    1025             }
    1026         } else {
    1027             for (i=0;i<myVector->n;i++) {
    1028                 if ((rangeMin <= myVector->data.F32[i]) &&
    1029                         (myVector->data.F32[i] <= rangeMax)) {
    1030                     diff = myVector->data.F32[i] - mean;
    1031                     sumSquares+= (diff * diff);
    1032                     sumDiffs+= diff;
    1033                     countInt++;
    1034                 }
    1035             }
    1036             countInt = myVector->n;
    1037         }
    1038     } else {
    1039         if (maskVector != NULL) {
    1040             for (i=0;i<myVector->n;i++) {
    1041                 if (!(maskVal & maskVector->data.U8[i])) {
    1042                     diff = myVector->data.F32[i] - mean;
    1043                     sumSquares+= (diff * diff);
    1044                     sumDiffs+= diff;
    1045                     countInt++;
    1046                 }
    1047             }
    1048         } else {
    1049             for (i=0;i<myVector->n;i++) {
    1050                 diff = myVector->data.F32[i] - mean;
    1051                 sumSquares+= (diff * diff);
    1052                 sumDiffs+= diff;
    1053                 countInt++;
    1054             }
    1055             countInt = myVector->n;
    1056         }
    1057     }
    1058     countFloat = (float) countInt;
    1059 
    1060     #ifdef DARWIN
    1061 
    1062     stats->sampleStdev = (float) sqrt( (sumSquares-(sumDiffs *
    1063                                         sumDiffs/countFloat))/ (countFloat-1));
    1064     #else
    1065 
    1066     stats->sampleStdev = sqrtf( (sumSquares-(sumDiffs *
    1067                                  sumDiffs/countFloat))/ (countFloat-1));
    1068     #endif
    1069 }
    1070 
    1071 /******************************************************************************
    1072 p_psVectorClippedStats(myVector, maskVector, maskVal, stats): calculates the
    1073 clipped stats (mean or stdev) of the input vector.
    1074  
    1075 Inputs
    1076     myVector
    1077     maskVector
    1078     maskVal
    1079     stats
    1080 Returns
    1081     NULL
    1082  *****************************************************************************/
    1083 void p_psVectorClippedStats(const psVector *restrict myVector,
    1084                             const psVector *restrict maskVector,
    1085                             unsigned int maskVal,
    1086                             psStats *stats)
    1087 {
    1088     int i = 0;                                  // Loop index variable
    1089     int j = 0;                                  // Loop index variable
    1090     float clippedMean = 0.0;                    // self-explanatory
    1091     float clippedStdev = 0.0;                   // self-explanatory
    1092     float oldStanMean = 0.0;                    // Temporary variable
    1093     float oldStanStdev = 0.0;                   // Temporary variable
    1094     psVector *tmpMask = NULL;                   // Temporary vector
    1095 
    1096     // Endure that stats->clipIter is within the proper range.
    1097     if (!((CLIPPED_NUM_ITER_LB <= stats->clipIter ) &&
    1098             (stats->clipIter <= CLIPPED_NUM_ITER_UB))) {
    1099         psAbort(__func__, "Unallowed value for clipIter (%d).\n",
    1100                 stats->clipIter);
    1101     }
    1102 
    1103     // Endure that stats->clipSigma is within the proper range.
    1104     if (!((CLIPPED_SIGMA_LB <= stats->clipSigma ) &&
    1105             (stats->clipSigma <= CLIPPED_SIGMA_UB))) {
    1106         psAbort(__func__, "Unallowed value for clipSigma (%f).\n",
    1107                 stats->clipSigma);
    1108     }
    1109 
    1110     // We allocate a temporary mask vector since during the iterative
    1111     // steps that follow, we will be masking off additional data points.
    1112     // However, we do no want to modify the original mask vector.
    1113     tmpMask = psVectorAlloc(myVector->n, PS_TYPE_U8);
    1114     tmpMask->n = myVector->n;
    1115 
    1116     // If we were called with a mask vector, then initialize the temporary
    1117     // mask vector with those values.
    1118     if (maskVector != NULL) {
    1119         for (i=0;i<tmpMask->n;i++) {
    1120             tmpMask->data.U8[i] = maskVector->data.U8[i];
    1121         }
    1122     }
    1123 
    1124     // 1. Compute the sample median.
    1125     // NOTE: This seems odd.  Verify with IfA that we want to calculate the
    1126     // median here, not the mean.
    1127     p_psVectorSampleMedian(myVector, maskVector, maskVal, stats);
    1128 
    1129     // 2. Compute the sample standard deviation.
    1130     p_psVectorSampleStdev(myVector, maskVector, maskVal, stats);
    1131 
    1132     // 3. Use the sample median as the first estimator of the mean X.
    1133     clippedMean = stats->sampleMean;
    1134 
    1135     // 4. Use the sample stdev as the first estimator of the mean stdev.
    1136     clippedStdev = stats->sampleStdev;
    1137 
    1138     // Must save the old sampleMean and sampleStdev since the following code
    1139     // block overwrites them.
    1140     oldStanMean = stats->sampleMean;
    1141     oldStanStdev = stats->sampleStdev;
    1142 
    1143     // 5. Repeat N times:
    1144     for (i=0;i<stats->clipIter;i++) {
    1145         for (j=0;j<myVector->n;j++) {
    1146             // a) Exclude all values x_i for which |x_i - x| > K * stdev
    1147             if (fabs(myVector->data.F32[j] - clippedMean) >
    1148                     (stats->clipSigma * clippedStdev)) {
    1149                 tmpMask->data.U8[i] = 0xff;
    1150             }
    1151             // b) compute new mean and stdev
    1152             p_psVectorSampleMedian(myVector, tmpMask, maskVal, stats);
    1153             p_psVectorSampleStdev(myVector, tmpMask, maskVal, stats);
    1154 
    1155             // c) Use the new mean for x
    1156             clippedMean = stats->sampleMean;
    1157 
    1158             // d) Use the new stdev for stdev
    1159             clippedStdev = stats->sampleStdev;
    1160         }
    1161     }
    1162     stats->sampleMean = oldStanMean;
    1163     stats->sampleStdev= oldStanStdev;
    1164 
    1165     // 7. The last calcuated value of x is the cliped mean.
    1166     if (stats->options & PS_STAT_CLIPPED_MEAN) {
    1167         stats->clippedMean = clippedMean;
    1168     }
    1169 
    1170     // 8. The last calcuated value of stdev is the cliped stdev.
    1171     if (stats->options & PS_STAT_CLIPPED_STDEV) {
    1172         stats->clippedStdev = clippedStdev;
    1173     }
    1174 
    1175     psVectorFree(tmpMask);
    11761204}
    11771205
Note: See TracChangeset for help on using the changeset viewer.