IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Dec 21, 2004, 10:42:07 AM (22 years ago)
Author:
gusciora
Message:

Added errors arguments to the VectorStats and VectorHistogram functions.
The arguments are ignored in the histogram and robust stats code.

File:
1 edited

Legend:

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

    r2762 r2778  
    99 *  @author GLG, MHPCC
    1010 *
    11  *  @version $Revision: 1.104 $ $Name: not supported by cvs2svn $
    12  *  @date $Date: 2004-12-20 21:39:42 $
     11 *  @version $Revision: 1.105 $ $Name: not supported by cvs2svn $
     12 *  @date $Date: 2004-12-21 20:42:07 $
    1313 *
    1414 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    146146 *****************************************************************************/
    147147int p_psVectorSampleMean(const psVector* restrict myVector,
     148                         const psVector* restrict errors,
    148149                         const psVector* restrict maskVector,
    149150                         psU32 maskVal,
     
    156157    // If PS_STAT_USE_RANGE is requested, then we enter a slightly different
    157158    // loop.
    158     if (stats->options & PS_STAT_USE_RANGE) {
    159         if (maskVector != NULL) {
    160             for (i = 0; i < myVector->n; i++) {
    161                 // Check if the data is with the specified range
    162                 if (!(maskVal & maskVector->data.U8[i]) &&
    163                         (stats->min <= myVector->data.F32[i]) &&
    164                         (myVector->data.F32[i] <= stats->max)) {
     159    if (errors == NULL) {
     160        if (stats->options & PS_STAT_USE_RANGE) {
     161            if (maskVector != NULL) {
     162                for (i = 0; i < myVector->n; i++) {
     163                    // Check if the data is with the specified range
     164                    if (!(maskVal & maskVector->data.U8[i]) &&
     165                            (stats->min <= myVector->data.F32[i]) &&
     166                            (myVector->data.F32[i] <= stats->max)) {
     167                        mean += myVector->data.F32[i];
     168                        count++;
     169                    }
     170                }
     171                if (count != 0) {
     172                    mean /= (float)count;
     173                } else {
     174                    mean = NAN;
     175                }
     176
     177            } else {
     178                for (i = 0; i < myVector->n; i++) {
     179                    if ((stats->min <= myVector->data.F32[i]) &&
     180                            (myVector->data.F32[i] <= stats->max)) {
     181                        mean += myVector->data.F32[i];
     182                        count++;
     183                    }
     184                }
     185                if (count != 0) {
     186                    mean /= (float)count;
     187                } else {
     188                    mean = NAN;
     189                }
     190            }
     191        } else {
     192            if (maskVector != NULL) {
     193                for (i = 0; i < myVector->n; i++) {
     194                    if (!(maskVal & maskVector->data.U8[i])) {
     195                        mean += myVector->data.F32[i];
     196                        count++;
     197                    }
     198                }
     199                if (count != 0) {
     200                    mean /= (float)count;
     201                } else {
     202                    mean = NAN;
     203                }
     204            } else {
     205                for (i = 0; i < myVector->n; i++) {
    165206                    mean += myVector->data.F32[i];
    166                     count++;
    167                 }
    168             }
    169             if (count != 0) {
    170                 mean /= (float)count;
     207                }
     208                mean /= (float)myVector->n;
     209            }
     210        }
     211    } else {
     212        psF32 errorDivisor = 0.0;
     213        if (stats->options & PS_STAT_USE_RANGE) {
     214            if (maskVector != NULL) {
     215                for (i = 0; i < myVector->n; i++) {
     216                    // Check if the data is with the specified range
     217                    if (!(maskVal & maskVector->data.U8[i]) &&
     218                            (stats->min <= myVector->data.F32[i]) &&
     219                            (myVector->data.F32[i] <= stats->max)) {
     220                        mean += myVector->data.F32[i]/errors->data.F32[i];
     221                        errorDivisor+= (1.0 / errors->data.F32[i]);
     222                        count++;
     223                    }
     224                }
     225                if (count != 0) {
     226                    mean /= errorDivisor;
     227                } else {
     228                    mean = NAN;
     229                }
     230
    171231            } else {
    172                 mean = NAN;
    173             }
    174 
    175         } else {
    176             for (i = 0; i < myVector->n; i++) {
    177                 if ((stats->min <= myVector->data.F32[i]) &&
    178                         (myVector->data.F32[i] <= stats->max)) {
    179                     mean += myVector->data.F32[i];
    180                     count++;
    181                 }
    182             }
    183             if (count != 0) {
    184                 mean /= (float)count;
     232                for (i = 0; i < myVector->n; i++) {
     233                    if ((stats->min <= myVector->data.F32[i]) &&
     234                            (myVector->data.F32[i] <= stats->max)) {
     235                        mean += myVector->data.F32[i]/errors->data.F32[i];
     236                        errorDivisor+= (1.0 / errors->data.F32[i]);
     237                        count++;
     238                    }
     239                }
     240                if (count != 0) {
     241                    mean /= errorDivisor;
     242                } else {
     243                    mean = NAN;
     244                }
     245            }
     246        } else {
     247            if (maskVector != NULL) {
     248                for (i = 0; i < myVector->n; i++) {
     249                    if (!(maskVal & maskVector->data.U8[i])) {
     250                        mean += myVector->data.F32[i]/errors->data.F32[i];
     251                        errorDivisor+= (1.0 / errors->data.F32[i]);
     252                        count++;
     253                    }
     254                }
     255                if (count != 0) {
     256                    mean /= errorDivisor;
     257                } else {
     258                    mean = NAN;
     259                }
    185260            } else {
    186                 mean = NAN;
    187             }
    188         }
    189     } else {
    190         if (maskVector != NULL) {
    191             for (i = 0; i < myVector->n; i++) {
    192                 if (!(maskVal & maskVector->data.U8[i])) {
    193                     mean += myVector->data.F32[i];
    194                     count++;
    195                 }
    196             }
    197             if (count != 0) {
    198                 mean /= (float)count;
    199             } else {
    200                 mean = NAN;
    201             }
    202         } else {
    203             for (i = 0; i < myVector->n; i++) {
    204                 mean += myVector->data.F32[i];
    205             }
    206             mean /= (float)myVector->n;
     261                for (i = 0; i < myVector->n; i++) {
     262                    mean += myVector->data.F32[i]/errors->data.F32[i];
     263                    errorDivisor+= (1.0 / errors->data.F32[i]);
     264                }
     265                mean /= errorDivisor;
     266            }
    207267        }
    208268    }
     
    349409/******************************************************************************
    350410p_psVectorNValues(myVector, maskVector, maskVal, stats): This routine returns
    351 "true" if the inputPsVector as 1 or more valid elements (a valid element is an
    352 unmasked element within the specifined min/max range).  Otherwise, return
     411"true" if the inputPsVector has 1 or more valid elements (a valid element is an
     412unmasked element within the specified min/max range).  Otherwise, return
    353413"false".
    354414 *****************************************************************************/
     
    447507median of the input vector.  Returns true on success (including if there were
    448508no valid input vector elements).
     509 
     510XXX: Use static vectors for sort arrays.
    449511 *****************************************************************************/
    450512bool p_psVectorSampleMedian(const psVector* restrict myVector,
     
    522584    }
    523585
    524     // Calculate the median exactly.
     586    // Calculate the median exactly.  Use the average if the number of samples
     587    // is even.
    525588    if (0 == (nValues % 2)) {
    526589        stats->sampleMedian = 0.5 * (sortedVector->data.F32[(nValues / 2) - 1] +
     
    723786 
    724787 *****************************************************************************/
    725 void p_psVectorSampleStdev(const psVector* restrict myVector,
    726                            const psVector* restrict maskVector,
    727                            psU32 maskVal,
    728                            psStats* stats)
     788void p_psVectorSampleStdevOLD(const psVector* restrict myVector,
     789                              const psVector* restrict errors,
     790                              const psVector* restrict maskVector,
     791                              psU32 maskVal,
     792                              psStats* stats)
    729793{
    730794    psS32 i = 0;                  // Loop index variable
     
    739803    // calculated, then call p_psVectorSampleMean()
    740804    if (0 != isnan(stats->sampleMean)) {
    741         p_psVectorSampleMean(myVector, maskVector, maskVal, stats);
     805        p_psVectorSampleMean(myVector, errors, maskVector, maskVal, stats);
    742806    }
    743807    // If the mean is NAN, then generate a warning and set the stdev to NAN.
     
    801865    } else {
    802866        countFloat = (float)countInt;
    803         #ifdef DARWIN
    804 
    805         stats->sampleStdev = (float)sqrt((sumSquares -
    806                                           (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
    807         #else
    808 
    809         stats->sampleStdev = sqrtf((sumSquares -
    810                                     (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
    811         #endif
    812 
    813     }
    814 }
    815 
     867        stats->sampleStdev = PS_SQRT_F32((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
     868    }
     869}
    816870/******************************************************************************
    817 p_psVectorClippedStats(myVector, maskVector, maskVal, stats): calculates the
     871p_psVectorSampleStdev(myVector, maskVector, maskVal, stats): calculates the
     872stdev of the input vector.
     873Inputs
     874    myVector
     875    maskVector
     876    maskVal
     877    stats
     878Returns
     879    NULL
     880 
     881 *****************************************************************************/
     882void p_psVectorSampleStdev(const psVector* restrict myVector,
     883                           const psVector* restrict errors,
     884                           const psVector* restrict maskVector,
     885                           psU32 maskVal,
     886                           psStats* stats)
     887{
     888    psS32 i = 0;                  // Loop index variable
     889    psS32 countInt = 0;           // # of data points being used
     890    float countFloat = 0.0;     // # of data points being used
     891    float mean = 0.0;           // The mean
     892    float diff = 0.0;           // Used in calculating stdev
     893    float sumSquares = 0.0;     // temporary variable
     894    float sumDiffs = 0.0;       // temporary variable
     895    //    psF32 sum1;
     896    //    psF32 sum2;
     897    psF32 errorDivisor;
     898
     899    // This procedure requires the mean.  If it has not been already
     900    // calculated, then call p_psVectorSampleMean()
     901    if (0 != isnan(stats->sampleMean)) {
     902        p_psVectorSampleMean(myVector, errors, maskVector, maskVal, stats);
     903    }
     904    // If the mean is NAN, then generate a warning and set the stdev to NAN.
     905    if (0 != isnan(stats->sampleMean)) {
     906        stats->sampleStdev = NAN;
     907        psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleStdev(): p_psVectorSampleMean() reported a NAN mean.\n");
     908        return;
     909    }
     910
     911    mean = stats->sampleMean;
     912    if (stats->options & PS_STAT_USE_RANGE) {
     913        if (maskVector != NULL) {
     914            for (i = 0; i < myVector->n; i++) {
     915                if (!(maskVal & maskVector->data.U8[i]) &&
     916                        (stats->min <= myVector->data.F32[i]) &&
     917                        (myVector->data.F32[i] <= stats->max)) {
     918                    diff = myVector->data.F32[i] - mean;
     919                    sumSquares += (diff * diff);
     920                    sumDiffs += diff;
     921                    countInt++;
     922                    errorDivisor+= (1.0 / PS_SQR(errors->data.F32[i]));
     923                }
     924            }
     925        } else {
     926            for (i = 0; i < myVector->n; i++) {
     927                if ((stats->min <= myVector->data.F32[i]) &&
     928                        (myVector->data.F32[i] <= stats->max)) {
     929                    diff = myVector->data.F32[i] - mean;
     930                    sumSquares += (diff * diff);
     931                    sumDiffs += diff;
     932                    countInt++;
     933                    errorDivisor+= (1.0 / PS_SQR(errors->data.F32[i]));
     934                }
     935            }
     936            countInt = myVector->n;
     937        }
     938    } else {
     939        if (maskVector != NULL) {
     940            for (i = 0; i < myVector->n; i++) {
     941                if (!(maskVal & maskVector->data.U8[i])) {
     942                    diff = myVector->data.F32[i] - mean;
     943                    sumSquares += (diff * diff);
     944                    sumDiffs += diff;
     945                    countInt++;
     946                    errorDivisor+= (1.0 / PS_SQR(errors->data.F32[i]));
     947                }
     948            }
     949        } else {
     950            for (i = 0; i < myVector->n; i++) {
     951                diff = myVector->data.F32[i] - mean;
     952                sumSquares += (diff * diff);
     953                sumDiffs += diff;
     954                countInt++;
     955            }
     956            countInt = myVector->n;
     957            errorDivisor+= (1.0 / PS_SQR(errors->data.F32[i]));
     958        }
     959    }
     960
     961    if (countInt == 0) {
     962        stats->sampleStdev = NAN;
     963        psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleStdev(): no valid psVector elements (%d).  Setting stats->sampleStdev = NAN.\n", countInt);
     964    } else if (countInt == 1) {
     965        stats->sampleStdev = 0.0;
     966        psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleStdev(): only one valid psVector elements (%d).  Setting stats->sampleStdev = 0.0.\n", countInt);
     967    } else {
     968        // XXX: The ADD specifies this as the definition of the standard
     969        // deviation if the errors are known.  Verify this with IfA: none of
     970        // the data points in the vector are used.  Verify that the masks and
     971        // data ranges are used correctly.
     972        if (errors != NULL) {
     973            stats->sampleStdev = (1.0 / PS_SQRT_F32(errorDivisor));
     974        } else {
     975            countFloat = (float)countInt;
     976            stats->sampleStdev = PS_SQRT_F32((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
     977
     978        }
     979    }
     980}
     981
     982/******************************************************************************
     983p_psVectorClippedStats(myVector, errors, maskVector, maskVal, stats): calculates the
    818984clipped stats (mean or stdev) of the input vector.
    819985 
     
    829995 *****************************************************************************/
    830996int p_psVectorClippedStats(const psVector* restrict myVector,
     997                           const psVector* restrict errors,
    831998                           const psVector* restrict maskVector,
    832999                           psU32 maskVal,
     
    8731040
    8741041    // 2. Compute the sample standard deviation.
    875     p_psVectorSampleStdev(myVector, maskVector, maskVal, stats);
     1042    p_psVectorSampleStdev(myVector, errors, maskVector, maskVal, stats);
    8761043    if (isnan(stats->sampleStdev)) {
    8771044        psLogMsg(__func__, PS_LOG_WARN, "Call to p_psVectorSampleStdev returned NAN\n");
     
    8941061    // 5. Repeat N times:
    8951062    for (i = 0; i < stats->clipIter; i++) {
    896         for (j = 0; j < myVector->n; j++) {
    897             // a) Exclude all values x_i for which |x_i - x| > K * stdev
    898             if (fabs(myVector->data.F32[j] - clippedMean) > (stats->clipSigma * clippedStdev)) {
    899                 tmpMask->data.U8[i] = 0xff;
     1063        // a) Exclude all values x_i for which |x_i - x| > K * stdev
     1064        if (errors != NULL) {
     1065            for (j = 0; j < myVector->n; j++) {
     1066                if (fabs(myVector->data.F32[j] - clippedMean) > (stats->clipSigma * errors->data.F32[j])) {
     1067                    tmpMask->data.U8[i] = 0xff;
     1068                }
     1069            }
     1070        } else {
     1071            for (j = 0; j < myVector->n; j++) {
     1072                if (fabs(myVector->data.F32[j] - clippedMean) > (stats->clipSigma * clippedStdev)) {
     1073                    tmpMask->data.U8[i] = 0xff;
     1074                }
    9001075            }
    9011076        }
    9021077
    9031078        // b) compute new mean and stdev
    904         p_psVectorSampleMean(myVector, tmpMask, maskVal, stats);
    905         p_psVectorSampleStdev(myVector, tmpMask, maskVal, stats);
     1079        p_psVectorSampleMean(myVector, errors, tmpMask, maskVal, stats);
     1080        p_psVectorSampleStdev(myVector, errors, tmpMask, maskVal, stats);
    9061081
    9071082        // If the new mean and stdev are not NAN, then we use them.
     
    12421417*****************************************************************************/
    12431418int p_psVectorRobustStats(const psVector* restrict myVector,
     1419                          const psVector* restrict errors,
    12441420                          const psVector* restrict maskVector,
    12451421                          psU32 maskVal,
     
    12741450    // by computing the clipped standard deviation of the vector, and dividing
    12751451    // that by 10.0;
    1276     int rc = p_psVectorClippedStats(myVector, maskVector, maskVal, tmpStats);
     1452    //XXX: add errors
     1453    int rc = p_psVectorClippedStats(myVector, NULL, maskVector, maskVal, tmpStats);
    12771454    if (rc != 0) {
    12781455        psError(PS_ERR_UNEXPECTED_NULL,
     
    13331510
    13341511    // Populate the histogram array.
    1335     psVectorHistogram(robustHistogram, myVector, maskVector, maskVal);
     1512    psVectorHistogram(robustHistogram, myVector, errors, maskVector, maskVal);
    13361513
    13371514    // Smooth the histogram, Gaussian-style.
     
    14161593        }
    14171594    }
    1418     myStdev = sqrt((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
     1595    myStdev = PS_SQRT_F32((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
    14191596
    14201597    // Using the above (myMean, myStdev) as initial estimates, we fit a
     
    16741851
    16751852/*****************************************************************************
    1676 psVectorHistogram(out, in, mask, maskVal): this procedure takes as input a
    1677 preallocated and initialized histogram structure.  It fills the bins in that
    1678 histogram structure in accordance with the input data "in" and the, possibly
    1679 NULL, mask vector.
     1853psVectorHistogram(out, in, errors, mask, maskVal): this procedure takes as
     1854input a preallocated and initialized histogram structure.  It fills the bins
     1855in that histogram structure in accordance with the input data "in" and the,
     1856possibly NULL, mask vector.
    16801857 
    16811858Inputs:
     
    16861863Returns:
    16871864    The histogram structure "out".
     1865 
     1866XXX: Waiting for direction on how to use the errors parameter.
    16881867 *****************************************************************************/
    16891868psHistogram* psVectorHistogram(psHistogram* out,
    16901869                               const psVector* restrict in,
     1870                               const psVector* restrict errors,
    16911871                               const psVector* restrict mask,
    16921872                               psU32 maskVal)
     
    17001880        PS_VECTOR_CHECK_SIZE_EQUAL(in, mask, NULL);
    17011881        PS_VECTOR_CHECK_TYPE(mask, PS_TYPE_U8, NULL);
     1882    }
     1883    if (errors != NULL) {
     1884        PS_VECTOR_CHECK_SIZE_EQUAL(in, errors, NULL);
     1885        PS_VECTOR_CHECK_TYPE(errors, in->type.type, NULL);
    17021886    }
    17031887
     
    18282012psStats* psVectorStats(psStats* stats,
    18292013                       psVector* in,
     2014                       psVector* errors,
    18302015                       psVector* mask,
    18312016                       psU32 maskVal)
     
    18372022        PS_VECTOR_CHECK_TYPE(mask, PS_TYPE_U8, stats);
    18382023    }
     2024    if (errors != NULL) {
     2025        PS_VECTOR_CHECK_SIZE_EQUAL(errors, in, stats);
     2026        PS_VECTOR_CHECK_TYPE(errors, in->type.type, stats);
     2027    }
     2028
    18392029    psVector* inF32;
    1840     psS32 mustFreeTmp = 1;
     2030    psVector* errorsF32;
     2031    psS32 mustFreeVectorIn = 1;
     2032    psS32 mustFreeVectorErrors = 1;
    18412033
    18422034    inF32 = p_psConvertToF32((psVector *) in);
    18432035    if (inF32 == NULL) {
    18442036        inF32 = in;
    1845         mustFreeTmp = 0;
     2037        mustFreeVectorIn = 0;
     2038    }
     2039    errorsF32 = p_psConvertToF32((psVector *) errors);
     2040    if (errorsF32 == NULL) {
     2041        errorsF32 = errors;
     2042        mustFreeVectorErrors = 0;
    18462043    }
    18472044
     
    18522049    // ************************************************************************
    18532050    if (stats->options & PS_STAT_SAMPLE_MEAN) {
    1854         if (0 != p_psVectorSampleMean(inF32, mask, maskVal, stats)) {
     2051        if (0 != p_psVectorSampleMean(inF32, errorsF32, mask, maskVal, stats)) {
    18552052            psLogMsg(__func__, PS_LOG_WARN,
    18562053                     "WARNING: psVectorStats(): p_psVectorSampleMean() returned an error.\n");
     
    18662063    // ************************************************************************
    18672064    if (stats->options & PS_STAT_SAMPLE_STDEV) {
    1868         if (0 != p_psVectorSampleMean(inF32, mask, maskVal, stats)) {
     2065        if (0 != p_psVectorSampleMean(inF32, errorsF32, mask, maskVal, stats)) {
    18692066            psLogMsg(__func__, PS_LOG_WARN,
    18702067                     "WARNING: psVectorStats(): p_psVectorSampleMean() returned an error.\n");
    18712068        }
    1872         p_psVectorSampleStdev(inF32, mask, maskVal, stats);
     2069        p_psVectorSampleStdev(inF32, errorsF32, mask, maskVal, stats);
    18732070    }
    18742071    // ************************************************************************
     
    18872084            (stats->options & PS_STAT_ROBUST_STDEV) ||
    18882085            (stats->options & PS_STAT_ROBUST_QUARTILE)) {
    1889         if (0 != p_psVectorRobustStats(inF32, mask, maskVal, stats)) {
     2086        if (0 != p_psVectorRobustStats(inF32, errorsF32, mask, maskVal, stats)) {
    18902087            psError(PS_ERR_UNKNOWN, false,
    18912088                    PS_ERRORTEXT_psStats_STATS_FAILED);
     
    18942091    }
    18952092
     2093    // XXX: Different conditions for return -1 and -2?
    18962094    if ((stats->options & PS_STAT_CLIPPED_MEAN) || (stats->options & PS_STAT_CLIPPED_STDEV)) {
    1897         if (-1 == p_psVectorClippedStats(inF32, mask, maskVal, stats)) {
     2095        if (-1 >  p_psVectorClippedStats(inF32, errorsF32, mask, maskVal, stats)) {
    18982096            psError(PS_ERR_UNKNOWN, false,
    1899                     "Failed to calculate clipped statistics for input psVector.");
     2097                    "Failed to calculate clipped statistics for input psVector.\n");
    19002098            stats->clippedMean = NAN;
    19012099            stats->clippedStdev = NAN;
    1902         } else if (-2 == p_psVectorClippedStats(inF32, mask, maskVal, stats)) {
     2100        } else if (-2 == p_psVectorClippedStats(inF32, errorsF32, mask, maskVal, stats)) {
    19032101            psLogMsg(__func__, PS_LOG_WARN, "Failed to calculate clipped statistics for input psVector.");
    19042102            stats->clippedMean = NAN;
     
    19252123    }
    19262124
    1927     if (mustFreeTmp == 1) {
     2125    if (mustFreeVectorIn == 1) {
    19282126        psFree(inF32);
    19292127    }
     2128    if (mustFreeVectorErrors == 1) {
     2129        psFree(errorsF32);
     2130    }
    19302131    return (stats);
    19312132}
Note: See TracChangeset for help on using the changeset viewer.