contrib/brl/bbas/bsta/bsta_histogram.txx

Go to the documentation of this file.
00001 #ifndef bsta_histogram_txx_
00002 #define bsta_histogram_txx_
00003 //:
00004 // \file
00005 #include "bsta_histogram.h"
00006 
00007 #include <vcl_cmath.h> // for log()
00008 #include <vcl_iostream.h>
00009 #include <vcl_cassert.h>
00010 #include "bsta_gauss.h"
00011 #include <vnl/vnl_math.h> // for log2e == 1/vcl_log(2.0)
00012 
00013 template <class T>
00014 bsta_histogram<T>::bsta_histogram()
00015   : area_valid_(false), area_(0), nbins_(0), range_(0),
00016     delta_(0),min_prob_(0), min_(0), max_(0)
00017 {
00018   bsta_histogram_base::type_ = bsta_histogram_traits<T>::type();
00019 }
00020 
00021 template <class T>
00022 bsta_histogram<T>::bsta_histogram(const T range, const unsigned int nbins,
00023                                   const T min_prob)
00024   : area_valid_(false), area_(0), nbins_(nbins), range_(range),
00025     delta_(0),min_prob_(min_prob), min_(0), max_(range)
00026 {
00027   bsta_histogram_base::type_ = bsta_histogram_traits<T>::type();
00028   if (nbins>0)
00029   {
00030     delta_ = range_/nbins;
00031     counts_.resize(nbins, T(0));
00032   }
00033 }
00034 
00035 template <class T>
00036 bsta_histogram<T>::bsta_histogram(const T min, const T max,
00037                                   const unsigned int nbins,
00038                                   const T min_prob)
00039   : area_valid_(false), area_(0), nbins_(nbins), delta_(0),
00040     min_prob_(min_prob), min_ (min), max_(max)
00041 {
00042   bsta_histogram_base::type_ = bsta_histogram_traits<T>::type();
00043   if (nbins>0)
00044   {
00045     range_ = max-min;
00046     delta_ = range_/nbins;
00047     counts_.resize(nbins, T(0));
00048   }
00049   else
00050   {
00051     range_ = 0;
00052     delta_ = 0;
00053   }
00054 }
00055 
00056 template <class T>
00057 bsta_histogram<T>::bsta_histogram(const T min, const T max,
00058                                   vcl_vector<T> const& data, const T min_prob)
00059   : area_valid_(false), area_(0), delta_(0), min_prob_(min_prob),
00060     min_ (min), max_(max), counts_(data)
00061 {
00062   bsta_histogram_base::type_ = bsta_histogram_traits<T>::type();
00063   nbins_ = data.size();
00064   range_ = max-min;
00065   if (nbins_>0)
00066     delta_ = range_/nbins_;
00067   else
00068     delta_ = 0;
00069 }
00070 
00071 template <class T>
00072 void bsta_histogram<T>::upcount(T x, T mag)
00073 {
00074   if (x<min_||x>max_)
00075     return;
00076   for (unsigned int i = 0; i<nbins_; i++)
00077     if ((i+1)*delta_>=(x-min_))
00078     {
00079       counts_[i] += mag;
00080       break;
00081     }
00082   area_valid_ = false;
00083 }
00084 
00085 template <class T>
00086 void bsta_histogram<T>::compute_area() const
00087 {
00088   area_ =0;
00089   for (unsigned int i = 0; i<nbins_; i++)
00090     area_ += counts_[i];
00091   area_valid_ = true;
00092 }
00093 
00094 template <class T>
00095 T bsta_histogram<T>::p(unsigned int bin) const
00096 {
00097   if (bin>=nbins_)
00098     return 0;
00099   if (!area_valid_)
00100     compute_area();
00101   if (area_ == T(0))
00102     return 0;
00103   else
00104     return counts_[bin]/area_;
00105 }
00106 
00107 template <class T>
00108 T bsta_histogram<T>::p(const T val) const
00109 {
00110   if (val<min_||val>max_)
00111     return 0;
00112   if (!area_valid_)
00113     compute_area();
00114   if (area_ == T(0))
00115     return 0;
00116   else
00117     for (unsigned int i = 0; i<nbins_; i++)
00118       if ((i+1)*delta_>=(val-min_))
00119         return counts_[i]/area_;
00120 return 0;
00121 }
00122 
00123 template <class T>
00124 T bsta_histogram<T>::area() const
00125 {
00126   if (!area_valid_)
00127     compute_area();
00128   return area_;
00129 }
00130 
00131 //: Mean of distribution
00132 template <class T>
00133 T bsta_histogram<T>::mean() const
00134 {
00135   return mean(0, nbins_-1);
00136 }
00137 
00138   //: Mean of distribution between bin indices
00139 template <class T>
00140 T bsta_histogram<T>::mean(const unsigned int lowbin, const unsigned int highbin) const
00141 {
00142   assert(lowbin<=highbin);
00143   assert(highbin<nbins_);
00144   T sum = 0;
00145   T sumx = 0;
00146   for (unsigned i = lowbin; i<=highbin; ++i)
00147   {
00148     sum += counts_[i];
00149     sumx += (i*delta_ + min_)*counts_[i];
00150   }
00151   if (sum==0)
00152     return 0;
00153   T result = sumx/sum;
00154   return result;
00155 }
00156 
00157 template <class T>
00158 T bsta_histogram<T>::mean_vals(const T low, const T high) const
00159 {
00160   //find bin indices
00161   T tlow=low, thigh=high;
00162   if(tlow<min_) tlow = min_; if(thigh>max_) thigh = max_;
00163   unsigned low_bin=0, high_bin = 0;
00164   for (unsigned int i = 0; i<nbins_; i++)
00165     if ((i+1)*delta_>=(tlow-min_)){
00166       low_bin = i;
00167       break;
00168       }
00169   for (unsigned int i = 0; i<nbins_; i++)
00170     if ((i+1)*delta_>=(thigh-min_)){
00171       high_bin = i;
00172       break;
00173       }
00174   return this->mean(low_bin, high_bin);
00175 }
00176 
00177   //: Variance of distribution
00178 template <class T>
00179 T bsta_histogram<T>::variance() const
00180 {
00181   return variance(0, nbins_-1);
00182 }
00183 
00184   //: Variance of distribution between bin indices
00185 template <class T>
00186 T bsta_histogram<T>::
00187 variance(const unsigned int lowbin, const unsigned int highbin) const
00188 {
00189   assert(lowbin<=highbin);
00190   assert(highbin<nbins_);
00191   T mean = this->mean(lowbin, highbin);
00192   mean -= min_;
00193   T sum = 0;
00194   T sumx2 = 0;
00195   for (unsigned i = lowbin; i<=highbin; ++i)
00196   {
00197     sum += counts_[i];
00198     sumx2 += (i*delta_-mean)*(i*delta_-mean)*counts_[i];
00199   }
00200   if (sum==0)
00201     return 0;
00202   T result = sumx2/sum;
00203   return result;
00204 }
00205 
00206 template <class T>
00207 T bsta_histogram<T>::
00208 variance_vals(const T low, const T high) const
00209 {
00210 //find bin indices
00211   T tlow=low, thigh=high;
00212   if(tlow<min_) tlow = min_; if(thigh>max_) thigh = max_;
00213   unsigned low_bin=0, high_bin = 0;
00214   for (unsigned int i = 0; i<nbins_; i++)
00215     if ((i+1)*delta_>=(tlow-min_)){
00216       low_bin = i;
00217       break;
00218       }
00219   for (unsigned int i = 0; i<nbins_; i++)
00220     if ((i+1)*delta_>=(thigh-min_)){
00221       high_bin = i;
00222       break;
00223       }
00224     return this->variance(low_bin, high_bin);
00225 }
00226 template <class T>
00227 T bsta_histogram<T>::entropy() const
00228 {
00229   T ent = 0;
00230   for (unsigned int i = 0; i<nbins_; ++i)
00231   {
00232     T pi = this->p(i);
00233     if (pi>min_prob_)
00234       ent -= pi*T(vcl_log(pi));
00235   }
00236   ent *= (T)vnl_math::log2e;
00237   return ent;
00238 }
00239 
00240 template <class T>
00241 T bsta_histogram<T>::renyi_entropy() const
00242 {
00243   T sum = 0, ent = 0;
00244   for (unsigned int i = 0; i<nbins_; ++i)
00245   {
00246     T pi = this->p(i);
00247     sum += pi*pi;
00248   }
00249   if (sum>min_prob_)
00250     ent = - T(vcl_log(sum))*(T)vnl_math::log2e;
00251   return ent;
00252 }
00253 
00254 template <class T>
00255 void bsta_histogram<T>::parzen(const T sigma)
00256 {
00257   if (sigma<=0)
00258     return;
00259   double sd = (double)sigma;
00260   vcl_vector<double> in(nbins_), out(nbins_);
00261   for (unsigned int i=0; i<nbins_; i++)
00262     in[i]=counts_[i];
00263   bsta_gauss::bsta_1d_gaussian(sd, in, out);
00264   for (unsigned int i=0; i<nbins_; i++)
00265     counts_[i]=(T)out[i];
00266 }
00267 
00268 //The first non-zero bin starting at index = 0
00269 template <class T>
00270 unsigned bsta_histogram<T>::low_bin()
00271 {
00272   unsigned lowbin=0;
00273   for (; lowbin<nbins_&&counts_[lowbin]==0; ++lowbin) /*nothing*/;
00274   return lowbin;
00275 }
00276 
00277 //The first non-zero bin starting at index = nbins-1
00278 template <class T>
00279 unsigned bsta_histogram<T>::high_bin()
00280 {
00281   unsigned highbin=nbins_-1;
00282   for (; highbin>0&&counts_[highbin]==0; --highbin) /*nothing*/;
00283   return highbin;
00284 }
00285 
00286 // Fraction of area less than value
00287 template <class T>
00288 T bsta_histogram<T>::fraction_below(const T value) const
00289 {
00290  if (value<min_||value>max_)
00291     return 0;
00292   if (!area_valid_)
00293     compute_area();
00294   if (area_ == T(0))
00295     return 0;
00296   T sum = 0, limit=(value-min_);
00297   for (unsigned int i = 0; i<nbins_; i++)
00298     if ((i+1)*delta_<limit)
00299       sum+=counts_[i];
00300     else
00301       return sum/area_;
00302  return 0;
00303 }
00304 
00305 // Fraction of area greater than value
00306 template <class T>
00307 T bsta_histogram<T>::fraction_above(const T value) const
00308 {
00309  if (value<min_||value>max_)
00310     return 0;
00311   if (!area_valid_)
00312     compute_area();
00313   if (area_ == T(0))
00314     return 0;
00315   T sum = 0, limit=(value-min_);
00316   for (unsigned int i = 0; i<nbins_; i++)
00317     if ((i+1)*delta_>limit)
00318       sum+=counts_[i];
00319   return sum/area_;
00320 }
00321 
00322 // Value for area fraction below value
00323 template <class T>
00324 T bsta_histogram<T>::value_with_area_below(const T area_fraction) const
00325 {
00326   if (area_fraction>T(1))
00327     return 0;
00328   if (!area_valid_)
00329     compute_area();
00330   if (area_ == T(0))
00331     return 0;
00332   T sum = 0;
00333   for (unsigned int i=0; i<nbins_; i++)
00334   {
00335     sum += counts_[i];
00336     if (sum>=area_fraction*area_)
00337       return (i+1)*delta_+min_;
00338   }
00339   return 0;
00340 }
00341 
00342 // Value for area fraction above value
00343 template <class T>
00344 T  bsta_histogram<T>::value_with_area_above(const T area_fraction) const
00345 {
00346   if (area_fraction>T(1))
00347     return 0;
00348   if (!area_valid_)
00349     compute_area();
00350   if (area_ == T(0))
00351     return 0;
00352   T sum = 0;
00353   for (unsigned int i=nbins_-1; i!=0; i--)
00354   {
00355     sum += counts_[i];
00356     if (sum>area_fraction*area_)
00357       return (i+1)*delta_+min_;
00358   }
00359   return 0;
00360 }
00361 
00362 template <class T>
00363 void bsta_histogram<T>::print(vcl_ostream& os) const
00364 {
00365   for (unsigned int i=0; i<nbins_; i++)
00366     if (p(i) > 0)
00367       os << "p[" << i << "]=" << p(i) << '\n';
00368 }
00369 
00370 //: print as a matlab plot command
00371 template <class T>
00372 void bsta_histogram<T>::print_to_m(vcl_ostream& os) const
00373 {
00374   os << "x = [" << min_;
00375   for (unsigned int i=1; i<nbins_; i++)
00376     os << ", " << min_ + i*delta_;
00377   os << "];\n";
00378   os << "y = [" << p((unsigned int)0);
00379   for (unsigned int i=1; i<nbins_; i++)
00380     os << ", " << p(i);
00381   os << "];\n";
00382   os << "bar(x,y,'r')\n";
00383 }
00384 
00385 template <class T>
00386 void bsta_histogram<T>::print_vals_prob(vcl_ostream& os) const
00387 {
00388   for(unsigned i = 0; i<nbins_; ++i)
00389     os << avg_bin_value(i) << ' ' << p(i) << '\n';
00390 }
00391 
00392 template <class T>
00393 vcl_ostream& bsta_histogram<T>::write(vcl_ostream& s) const
00394 {
00395   s << area_valid_ << ' '
00396     << area_ << ' '
00397     << nbins_ << ' '
00398     << range_ << ' '
00399     << delta_ << ' '
00400     << min_prob_ << ' '
00401     << min_ << ' '
00402     << max_ << ' ';
00403   for (unsigned i = 0; i < counts_.size() ; i++)
00404     s << counts_[i] << ' ';
00405 
00406   return  s << '\n';
00407 }
00408 
00409 template <class T>
00410 vcl_istream& bsta_histogram<T>::read(vcl_istream& s)
00411 {
00412   s >> area_valid_
00413     >> area_
00414     >> nbins_
00415     >> range_
00416     >> delta_
00417     >> min_prob_
00418     >> min_
00419     >> max_;
00420   counts_.resize(nbins_);
00421   for (unsigned i = 0; i < counts_.size() ; i++)
00422     s >> counts_[i] ;
00423   return  s;
00424 }
00425 
00426 //: Write to stream
00427 template <class T>
00428 vcl_ostream& operator<<(vcl_ostream& s, bsta_histogram<T> const& h)
00429 {
00430   return h.write(s);
00431 }
00432 
00433 //: Read from stream
00434 template <class T>
00435 vcl_istream& operator>>(vcl_istream& is, bsta_histogram<T>& h)
00436 {
00437   return h.read(is);
00438 }
00439 
00440 
00441 #undef BSTA_HISTOGRAM_INSTANTIATE
00442 #define BSTA_HISTOGRAM_INSTANTIATE(T) \
00443 template class bsta_histogram<T >;\
00444 template vcl_istream& operator>>(vcl_istream&, bsta_histogram<T >&);\
00445 template vcl_ostream& operator<<(vcl_ostream&, bsta_histogram<T > const&)
00446 
00447 #endif // bsta_histogram_txx_

Generated on Mon Mar 8 05:30:33 2010 for contrib/brl/bbas/bsta by  doxygen 1.5.1