00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 #ifndef __VCG_HISTOGRAM
00088 #define __VCG_HISTOGRAM
00089
00090 #include <vector>
00091 #include <algorithm>
00092 #include <assert.h>
00093 #include <string>
00094 #include <limits>
00095 #include <vcg/math/base.h>
00096 #include <stdio.h>
00097
00098 namespace vcg {
00099
00100 template <class ScalarType>
00101 class Distribution
00102 {
00103 private:
00104 std::vector<ScalarType> vec;
00105 bool dirty;
00106 double valSum;
00107 double sqrdValSum;
00108 double avg;
00109 double sqrdAvg;
00110 double rms;
00111 double min_v;
00112 double max_v;
00113
00114
00115 public:
00116
00117 Distribution() { Clear(); }
00118
00119 void Clear()
00120 {
00121 vec.clear();
00122 dirty=true;
00123 min_v = std::numeric_limits<float>::max();
00124 max_v = -std::numeric_limits<float>::max();
00125 }
00126
00127 void Add(const ScalarType v)
00128 {
00129 vec.push_back(v);
00130 dirty=true;
00131 if(v<min_v) min_v=v;
00132 if(v>max_v) max_v=v;
00133 }
00134
00135 ScalarType Min() { return min_v; }
00136 ScalarType Max() { return max_v; }
00137
00138 ScalarType Avg(){ DirtyCheck(); return avg;}
00140 ScalarType RMS(){ DirtyCheck(); return rms;}
00141
00143
00144 ScalarType Variance(){ DirtyCheck(); return sqrdAvg - avg*avg ;}
00145
00147 ScalarType StandardDeviation(){ DirtyCheck(); return sqrt( Variance() );}
00148 void DirtyCheck()
00149 {
00150 if(!dirty) return;
00151 std::sort(vec.begin(),vec.end());
00152 valSum=0;
00153 sqrdValSum=0;
00154 typename std::vector<ScalarType>::iterator vi;
00155 for(vi=vec.begin();vi!=vec.end();++vi)
00156 {
00157 valSum += double(*vi);
00158 sqrdValSum += double(*vi)*double(*vi);
00159 }
00160 avg = valSum/double(vec.size());
00161 sqrdAvg = sqrdValSum/double(vec.size());
00162 rms = math::Sqrt(sqrdAvg);
00163 dirty=false;
00164 }
00165
00166 ScalarType Percentile(ScalarType perc)
00167 {
00168 assert(perc>=0 && perc<=1);
00169 DirtyCheck();
00170 int index = vec.size() *perc -1;
00171
00172 if(index< 0 ) index = 0;
00173
00174 return vec[index];
00175 }
00176 };
00177
00178
00179
00185 template <class ScalarType>
00186 class Histogram
00187 {
00188
00189
00190 private:
00191
00192 std::vector <int> H;
00193 std::vector <ScalarType> R;
00194 ScalarType minv;
00195 ScalarType maxv;
00196 int n;
00197
00198
00200 int cnt;
00201 ScalarType avg;
00202 ScalarType rms;
00203
00207 int BinIndex(ScalarType val) ;
00208
00209
00210 public:
00211
00222 void SetRange(ScalarType _minv, ScalarType _maxv, int _n,ScalarType gamma=1.0 );
00223
00224 ScalarType MinV() {return minv;};
00225 ScalarType MaxV() {return maxv;};
00226
00227
00228
00235 void Add(ScalarType v);
00236
00237 int MaxCount() const;
00238 int BinCount(ScalarType v);
00239 int BinCountInd(int index) {return H[index];}
00240 int BinCount(ScalarType v, ScalarType width);
00241 ScalarType BinLowerBound(int index) {return R[index];}
00242 ScalarType BinUpperBound(int index) {return R[index+1];};
00243 int RangeCount(ScalarType rangeMin, ScalarType rangeMax);
00244 ScalarType BinWidth(ScalarType v);
00245
00251 ScalarType Percentile(ScalarType frac) const;
00252
00254 ScalarType Avg(){ return avg/cnt;}
00255
00257 ScalarType RMS(){ return sqrt(rms/double(cnt));}
00258
00260 ScalarType Variance(){ return fabs(rms/cnt-Avg()*Avg());}
00261
00263 ScalarType StandardDeviation(){ return sqrt(Variance());}
00264
00266 void FileWrite(const std::string &filename);
00267
00269 void Clear();
00270 };
00271
00272 template <class ScalarType>
00273 void Histogram<ScalarType>::Clear()
00274 {
00275 H.clear();
00276 R.clear();
00277 cnt=0;
00278 avg=0;
00279 rms=0;
00280 n=0;
00281 minv=0;
00282 maxv=1;
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 template <class ScalarType>
00303 void Histogram<ScalarType>::SetRange(ScalarType _minv, ScalarType _maxv, int _n, ScalarType gamma)
00304 {
00305
00306 Clear();
00307
00308 minv=_minv;maxv=_maxv;n=_n;
00309 H.resize(n+2);
00310 fill(H.begin(),H.end(),0);
00311 R.resize(n+3);
00312
00313 R[0] = - std::numeric_limits< ScalarType >::max();
00314 R[n+2] = std::numeric_limits< ScalarType >::max();
00315
00316 double delta=(maxv-minv);
00317 if(gamma==1)
00318 {
00319 for(int i=0; i<=n; ++i)
00320 R[i+1] = minv + delta*ScalarType(i)/n;
00321 }
00322 else
00323 {
00324 for(int i=0; i<=n; ++i)
00325 R[i+1] = minv + delta*pow(ScalarType(i)/n,gamma);
00326 }
00327 }
00328
00329
00330
00331 template <class ScalarType>
00332 int Histogram<ScalarType>::BinIndex(ScalarType val)
00333 {
00334
00335
00336 typename std::vector<ScalarType>::iterator it = lower_bound(R.begin(),R.end(),val);
00337
00338 assert(it!=R.begin());
00339 assert(it!=R.end());
00340 assert((*it)>=val);
00341
00342 int pos = it-R.begin();
00343 assert(pos >=1);
00344 pos -= 1;
00345 assert (R[pos] < val);
00346 assert ( val <= R[pos+1] );
00347 return pos;
00348 }
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 template <class ScalarType>
00360 void Histogram<ScalarType>::Add(ScalarType v)
00361 {
00362 int pos=BinIndex(v);
00363 if(pos>=0 && pos<=n)
00364 {
00365 ++H[pos];
00366 ++cnt;
00367 avg+=v;
00368 rms += v*v;
00369 }
00370 }
00371
00372 template <class ScalarType>
00373 int Histogram<ScalarType>::BinCount(ScalarType v)
00374 {
00375 return H[BinIndex(v)];
00376 }
00377
00378 template <class ScalarType>
00379 int Histogram<ScalarType>::BinCount(ScalarType v, ScalarType width)
00380 {
00381 return RangeCount(v-width/2.0,v+width/2.0);
00382 }
00383
00384 template <class ScalarType>
00385 int Histogram<ScalarType>::RangeCount(ScalarType rangeMin, ScalarType rangeMax)
00386 {
00387 int firstBin=BinIndex(rangeMin);
00388 int lastBin=BinIndex (rangeMax);
00389 int sum=0;
00390 for(int i=firstBin; i<=lastBin;++i)
00391 sum+=H[i];
00392 return sum;
00393 }
00394
00395 template <class ScalarType>
00396 ScalarType Histogram<ScalarType>::BinWidth(ScalarType v)
00397 {
00398 int pos=BinIndex(v);
00399 return R[pos+1]-R[pos];
00400 }
00401
00402 template <class ScalarType>
00403 void Histogram<ScalarType>::FileWrite(const std::string &filename)
00404 {
00405 FILE *fp;
00406 fp=fopen(filename.c_str(),"w");
00407
00408 for(unsigned int i=0; i<H.size(); i++)
00409 fprintf (fp,"%12.8lf , %12.8lf \n",R[i],double(H[i])/cnt);
00410
00411 fclose(fp);
00412 }
00413
00414
00415 template <class ScalarType>
00416 int Histogram<ScalarType>::MaxCount() const
00417 {
00418 return *(std::max_element(H.begin(),H.end()));
00419 }
00420
00421
00422
00423
00424
00425 template <class ScalarType>
00426 ScalarType Histogram<ScalarType>::Percentile(ScalarType frac) const
00427 {
00428 if(H.size()==0 && R.size()==0)
00429 return 0;
00430
00431
00432 assert(frac >= 0 && frac <= 1);
00433
00434 ScalarType sum=0,partsum=0;
00435 size_t i;
00436
00437
00438 for(i=0;i<H.size();i++) sum+=H[i];
00439 assert(sum==cnt);
00440
00441 sum*=frac;
00442 for(i=0; i<H.size(); i++)
00443 {
00444 partsum+=H[i];
00445 if(partsum>=sum) break;
00446 }
00447
00448 assert(i<H.size());
00449
00450 return R[i+1];
00451 }
00452
00453 typedef Histogram<double> Histogramd ;
00454 typedef Histogram<float> Histogramf ;
00455
00456 }
00457
00458 #endif