histogram.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 * VCGLib                                                            o o     *
00003 * Visual and Computer Graphics Library                            o     o   *
00004 *                                                                _   O  _   *
00005 * Copyright(C) 2004                                                \/)\/    *
00006 * Visual Computing Lab                                            /\/|      *
00007 * ISTI - Italian National Research Council                           |      *
00008 *                                                                    \      *
00009 * All rights reserved.                                                      *
00010 *                                                                           *
00011 * This program is free software; you can redistribute it and/or modify      *
00012 * it under the terms of the GNU General Public License as published by      *
00013 * the Free Software Foundation; either version 2 of the License, or         *
00014 * (at your option) any later version.                                       *
00015 *                                                                           *
00016 * This program is distributed in the hope that it will be useful,           *
00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00020 * for more details.                                                         *
00021 *                                                                           *
00022 ****************************************************************************/
00023 #ifndef __VCG_HISTOGRAM
00024 #define __VCG_HISTOGRAM
00025 
00026 #include <vector>
00027 #include <algorithm>
00028 #include <assert.h>
00029 #include <string>
00030 #include <limits>
00031 #include <vcg/math/base.h>
00032 #include <stdio.h>
00033 
00034 namespace vcg {
00035 
00036 template <class ScalarType>
00037 class Distribution
00038 {
00039 private:
00040   std::vector<ScalarType> vec;
00041   bool dirty;
00042   double valSum;
00043   double sqrdValSum;
00044   double avg;
00045   double sqrdAvg;
00046   double rms;
00047   double min_v;
00048   double max_v;
00049 
00050 
00051 public:
00052 
00053   Distribution() { Clear(); }
00054 
00055   void Clear()
00056   {
00057     vec.clear();
00058     dirty=true;
00059     min_v =  std::numeric_limits<float>::max();
00060     max_v = -std::numeric_limits<float>::max();
00061   }
00062 
00063   void Add(const ScalarType v)
00064   {
00065     vec.push_back(v);
00066     dirty=true;
00067     if(v<min_v) min_v=v;
00068     if(v>max_v) max_v=v;
00069   }
00070 
00071   ScalarType Min() const { return min_v; }
00072   ScalarType Max() const { return max_v; }
00073   ScalarType Cnt() const { return ScalarType(vec.size()); }
00074 
00075   ScalarType Sum(){ DirtyCheck(); return valSum; }
00076   ScalarType Avg(){ DirtyCheck(); return avg;}
00078   ScalarType RMS(){ DirtyCheck(); return rms;}
00079 
00082   ScalarType Variance(){ DirtyCheck(); return sqrdAvg - avg*avg ;}
00083 
00085   ScalarType StandardDeviation(){ DirtyCheck(); return sqrt( Variance() );}
00086 
00087   void DirtyCheck()
00088   {
00089     if(!dirty) return;
00090     std::sort(vec.begin(),vec.end());
00091     valSum=0;
00092     sqrdValSum=0;
00093     typename std::vector<ScalarType>::iterator vi;
00094     for(vi=vec.begin();vi!=vec.end();++vi)
00095     {
00096       valSum += double(*vi);
00097       sqrdValSum += double(*vi)*double(*vi);
00098     }
00099     avg = valSum/double(vec.size());
00100     sqrdAvg = sqrdValSum/double(vec.size());
00101     rms = math::Sqrt(sqrdAvg);
00102     dirty=false;
00103   }
00104 
00105   ScalarType Percentile(ScalarType perc)
00106   {
00107     assert(!vec.empty());
00108     assert(perc>=0 && perc<=1);
00109     DirtyCheck();
00110     int index = vec.size() *perc -1;
00111 
00112     if(index< 0 ) index = 0;
00113 
00114     return vec[index];
00115   }
00116 };
00117 
00118 
00119 
00125 template <class ScalarType>
00126 class Histogram
00127 {
00128 
00129   // public data members
00130 protected:
00131 
00132   std::vector <ScalarType> H;   
00133   std::vector <ScalarType> R;   
00134   ScalarType minv;      
00135   ScalarType maxv;      
00136   ScalarType minElem;   
00137   ScalarType maxElem;   
00138   int n;        
00139 
00140 
00142   ScalarType cnt;       
00143   ScalarType sum;       
00144   ScalarType rms;       
00145 
00149   int BinIndex(ScalarType val) ;
00150 
00151   // public methods
00152 public:
00153 
00164   void SetRange(ScalarType _minv, ScalarType _maxv, int _n,ScalarType gamma=1.0 );
00165 
00166   ScalarType MinV() {return minv;}      
00167   ScalarType MaxV() {return maxv;}      
00168   ScalarType Sum()  {return sum;}       
00169   ScalarType Cnt()  {return cnt;}
00170 
00171   ScalarType MinElem() {return minElem;}        
00172   ScalarType MaxElem() {return maxElem;}        
00173 
00180   void Add(ScalarType v, ScalarType increment=ScalarType(1.0));
00181 
00182   ScalarType MaxCount() const;        
00183   ScalarType MaxCountInRange() const; 
00184   int BinNum() const {return n;}
00185   ScalarType BinCount(ScalarType v);
00186   ScalarType BinCountInd(int index) {return H[index];}
00187   ScalarType BinCount(ScalarType v, ScalarType width);
00188   ScalarType BinLowerBound(int index) {return R[index];}
00189   ScalarType BinUpperBound(int index) {return R[index+1];}
00190   ScalarType RangeCount(ScalarType rangeMin, ScalarType rangeMax);
00191   ScalarType BinWidth(ScalarType v);
00192 
00198   ScalarType Percentile(ScalarType frac) const;
00199 
00201   ScalarType Avg(){ return sum/cnt;}
00202 
00204   ScalarType RMS(){ return sqrt(rms/double(cnt));}
00205 
00207   ScalarType Variance(){ return fabs(rms/cnt-Avg()*Avg());}
00208 
00210   ScalarType StandardDeviation(){ return sqrt(Variance());}
00211 
00213   void FileWrite(const std::string &filename);
00214 
00216   void Clear();
00217 };
00218 
00219 template <class ScalarType>
00220 void Histogram<ScalarType>::Clear()
00221 {
00222   H.clear();
00223   R.clear();
00224   cnt=0;
00225   sum=0;
00226   rms=0;
00227   n=0;
00228   minv=0;
00229   maxv=1;
00230   minElem = std::numeric_limits<ScalarType>::max();
00231   maxElem = -std::numeric_limits<ScalarType>::max();
00232 }
00233 
00234 /*
00235 Note that the histogram holds <n> valid bins plus two semi-infinite bins.
00236 
00237 R[0]   = -inf
00238 R[1]   = minv
00239 R[n+1] = maxv
00240 R[n+2] = +inf
00241 
00242 
00243 Eg. SetRange(0, 10, 5) asks for 5 intervals covering the 0..10 range
00244 
00245     H[0]  H[1]   H[2]   H[3]   H[4]   H[5]    H[6]
00246 -inf    0      2      4      6      8      10    +inf
00247 R[0]   R[1]   R[2]   R[3]   R[4]   R[5]   R[6]   R[7]
00248 
00249 */
00250 
00251 template <class ScalarType>
00252 void Histogram<ScalarType>::SetRange(ScalarType _minv, ScalarType _maxv, int _n, ScalarType gamma)
00253 {
00254   // reset data
00255   Clear();
00256 
00257   minv=_minv;maxv=_maxv;n=_n;
00258   H.resize(n+2);
00259   fill(H.begin(),H.end(),0);
00260   R.resize(n+3);
00261 
00262   R[0]   = - std::numeric_limits< ScalarType >::max();
00263   R[n+2] =   std::numeric_limits< ScalarType >::max();
00264 
00265   double delta=(maxv-minv);
00266   if(gamma==1)
00267   {
00268     for(int i=0; i<=n; ++i)
00269       R[i+1] = minv + delta*ScalarType(i)/n;
00270   }
00271   else
00272   {
00273     for(int i=0; i<=n; ++i)
00274       R[i+1] = minv + delta*pow(ScalarType(i)/n,gamma);
00275   }
00276 }
00277 
00278 
00279 
00280 template <class ScalarType>
00281 int Histogram<ScalarType>::BinIndex(ScalarType val)
00282 {
00283   // lower_bound returns the furthermost iterator i in [first, last) such that, for every iterator j in [first, i), *j < value.
00284   // E.g. An iterator pointing to the first element "not less than" val, or end() if every element is less than val.
00285   typename std::vector<ScalarType>::iterator it = lower_bound(R.begin(),R.end(),val);
00286 
00287   assert(it!=R.begin());
00288   assert(it!=R.end());
00289   assert((*it)>=val);
00290 
00291   int pos = it-R.begin();
00292   assert(pos >=1);
00293   pos -= 1;
00294   assert (R[pos] < val);
00295   assert (         val <= R[pos+1] );
00296   return pos;
00297 }
00298 
00299 /*
00300     H[0]  H[1]   H[2]   H[3]   H[4]   H[5]    H[6]
00301 -inf    0      2      4      6      8      10    +inf
00302 R[0]   R[1]   R[2]   R[3]   R[4]   R[5]   R[6]   R[7]
00303 
00304 asking for 3.14 lower bound will return an iterator pointing to R[3]==4; and will increase H[2]
00305 asking for 4    lower bound will return an iterator pointing to R[3]==4; and will increase H[2]
00306 
00307 */
00308 template <class ScalarType>
00309 void Histogram<ScalarType>::Add(ScalarType v, ScalarType increment)
00310 {
00311   int pos=BinIndex(v);
00312   if(v<minElem) minElem=v;
00313   if(v>maxElem) maxElem=v;
00314   assert((pos>=0)&&(pos<=n+1));
00315   H[pos]+=increment;
00316   cnt+=increment;
00317   sum+=v*increment;
00318   rms += (v*v)*increment;
00319 }
00320 
00321 template <class ScalarType>
00322 ScalarType Histogram<ScalarType>::BinCount(ScalarType v)
00323 {
00324   return H[BinIndex(v)];
00325 }
00326 
00327 template <class ScalarType>
00328 ScalarType Histogram<ScalarType>::BinCount(ScalarType v, ScalarType width)
00329 {
00330   return RangeCount(v-width/2.0,v+width/2.0);
00331 }
00332 
00333 template <class ScalarType>
00334 ScalarType Histogram<ScalarType>::RangeCount(ScalarType rangeMin, ScalarType rangeMax)
00335 {
00336   int firstBin=BinIndex(rangeMin);
00337   int lastBin=BinIndex (rangeMax);
00338   ScalarType sum=0;
00339   for(int i=firstBin; i<=lastBin;++i)
00340     sum+=H[i];
00341   return sum;
00342 }
00343 
00344 template <class ScalarType>
00345 ScalarType Histogram<ScalarType>::BinWidth(ScalarType v)
00346 {
00347   int pos=BinIndex(v);
00348   return R[pos+1]-R[pos];
00349 }
00350 
00351 template <class ScalarType>
00352 void Histogram<ScalarType>::FileWrite(const std::string &filename)
00353 {
00354   FILE *fp;
00355   fp=fopen(filename.c_str(),"w");
00356 
00357   for(unsigned int i=0; i<H.size(); i++)
00358     fprintf (fp,"%12.8lf , %12.8lf \n",R[i],double(H[i])/cnt);
00359 
00360   fclose(fp);
00361 }
00362 
00363 
00364 template <class ScalarType>
00365 ScalarType Histogram<ScalarType>::MaxCount() const
00366 {
00367   return *(std::max_element(H.begin(),H.end()));
00368 }
00369 
00370 template <class ScalarType>
00371 ScalarType Histogram<ScalarType>::MaxCountInRange() const
00372 {
00373   return *(std::max_element(H.begin()+1,H.end()-1));
00374 }
00375 
00376 // Return the scalar value <r> such that there are <frac> samples <= <r>.
00377 // E.g. Percentile(0.0) will return  R[1]   e.g. min value
00378 // E.g. Percentile(1.0) will return  R[n+1] e.g max value
00379 
00380 template <class ScalarType>
00381 ScalarType Histogram<ScalarType>::Percentile(ScalarType frac) const
00382 {
00383   if(H.size()==0 && R.size()==0)
00384     return 0;
00385 
00386   // check percentile range
00387   assert(frac >= 0 && frac <= 1);
00388 
00389   ScalarType sum=0,partsum=0;
00390   size_t i;
00391 
00392   // useless summation just to be sure
00393   for(i=0;i<H.size();i++) sum+=H[i];
00394   assert(sum==cnt);
00395 
00396   sum*=frac;
00397   for(i=0; i<H.size(); i++)
00398   {
00399     partsum+=H[i];
00400     if(partsum>=sum) break;
00401   }
00402 
00403   assert(i<H.size());
00404 
00405   return R[i+1];
00406 }
00407 
00408 typedef Histogram<double> Histogramd ;
00409 typedef Histogram<float> Histogramf ;
00410 
00411 } // end namespace (vcg)
00412 
00413 #endif  /* __VCG_HISTOGRAM */


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:31:42