lib/histogram.c File Reference

#include "common.h"
#include "histogram.h"

Include dependency graph for histogram.c:

Go to the source code of this file.

Functions

static unsigned autoScale (float *values, size_t N, float *binSize, unsigned *binCount, float *minValue, float *min, float *max)
void freeHistoGram (struct histoResult **histoResults)
histoResulthistoGram (float *values, size_t N, float binSize, unsigned binCount, float minValue, float min, float max, struct histoResult *accumHisto)

Variables

static char const rcsid [] = "$Id: histogram.c,v 1.4 2004/09/14 23:43:58 hiram Exp $"


Function Documentation

static unsigned autoScale ( float *  values,
size_t  N,
float *  binSize,
unsigned *  binCount,
float *  minValue,
float *  min,
float *  max 
) [static]

Definition at line 8 of file histogram.c.

References DEFAULT_BIN_COUNT, FALSE, INFINITY, and TRUE.

Referenced by histoGram().

00014                                               : binCount is actually one
00015  *      too high to get the minimum and maximum values in the first and
00016  *      last (binCount-1) bins correctly.
00017  */
00018 {
00019 float minFound = INFINITY;
00020 float maxFound = -1.0 * INFINITY;
00021 float range = 0.0;
00022 unsigned count = 0;
00023 unsigned bins = DEFAULT_BIN_COUNT;
00024 size_t i;
00025 boolean findMinMax = FALSE;
00026 
00027 if ( (*min == 0.0) && (*max == 0.0) )
00028     findMinMax = TRUE;
00029 else
00030     {
00031     minFound = *min;
00032     maxFound = *max;
00033     }
00034 
00035 if (isnan(*minValue))
00036     {                           /*      minValue is not specified       */
00037     for (i = 0; i < N; ++i)
00038         {
00039         if (!isnan(values[i]))
00040             {
00041             if (findMinMax)
00042                 {
00043                 ++count;
00044                 if (values[i] < minFound) minFound = values[i];
00045                 if (values[i] > maxFound) maxFound = values[i];
00046                 }
00047             else
00048                 {
00049                 if ( (values[i] < *max) && (values[i] > *min) ) ++count;
00050                 }
00051             }
00052         }
00053     }
00054 else
00055     {
00056     minFound = *minValue;               /*      use given minValue      */
00057     for (i = 0; i < N; ++i)
00058         {
00059         if ((!isnan(values[i])) && (values[i] >= minFound))
00060             {
00061             if (findMinMax)
00062                 {
00063                 ++count;
00064                 if (values[i] > maxFound) maxFound = values[i];
00065                 }
00066             else
00067                 {
00068                 if ( (values[i] < *max) && (values[i] > *min) ) ++count;
00069                 }
00070             }
00071 
00072         }
00073     }
00074 
00075 if (count > 0)
00076     {
00077     /*  if the caller asked us to find min,max, return them     */
00078     if (findMinMax)
00079         {
00080         *min = minFound;
00081         *max = maxFound;
00082         }
00083 
00084     /*  If the caller did not specify a minValue, return it     */
00085     if (isnan(*minValue))
00086         *minValue = minFound;
00087 
00088     range = maxFound - minFound;
00089 
00090     /*  if they gave us a binCount, use it      */
00091     if (*binCount > 0)
00092         bins = *binCount;
00093     else
00094         *binCount = bins;
00095 
00096     if ( (range > 0.0) && (bins > 1))
00097         {
00098         /*  binSize is calculated on (bins - 1) to allow the minimum value
00099          *  to be in the middle of the first bin, and the highest value to be
00100          *      in the middle of the last bin
00101          */
00102         if (isnan(*binSize))
00103             *binSize = range / (bins - 1);
00104 
00105         if (*binSize > 0.0)
00106             return count;
00107         else
00108             return 0;   /*      did not work    */
00109         }
00110     }
00111 return 0;       /*      did not work    */
00112 }       /*      static unsigned autoScale()     */

Here is the caller graph for this function:

void freeHistoGram ( struct histoResult **  histoResults  ) 

Definition at line 114 of file histogram.c.

References histoResult::binCounts, freeMem(), histoResult::next, and histoResult::pValues.

00116 {
00117 if (histoResults && *histoResults)
00118     {
00119     struct histoResult *hr, *next;
00120 
00121     for (hr = *histoResults; hr; hr = next)
00122         {
00123         next = hr->next;
00124         freeMem(hr->binCounts);
00125         freeMem(hr->pValues);
00126         freeMem(hr);
00127         }
00128     *histoResults = NULL;
00129     }
00130 }

Here is the call graph for this function:

struct histoResult* histoGram ( float *  values,
size_t  N,
float  binSize,
unsigned  binCount,
float  minValue,
float  min,
float  max,
struct histoResult accumHisto 
) [read]

Definition at line 132 of file histogram.c.

