From 051c612abad9a5e8dc53286c17dbf46a158dc624 Mon Sep 17 00:00:00 2001 From: cignoni Date: Wed, 5 Mar 2008 11:21:49 +0000 Subject: [PATCH] Heavily refactored the whole structure. Some interfaces have been changed. Be careful. --- vcg/math/histogram.h | 193 +++++++++++++++++++++++++++---------------- 1 file changed, 123 insertions(+), 70 deletions(-) diff --git a/vcg/math/histogram.h b/vcg/math/histogram.h index b27b3451..fec9feab 100644 --- a/vcg/math/histogram.h +++ b/vcg/math/histogram.h @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.17 2008/02/29 12:15:06 cignoni +added maxcount + Revision 1.16 2006/11/28 21:29:21 cignoni Re added typedef Histogramf and Histogramd @@ -98,54 +101,44 @@ class Histogram { // public data members -public: +private: - //! Counters for bins. - std::vector H; - - //! Range for bins. - std::vector R; + std::vector H; //! Counters for bins. + std::vector R; //! Range for bins. + ScalarType minv; //! Minimum value. + ScalarType maxv; //! Maximum value. + int n; //! Number of vaild intervals stored between minv and maxv. - //! Minimum value. - ScalarType minv; - //! Maximum value. - ScalarType maxv; + /// incrementally updated values + int cnt; //! Number of accumulated samples. + ScalarType avg; //! Average. + ScalarType rms; //! Root mean square. - //! Number of intervals. - int n; - - //! Number of accumulated samples. - int cnt; - - //! Average. - ScalarType avg; - - //! Root mean square. - ScalarType rms; + /** + * Returns the index of the bin which contains a given value. + */ + int BinIndex(ScalarType val) ; // public methods public: - + /** * Set the histogram values. * * This method is used to correctly initialize the bins of the histogram. + * n is the number of valid intervals between minv and maxv. + * for a more robust working, the Histogram class stores also the two out of range intervals (-inf, minv] and [maxv, +inf) + * Each bin is left closed (eg it contains the value + * The \a gamma parameter is applied to modify the distribution of the ranges of the bins. Default uniform distibution. + * */ - void SetRange(ScalarType _minv, ScalarType _maxv, int _n); + void SetRange(ScalarType _minv, ScalarType _maxv, int _n,ScalarType gamma=1.0 ); - /** - * Set the histogram values. - * - * This method is used to correctly initialize the bins of the histogram. - * The \a gamma parameter is applied to modify the ranges of the bins. - */ - void SetRange(ScalarType _minv, ScalarType _maxv, int _n, ScalarType gamma); + ScalarType MinV() {return minv;}; //! Minimum value. + ScalarType MaxV() {return maxv;}; //! Minimum value. - /** - * Returns the index of the bin which contains a given value. - */ - int Interize(ScalarType val); + /** * Add a new value to the histogram. @@ -156,6 +149,11 @@ public: void Add(ScalarType v); int MaxCount() const; + int BinCount(ScalarType v); + int BinCount(ScalarType v, ScalarType width); + int RangeCount(ScalarType rangeMin, ScalarType rangeMax); + ScalarType BinWidth(ScalarType v); + /** * Returns the value corresponding to a given percentile of the data. * @@ -195,23 +193,22 @@ void Histogram::Clear() maxv=1; } +/* +Note that the histogram holds valid bins plus two semi-infinite bins. -template -void Histogram::SetRange(ScalarType _minv, ScalarType _maxv, int _n) -{ - // reset data - Clear(); +R[0] = -inf +R[1] = minv +R[n+1] = maxv +R[n+2] = +inf - // set bins - minv=_minv;maxv=_maxv;n=_n; - H.resize(n+1); - fill(H.begin(),H.end(),0); - R.resize(n+1); - ScalarType dlt=(maxv-minv)/n; - for(int i=0; i void Histogram::SetRange(ScalarType _minv, ScalarType _maxv, int _n, ScalarType gamma) @@ -220,31 +217,61 @@ void Histogram::SetRange(ScalarType _minv, ScalarType _maxv, int _n, Clear(); minv=_minv;maxv=_maxv;n=_n; - H.resize(n+1); + H.resize(n+2); fill(H.begin(),H.end(),0); - R.resize(n+1); + R.resize(n+3); - double dlt=(maxv-minv); - for(int i=0;i::max(); + R[n+2] = std::numeric_limits< ScalarType >::max(); + + double delta=(maxv-minv); + if(gamma==1) + { + for(int i=0; i<=n; ++i) + R[i+1] = minv + delta*ScalarType(i)/n; + } + else + { + for(int i=0; i<=n; ++i) + R[i+1] = minv + delta*pow(ScalarType(i)/n,gamma); + } } + template -int Histogram::Interize(ScalarType val) +int Histogram::BinIndex(ScalarType val) { - int pos = lower_bound(R.begin(),R.end(),val) - R.begin() - 1; - if (pos>n) pos=n; + // lower_bound returns the furthermost iterator i in [first, last) such that, for every iterator j in [first, i), *j < value. + // E.g. An iterator pointing to the first element "not less than" val, or end() if every element is less than val. + typename std::vector::iterator it = lower_bound(R.begin(),R.end(),val); + + assert(it!=R.begin()); + assert(it!=R.end()); + assert((*it)>=val); + + int pos = it-R.begin(); + assert(pos >=1); + pos -= 1; + assert (R[pos] < val); + assert ( val <= R[pos+1] ); return pos; } +/* + H[0] H[1] H[2] H[3] H[4] H[5] H[6] +-inf 0 2 4 6 8 10 +inf +R[0] R[1] R[2] R[3] R[4] R[5] R[6] R[7] +asking for 3.14 lower bound will return an iterator pointing to R[3]==4; and will increase H[2] +asking for 4 lower bound will return an iterator pointing to R[3]==4; and will increase H[2] + +*/ template void Histogram::Add(ScalarType v) { - int pos= lower_bound(R.begin(),R.end(),v)-R.begin()-1; - - if(pos>=0 && pos<=n) + int pos=BinIndex(v); + if(pos>=0 && pos<=n) { ++H[pos]; ++cnt; @@ -253,6 +280,35 @@ void Histogram::Add(ScalarType v) } } +template +int Histogram::BinCount(ScalarType v) +{ + return H[BinIndex(v)]; +} + +template +int Histogram::BinCount(ScalarType v, ScalarType width) +{ + return RangeCount(v-width/2.0,v+width/2.0); +} + +template +int Histogram::RangeCount(ScalarType rangeMin, ScalarType rangeMax) +{ + int firstBin=BinIndex(rangeMin); + int lastBin=BinIndex (rangeMax); + int sum=0; + for(int i=firstBin; i<=lastBin;++i) + sum+=H[i]; + return sum; +} + +template +ScalarType Histogram::BinWidth(ScalarType v) +{ + int pos=BinIndex(v); + return R[pos+1]-R[pos]; +} template void Histogram::FileWrite(const std::string &filename) @@ -273,7 +329,9 @@ int Histogram::MaxCount() const return *(std::max_element(H.begin(),H.end())); } - +// Return the scalar value such that there are samples <= . +// E.g. Percentile(0.0) will return R[1] e.g. min value +// E.g. Percentile(1.0) will return R[n+1] e.g max value template ScalarType Histogram::Percentile(ScalarType frac) const @@ -285,26 +343,21 @@ ScalarType Histogram::Percentile(ScalarType frac) const assert(frac >= 0 && frac <= 1); ScalarType sum=0,partsum=0; - int isum=0; int i; - for(i=0;i=sum) break; } + assert(i