gml_Histogram.h

00001 // gml_Histogram.h --
00002 //
00003 //    Define the gml_THistogram class.
00004 //
00005 //  Copyright (c) 2003 CLIPS-IMAG
00006 //
00007 //  See the file "gml_LicenseTerms.txt" for information on usage and redistribution
00008 //  of this file, and for a DISCLAIMER OF ALL WARRANTIES.
00009 //
00010 //  Updated to GML on December 21, 2003 (JL).
00011 //  Created on August 6, 1998 (FB).
00012 
00013 #ifndef __GML_HISTOGRAM__
00014 #define __GML_HISTOGRAM__
00015 
00016 // system includes
00017 #include <limits.h>
00018 #include <assert.h>
00019 #include <strings.h>
00020 #include <math.h>
00021 
00022 // project includes
00023 #include "gml/base/gml_Types.h"
00024 #include "gml/base/gml_Errors.h"
00025 #include "gml/math/gml_Math.h"
00026 #include "gml/base/gml_Array.h"
00027 
00028 
00029 /// gml_THistogram --
00030 ///
00031 ///   N-dimensional histogram objects.
00032 ///   Most checks in this class are done using assertions; compile with @c -DNDEBUG
00033 ///   to remove parameter checking.
00034 
00035 class gml_THistogram
00036 {
00037 public:
00038 
00039 
00040 #pragma mark -
00041 #pragma mark Constructors
00042 
00043 
00044   /// Init --
00045   ///
00046   ///   Allocate an histogram of dimension <dim>.
00047   ///   The resolution in dimension <k> is specified by <resolution[k]>.
00048   ///   
00049   ///   If the resolutions aren't specified (NULL), they default to 
00050   ///   <sDefaultResolution>
00051 
00052   gml_TError Init (UInt8 dimensions,    ///< histogram dimensions
00053                    UInt32 *resolution   ///< resolution for each dimension
00054       );
00055 
00056 
00057   /// Dispose --
00058   ///
00059   ///   Release the ressources allocated by this object.
00060 
00061   void Dispose ();
00062 
00063 
00064   /// Setup --
00065   ///
00066   ///   Setup the scale of the histogram
00067 
00068   gml_TError Setup (UInt8 dimension,    ///< index of the dimension to set up
00069                     Float32 start,      ///< lower bound of first interval
00070                     Float32 stepWidth   ///< width of each bucket
00071       );
00072 
00073 
00074 #pragma mark -
00075 #pragma mark Accessors
00076 
00077 
00078   /// Dim --
00079   ///
00080   ///   Return the dimension of the histogram
00081   
00082   UInt8 Dim () const;
00083 
00084 
00085   /// Resolution --
00086   ///
00087   ///   Return the resolution for dimension <dim>
00088   
00089   UInt32 Resolution (UInt8 dim = 0) const;
00090 
00091 
00092   /// Start --
00093   ///
00094   ///   Return the lower bound for dimension <dim>
00095   Float32 Start (UInt8 dim = 0) const;
00096 
00097 
00098   /// Step --
00099   ///
00100   ///   Return the bucket width for dimension <dim>
00101   
00102   Float32 Step (UInt8 dim = 0) const;
00103 
00104 
00105   /// Samples --
00106   ///
00107   ///   Return the current number of samples
00108   
00109   UInt32 Samples () const;
00110 
00111 
00112   /// Get --
00113   ///
00114   ///   Return histogram value for the interval number <i>.
00115   ///   Valid only for 1D histograms.
00116   
00117   UInt32 Get (UInt32 i) const;
00118 
00119 
00120   /// Get --
00121   ///
00122   ///   Returns histogram value for the interval indexed by <i>.
00123   
00124   UInt32 Get (UInt32 *i) const;
00125 
00126 
00127   /// Get --
00128   ///
00129   ///   Return histogram value for the interval corresponding to
00130   ///   sample <sample>.
00131   ///   Valid only for 1D histograms.
00132   
00133   UInt32 Get (Float32 sample) const;
00134 
00135 
00136   /// Get --
00137   ///
00138   ///   Return histogram value for the interval corresponding to
00139   ///   sample <sample>.
00140   
00141   UInt32 Get (Float32 *sample) const;
00142 
00143 
00144   /// Next --
00145   ///
00146   ///   Walk to the index following <index> and update <sample> accordingly
00147   ///   Return <true> iff overflowing (i.e. walking back to index zero)
00148   
00149   bool Next (UInt32 *index, Float32 *sample);
00150 
00151 
00152 #pragma mark -
00153 #pragma mark Mutators
00154 
00155 
00156   /// Reset --
00157   ///
00158   ///   Reset to a blank histogram.
00159   
00160   void Reset ();
00161 
00162 
00163   /// Increment --
00164   ///
00165   ///   Increment the number of samples by <samples>
00166   
00167   void Increment (UInt32 samples = 1);
00168 
00169 
00170   /// Push --
00171   ///
00172   ///   Increment the frequency for the interval corresponding to
00173   ///   sample <sample> (one dimention).
00174   ///   returns the new value of histogram in that interval.
00175   ///   @warning Push() doesn't increment the number of samples.
00176   ///
00177   ///   Valid only for 1D histograms.
00178 
00179   void Push (Float32 sample, UInt32 count = 1);
00180 
00181 
00182   /// Push --
00183   ///
00184   ///   Increment the frequency for the interval corresponding to
00185   ///   sample <sample>.
00186   ///   returns the new value of histogram in that interval.
00187   ///   @warning Push() doesn't increment the number of samples.
00188   
00189   void Push (Float32 *sample, UInt32 count = 1);
00190 
00191 
00192   /// Push --
00193   ///
00194   ///   Increment the frequency for the interval number <i> (one dimention).
00195   ///   returns the new value of histogram in that interval.
00196   ///   @warning Push() doesn't increment the number of samples.
00197   ///
00198   ///   Valid only for 1D histograms.
00199   
00200   void Push (UInt32 index, UInt32 count = 1);
00201 
00202 
00203   /// Push --
00204   ///
00205   ///   Increment the frequency for the interval number indexed by <i>.
00206   ///   returns the new value of histogram in that interval.
00207   ///   @warning Push() doesn't increment the number of samples.
00208   
00209   void Push (UInt32 *index, UInt32 count = 1);
00210 
00211 
00212 #pragma mark -
00213 #pragma mark Expensive Accessors
00214 
00215 
00216   /// SampleMin --
00217   ///
00218   ///   Return the samples minimum.
00219   ///   All the samples used to build this histogram are greater than or equal
00220   ///   to the returned value.
00221   ///   Return NAN if the histogram is emtpy.
00222   
00223   Float32 SampleMin ();
00224 
00225 
00226   /// SampleMax --
00227   ///
00228   ///   Return the samples minimum.
00229   ///   All the samples used to build this histogram are strictly lower
00230   ///   than the returned value.
00231   ///   Return NAN if the histogram is emtpy.
00232   
00233   Float32 SampleMax ();
00234 
00235 
00236   /// BucketMin --
00237   ///
00238   ///   Return the maximum sample count in a single bucket.
00239   
00240   UInt32 BucketMin ();
00241 
00242 
00243   /// BucketMax --
00244   ///
00245   ///   Return the minimal sample count in a single bucket.
00246   
00247   UInt32 BucketMax ();
00248 
00249 
00250   /// Mean --
00251   ///
00252   ///   Compute the mean histogram value, as statistical average (robust == false)
00253   ///   or the median (robust == true).
00254   ///   Valid only for 1D histograms.
00255   
00256   gml_TError Mean (Float32 *mean, gml_TBoolean robust);
00257 
00258 
00259   /// Moments --
00260   ///
00261   ///   Compute the order 1 and 2 moments of histogram, either as the statistical
00262   ///   average and standard deviation, either as the median and median absolute
00263   ///   deviation.
00264   ///   Use Mean () eventually.
00265   ///   Currently valid only for 1D histograms.
00266   
00267   gml_TError Moments (Float32 *mean, Float32 *deviation, gml_TBoolean robust);
00268 
00269 
00270   /// Entropy --
00271   ///
00272   ///   Compute the order 1 entropy of the histogram.
00273   ///   Currently valid only for 1D histograms.
00274   
00275   gml_TError Entropy (Float32 *entropy);
00276 
00277 
00278   /// Desaturate --
00279   ///
00280   ///   Remove the samples in the extremal bucket.
00281   
00282   void Desaturate ();
00283 
00284 
00285   /// Quantiles --
00286   
00287   gml_TError Quantiles (gml_TArray<Float32>& quantiles);
00288 
00289 
00290 
00291 #pragma mark -
00292 #pragma mark Expensive Mutators
00293 
00294 
00295   /// Scale --
00296   ///
00297   ///   Scale the histogram sample counts by a factor a/2^b
00298   
00299   gml_TError Scale (UInt8 a, UInt8 b);
00300 
00301 
00302   /// Shift --
00303   ///
00304   ///   Shift up all values in the histogram by a
00305   
00306   gml_TError Shift (UInt8 a);
00307   
00308 
00309 protected:
00310 
00311 #pragma mark -
00312 #pragma mark Internal utilities
00313 
00314   /// Flat index of a sample in fData, given its N-D index
00315   UInt32 Index (UInt32 *sample) const;
00316 
00317   /// Flat index of a sample in fData, given its 1-D floating-point value
00318   UInt32 Index (Float32 sample) const;
00319 
00320   /// Flat index of a sample in fData, given its N-D floating-point value
00321   UInt32 Index (Float32 *sample) const;
00322 
00323   //
00324   // Fields
00325   //
00326 
00327   UInt8 fDim;                   ///< number of dimensions of histogram array
00328   UInt32 *fData;                ///< array of histogram values
00329   UInt32 fSize;                 ///< size of fData (product of resolutions)
00330   UInt32 fSamples;              ///< sum of histogram values
00331   UInt32 *fOffset;              ///< sub-dimension array sizes
00332   UInt32 *fIndex;               ///< temporary n-dimensional index storage
00333 
00334   // arrays of dimension parameters (on set of parameter per dimension)
00335   UInt32 *fResolution;          ///< number of intervals
00336   Float32 *fStart;              ///< lower bound of first interval
00337   Float32 *fStep;               ///< width of intervals
00338   Float32 *fStepR;              ///< reciprocates of fStep
00339 
00340 
00341 #pragma mark -
00342 #pragma mark Static members
00343 
00344 protected:
00345 
00346   // setup
00347   static void ClassInit ();     ///< class setup
00348   static bool sModuleInited;    ///< was ClassInit() called ? 
00349   
00350 public:
00351 
00352   // errors
00353   static gml_TError sErrorValidFor1DOnly;
00354   static gml_TError sErrorWrongDimension;
00355   static gml_TError sErrorWrongResolution;
00356 
00357   // defaults
00358   static const UInt32 sDefaultResolution = 256;
00359 
00360   // flags
00361   static const UInt8 sMomentsGaussian = 0 << 0;
00362   static const UInt8 sMomentsRobust   = 1 << 0;
00363 };
00364 
00365 
00366 #pragma mark -
00367 #pragma mark Inline functions
00368 
00369 inline UInt8 gml_THistogram::Dim () const
00370 {
00371   return fDim;
00372 }
00373 
00374 inline UInt32 gml_THistogram::Resolution (UInt8 dim) const
00375 {
00376   assert (dim < fDim);
00377   return fResolution[dim];
00378 }
00379 
00380 inline Float32 gml_THistogram::Start (UInt8 dim) const
00381 {
00382   assert (dim < fDim);
00383   return fStart[dim];
00384 }
00385 
00386 inline Float32 gml_THistogram::Step (UInt8 dim) const
00387 {
00388   assert (dim < fDim);
00389   return fStep[dim];
00390 }
00391 
00392 inline UInt32 gml_THistogram::Samples () const
00393 {
00394   return fSamples;
00395 }
00396 
00397 inline UInt32 gml_THistogram::Get (UInt32 sample) const
00398 {
00399   assert (fDim == 1);
00400   assert (sample < fResolution[0]);
00401   return fData[sample];
00402 }
00403 
00404 inline UInt32 gml_THistogram::Get (UInt32 *sample) const
00405 {
00406   return fData[Index (sample)];
00407 }
00408 
00409 inline UInt32 gml_THistogram::Get (Float32 sample) const
00410 {
00411   return fData[Index (sample)];
00412 }
00413 
00414 inline UInt32 gml_THistogram::Get (Float32 *sample) const
00415 {
00416   return fData[Index (sample)];
00417 }
00418 
00419 #pragma mark-
00420 
00421 inline void gml_THistogram::Increment (UInt32 samples)
00422 {
00423   fSamples += samples;
00424 }
00425 
00426 inline void gml_THistogram::Push (Float32 sample, UInt32 count)
00427 {
00428   fData[Index (sample)] += count;
00429 }
00430 
00431 inline void gml_THistogram::Push (Float32 *sample, UInt32 count)
00432 {
00433   fData[Index (sample)] += count;
00434 }
00435 
00436 inline void gml_THistogram::Push (UInt32 sample, UInt32 count)
00437 {
00438   assert (fDim == 1);
00439   assert (sample < fResolution[0]);
00440   fData[sample] += count;
00441 }
00442 
00443 inline void gml_THistogram::Push (UInt32 *sample, UInt32 count)
00444 {
00445   fData[Index (sample)] += count;
00446 }
00447 
00448 #pragma mark-
00449 
00450 inline UInt32 gml_THistogram::Index (UInt32 *sample) const
00451 {
00452   switch (fDim) {
00453     case 1: {
00454       assert (*sample < *fResolution);
00455       return *sample;
00456     }
00457     
00458     case 2: {
00459       assert (sample[0] < fResolution[0]);
00460       assert (sample[1] < fResolution[1]);
00461       return sample[0] * fOffset[0] + sample[1] * fOffset[1];
00462     }
00463     
00464     default: {
00465       UInt32 offset = 0;
00466       for (UInt8 j = 0; j < fDim; j++) {
00467         assert (sample[j] < fResolution[j]);
00468         offset += sample[j] * fOffset[j];
00469       }
00470       return offset;
00471     }
00472   }
00473 }
00474 
00475 inline UInt32 gml_THistogram::Index (Float32 sample) const
00476 {
00477   assert (fDim == 1);
00478   return (UInt32) LFloor ((sample - fStart[0]) * fStepR[0]);
00479 }
00480 
00481 inline UInt32 gml_THistogram::Index (Float32 *sample) const
00482 {
00483   for (int j = 0; j < fDim; ++j) {
00484     assert (LFloor ((sample[j] - fStart[j]) * fStepR[j])
00485             < fResolution[j]);
00486     fIndex[j] = LFloor ((sample[j] - fStart[j]) * fStepR[j]);
00487   }
00488   return Index (fIndex);
00489 }
00490 
00491 #endif /* __GML_HISTOGRAM__ */
Generated on Tue Jun 12 14:03:27 2007 for gml by Doxygen 1.5.2.