References AllocArray, AllocVar, autoScale(), histoResult::binCount, histoResult::binCounts, histoResult::binSize, histoResult::binZero, histoResult::count, DEFAULT_BIN_COUNT, FALSE, NAN, histoResult::pValues, and TRUE.

00146             : when giving a binCount, it is actually one
00147  *      higher to get the minimum and maximum values in the first and
00148  *      last (binCount-1) bins correctly.  The resulting histogram will
00149  *      appear to be (binCount-1) number of bins.
00150  *      When given a pointer to accumHisto, use that existing histo gram
00151  *      and continue accumulations in it.
00152  */
00153 {
00154 float autoBinSize = NAN;        /*      pass NAN's to cause auto scaling */
00155 float autoMinValue = NAN;
00156 float range = 0.0;
00157 unsigned autoBinCount = 0;
00158 unsigned autoValueCount = 0;
00159 boolean autoScaling = FALSE;
00160 unsigned valueCount = 0;
00161 unsigned i;                     /*      array index     */
00162 struct histoResult *hr;
00163 unsigned missed = 0;
00164 
00165 if (N == 0)
00166     return NULL;        /*      we don't work on zero number of values  */
00167 
00168 if (accumHisto)         /*      if accumulating in existing histogram   */
00169     {                   /*      use its parameters as the scaling values */
00170     autoBinCount = accumHisto->binCount;
00171     autoBinSize = accumHisto->binSize;
00172     autoMinValue = accumHisto->binZero;
00173     autoScaling = FALSE;
00174     range = autoBinSize * (autoBinCount - 1);
00175     valueCount = accumHisto->count;
00176     }
00177 else
00178     {
00179 /*      Caller may give us a range to work within       */
00180 if ( (0.0 == min) && (0.0 == max) )
00181     autoScaling = TRUE;
00182 else
00183     {
00184     range = max - min;
00185     if (range == 0.0)
00186         return NULL;    /*      caller gave us equal min, max ! */
00187     }
00188 
00189 /*      Caller may give us any of the binCount, binSize, minValue */
00190 if (binCount > 1)
00191     autoBinCount = binCount;
00192 else if (!autoScaling)
00193     autoBinCount = DEFAULT_BIN_COUNT;
00194 
00195 if (!isnan(binSize))
00196     autoBinSize = binSize;
00197 else if (!autoScaling)
00198     autoBinSize = range / (autoBinCount - 1);
00199 
00200 if (!isnan(minValue))
00201     autoMinValue = minValue;
00202 else if (!autoScaling)
00203     autoMinValue = min;
00204 
00205 if (autoScaling)
00206     {
00207     autoValueCount = autoScale(values, N, &autoBinSize,
00208                         &autoBinCount, &autoMinValue, &min, &max);
00209     if (autoValueCount == 0)
00210         return NULL;    /*      no result !     */
00211     }
00212 else
00213     autoValueCount = N;
00214     }
00215 
00216 if (accumHisto)         /*      if accumulating in existing histogram   */
00217     hr = accumHisto;
00218 else
00219     {
00220     AllocVar(hr);
00221     AllocArray(hr->binCounts,autoBinCount);
00222     AllocArray(hr->pValues,autoBinCount);
00223     }
00224 
00225 for (i = 0; i < N; ++i)
00226     {
00227     if (!isnan(values[i]) && (values[i] >= autoMinValue))
00228         {
00229         if ( (values[i] <= max) && (values[i] >= min) )
00230             {
00231             float f = values[i] - autoMinValue;
00232             int inx = (int) floor(f / autoBinSize);
00233 
00234             if ( (inx >= 0) && (inx < autoBinCount))
00235                 {
00236                 ++valueCount;
00237                 ++hr->binCounts[inx];
00238                 }
00239             else
00240                 ++missed;
00241             }
00242             else
00243                 ++missed;
00244         }
00245         else
00246             ++missed;
00247     }   /*      for (i = 0; i < N; ++i) */
00248 
00249 if (accumHisto)         /*      if accumulating in existing histogram   */
00250     hr->count = valueCount;     /*      only this is new        */
00251 else
00252     {
00253     hr->binSize = autoBinSize;
00254     hr->binCount = autoBinCount;
00255     hr->count = valueCount;
00256     hr->binZero = autoMinValue;
00257     }
00258 
00259 for (i = 0; i < autoBinCount; ++i)
00260     {
00261     if (hr->binCounts[i] > 0)
00262         hr->pValues[i] = (float) hr->binCounts[i] / (float) valueCount;
00263     else
00264         hr->pValues[i] = 0.0;
00265     }
00266 
00267 return hr;
00268 }

Here is the call graph for this function:


Variable Documentation

char const rcsid[] = "$Id: histogram.c,v 1.4 2004/09/14 23:43:58 hiram Exp $" [static]

Definition at line 6 of file histogram.c.


Generated on Tue Dec 25 19:53:31 2007 for blat by  doxygen 1.5.2