00001 #ifndef bsta_histogram_txx_
00002 #define bsta_histogram_txx_
00003
00004
00005 #include "bsta_histogram.h"
00006
00007 #include <vcl_cmath.h>
00008 #include <vcl_iostream.h>
00009 #include <vcl_cassert.h>
00010 #include "bsta_gauss.h"
00011 #include <vnl/vnl_math.h>
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 unsigned int nbins, const T min, const T delta,
00058 const T min_prob)
00059 : area_valid_(false), area_(0), nbins_(nbins), delta_(delta),
00060 min_prob_(min_prob), min_(min), max_(min+nbins*delta)
00061 {
00062 bsta_histogram_base::type_ = bsta_histogram_traits<T>::type();
00063 if (nbins>0)
00064 {
00065 range_ = max_-min_;
00066 counts_.resize(nbins, T(0));
00067 }
00068 else
00069 range_ = 0;
00070 }
00071
00072 template <class T>
00073 bsta_histogram<T>::bsta_histogram(const T min, const T max,
00074 vcl_vector<T> const& data, const T min_prob)
00075 : area_valid_(false), area_(0), delta_(0), min_prob_(min_prob),
00076 min_(min), max_(max), counts_(data)
00077 {
00078 bsta_histogram_base::type_ = bsta_histogram_traits<T>::type();
00079 nbins_ = data.size();
00080 range_ = max-min;
00081 if (nbins_>0)
00082 delta_ = range_/nbins_;
00083 else
00084 delta_ = 0;
00085 }
00086
00087 template <class T>
00088 void bsta_histogram<T>::upcount(T x, T mag)
00089 {
00090 if (x<min_||x>max_)
00091 return;
00092 for (unsigned int i = 0; i<nbins_; ++i)
00093 if (T((i+1)*delta_) + min_ >= x)
00094 {
00095 counts_[i] += mag;
00096 break;
00097 }
00098 area_valid_ = false;
00099 }
00100
00101 template <class T>
00102
00103 int bsta_histogram<T>::bin_at_val(T x)
00104 {
00105 if (x<min_||x>max_)
00106 return -1;
00107 for (unsigned int i = 0; i<nbins_; ++i)
00108 if (T((i+1)*delta_) + min_ >= x)
00109 {
00110 return i;
00111 }
00112 return -1;
00113 }
00114
00115 template <class T>
00116 void bsta_histogram<T>::compute_area() const
00117 {
00118 area_ =0;
00119 for (unsigned int i = 0; i<nbins_; ++i)
00120 area_ += counts_[i];
00121 area_valid_ = true;
00122 }
00123
00124 template <class T>
00125 T bsta_histogram<T>::cumulative_area(unsigned bin) const
00126 {
00127 T area =0;
00128 for (unsigned int i = 0; i<bin; ++i)
00129 area += counts_[i];
00130 return area;
00131 }
00132
00133 template <class T>
00134 T bsta_histogram<T>::p(unsigned int bin) const
00135 {
00136 if (bin>=nbins_)
00137 return 0;
00138 if (!area_valid_)
00139 compute_area();
00140 if (area_ == T(0))
00141 return 0;
00142 else
00143 return counts_[bin]/area_;
00144 }
00145
00146 template <class T>
00147 T bsta_histogram<T>::p(const T val) const
00148 {
00149 if (val<min_||val>max_)
00150 return 0;
00151 if (!area_valid_)
00152 compute_area();
00153 if (area_ == T(0))
00154 return 0;
00155 else
00156 for (unsigned int i = 0; i<nbins_; ++i)
00157 if (T((i+1)*delta_) + min_ >= val)
00158 return counts_[i]/area_;
00159 return 0;
00160 }
00161
00162 template <class T>
00163 T bsta_histogram<T>::area() const
00164 {
00165 if (!area_valid_)
00166 compute_area();
00167 return area_;
00168 }
00169
00170
00171 template <class T>
00172 T bsta_histogram<T>::mean() const
00173 {
00174 return mean(0, nbins_-1);
00175 }
00176
00177
00178 template <class T>
00179 T bsta_histogram<T>::mean(const unsigned int lowbin, const unsigned int highbin) const
00180 {
00181 assert(lowbin<=highbin);
00182 assert(highbin<nbins_);
00183 T sum = 0;
00184 T sumx = 0;
00185 for (unsigned i = lowbin; i<=highbin; ++i)
00186 {
00187 sum += counts_[i];
00188 sumx += (i*delta_ + min_)*counts_[i];
00189 }
00190 if (sum==0)
00191 return 0;
00192 T result = sumx/sum;
00193 return result;
00194 }
00195
00196 template <class T>
00197 T bsta_histogram<T>::mean_vals(const T low, const T high) const
00198 {
00199
00200 T tlow=low, thigh=high;
00201 if (tlow<min_) tlow = min_;
00202 if (thigh>max_) thigh = max_;
00203 unsigned low_bin=0, high_bin = 0;
00204 for (unsigned int i = 0; i<nbins_; ++i)
00205 if (T((i+1)*delta_) + min_ >= tlow) {
00206 low_bin = i;
00207 break;
00208 }
00209 for (unsigned int i = 0; i<nbins_; ++i)
00210 if (T((i+1)*delta_) + min_ >= thigh) {
00211 high_bin = i;
00212 break;
00213 }
00214 return this->mean(low_bin, high_bin);
00215 }
00216
00217
00218 template <class T>
00219 T bsta_histogram<T>::variance() const
00220 {
00221 return variance(0, nbins_-1);
00222 }
00223
00224
00225 template <class T>
00226 T bsta_histogram<T>::
00227 variance(const unsigned int lowbin, const unsigned int highbin) const
00228 {
00229 assert(lowbin<=highbin);
00230 assert(highbin<nbins_);
00231 T mean = this->mean(lowbin, highbin);
00232 mean -= min_;
00233 T sum = 0;
00234 T sumx2 = 0;
00235 for (unsigned i = lowbin; i<=highbin; ++i)
00236 {
00237 sum += counts_[i];
00238 sumx2 += (i*delta_-mean)*(i*delta_-mean)*counts_[i];
00239 }
00240 if (sum==0)
00241 return 0;
00242 else
00243 return sumx2/sum;
00244 }
00245
00246 template <class T>
00247 T bsta_histogram<T>::
00248 variance_vals(const T low, const T high) const
00249 {
00250
00251 T tlow=low, thigh=high;
00252 if (tlow<min_) tlow = min_;
00253 if (thigh>max_) thigh = max_;
00254 unsigned low_bin=0, high_bin = 0;
00255 for (unsigned int i = 0; i<nbins_; ++i)
00256 if (T((i+1)*delta_) + min_ >= tlow) {
00257 low_bin = i;
00258 break;
00259 }
00260 for (unsigned int i = 0; i<nbins_; ++i)
00261 if (T((i+1)*delta_) + min_ >= thigh) {
00262 high_bin = i;
00263 break;
00264 }
00265 return this->variance(low_bin, high_bin);
00266 }
00267
00268 template <class T>
00269 T bsta_histogram<T>::entropy() const
00270 {
00271 double ent = 0;
00272 for (unsigned int i = 0; i<nbins_; ++i)
00273 {
00274 double pi = this->p(i);
00275 if (pi>min_prob_)
00276 ent -= pi*vcl_log(pi);
00277 }
00278 ent *= vnl_math::log2e;
00279 return T(ent);
00280 }
00281
00282 template <class T>
00283 T bsta_histogram<T>::renyi_entropy() const
00284 {
00285 double sum = 0, ent = 0;
00286 for (unsigned int i = 0; i<nbins_; ++i)
00287 {
00288 double pi = this->p(i);
00289 sum += pi*pi;
00290 }
00291 if (sum>min_prob_)
00292 ent = - vcl_log(sum)*vnl_math::log2e;
00293 return T(ent);
00294 }
00295
00296 template <class T>
00297 void bsta_histogram<T>::parzen(const T sigma)
00298 {
00299 if (sigma<=0)
00300 return;
00301 double sd = (double)sigma;
00302 vcl_vector<double> in(nbins_), out(nbins_);
00303 for (unsigned int i=0; i<nbins_; ++i)
00304 in[i]=counts_[i];
00305 bsta_gauss::bsta_1d_gaussian(sd, in, out);
00306 for (unsigned int i=0; i<nbins_; ++i)
00307 counts_[i]=(T)out[i];
00308 }
00309
00310
00311 template <class T>
00312 unsigned bsta_histogram<T>::low_bin()
00313 {
00314 unsigned lowbin=0;
00315 for (; lowbin<nbins_&&counts_[lowbin]==0; ++lowbin) ;
00316 return lowbin;
00317 }
00318
00319
00320 template <class T>
00321 unsigned bsta_histogram<T>::high_bin()
00322 {
00323 unsigned highbin=nbins_-1;
00324 for (; highbin>0&&counts_[highbin]==0; --highbin) ;
00325 return highbin;
00326 }
00327
00328
00329 template <class T>
00330 T bsta_histogram<T>::fraction_below(const T value) const
00331 {
00332 if (value<min_||value>max_)
00333 return 0;
00334 if (!area_valid_)
00335 compute_area();
00336 if (area_ == T(0))
00337 return 0;
00338 T sum = 0, limit=(value-min_);
00339 for (unsigned int i = 0; i<nbins_; ++i)
00340 if (T((i+1)*delta_)<limit)
00341 sum+=counts_[i];
00342 else
00343 return sum/area_;
00344 return 0;
00345 }
00346
00347
00348 template <class T>
00349 T bsta_histogram<T>::fraction_above(const T value) const
00350 {
00351 if (value<min_||value>max_)
00352 return 0;
00353 if (!area_valid_)
00354 compute_area();
00355 if (area_ == T(0))
00356 return 0;
00357 T sum = 0, limit=(value-min_);
00358 for (unsigned int i = 0; i<nbins_; ++i)
00359 if (T((i+1)*delta_)>limit)
00360 sum+=counts_[i];
00361 return sum/area_;
00362 }
00363
00364
00365 template <class T>
00366 T bsta_histogram<T>::value_with_area_below(const T area_fraction) const
00367 {
00368 if (area_fraction>T(1))
00369 return 0;
00370 if (!area_valid_)
00371 compute_area();
00372 if (area_ == T(0))
00373 return 0;
00374 T sum = 0;
00375 for (unsigned int i=0; i<nbins_; ++i)
00376 {
00377 sum += counts_[i];
00378 if (sum>=area_fraction*area_)
00379 return (i+1)*delta_+min_;
00380 }
00381 return 0;
00382 }
00383
00384
00385 template <class T>
00386 T bsta_histogram<T>::value_with_area_above(const T area_fraction) const
00387 {
00388 if (area_fraction>T(1))
00389 return 0;
00390 if (!area_valid_)
00391 compute_area();
00392 if (area_ == T(0))
00393 return 0;
00394 T sum = 0;
00395 for (unsigned int i=nbins_-1; i!=0; i--)
00396 {
00397 sum += counts_[i];
00398 if (sum>area_fraction*area_)
00399 return (i+1)*delta_+min_;
00400 }
00401 return 0;
00402 }
00403
00404
00405 template <class T>
00406 void bsta_histogram<T>::clear()
00407 {
00408 area_valid_ = false;
00409 area_ = T(0);
00410 counts_.assign(nbins_,T(0));
00411 }
00412
00413 template <class T>
00414 void bsta_histogram<T>::print(vcl_ostream& os) const
00415 {
00416 for (unsigned int i=0; i<nbins_; ++i)
00417 if (p(i) > 0)
00418 os << "p[" << i << "]=" << p(i) << '\n';
00419 }
00420
00421 template <class T>
00422 void bsta_histogram<T>::pretty_print(vcl_ostream& os) const
00423 {
00424 os << "area valid: " << area_valid_ << '\n'
00425 << "area: " << area_ << '\n'
00426 << "number of bins: " << nbins_ << '\n'
00427 << "range: " << range_ << '\n'
00428 << "delta: " << delta_ << '\n'
00429 << "min_prob: " << min_prob_ << '\n'
00430 << "min: " << min_ << '\n'
00431 << "max: " << max_ << '\n'
00432 << "counts: ";
00433 for (unsigned i = 0; i < counts_.size() ; ++i)
00434 os << counts_[i] << ' ';
00435 os << '\n';
00436 }
00437
00438
00439 template <class T>
00440 void bsta_histogram<T>::print_to_m(vcl_ostream& os) const
00441 {
00442 os << "x = [" << min_;
00443 for (unsigned int i=1; i<nbins_; ++i)
00444 os << ", " << min_ + i*delta_;
00445 os << "];\n"
00446 << "y = [" << p((unsigned int)0);
00447 for (unsigned int i=1; i<nbins_; ++i)
00448 os << ", " << p(i);
00449 os << "];\n"
00450 << "bar(x,y,'r')\n";
00451 }
00452
00453
00454 template <class T>
00455 void bsta_histogram<T>::print_to_arrays(vcl_ostream& os) const
00456 {
00457 os << min_;
00458 for (unsigned int i=1; i<nbins_; ++i)
00459 os << ", " << min_ + i*delta_;
00460 os << '\n'
00461 << p((unsigned int)0);
00462 for (unsigned int i=1; i<nbins_; ++i)
00463 os << ", " << p(i);
00464 os << '\n';
00465 }
00466
00467 template <class T>
00468 void bsta_histogram<T>::print_vals_prob(vcl_ostream& os) const
00469 {
00470 for (unsigned i = 0; i<nbins_; ++i)
00471 os << avg_bin_value(i) << ' ' << p(i) << '\n';
00472 }
00473
00474 template <class T>
00475 vcl_ostream& bsta_histogram<T>::write(vcl_ostream& s) const
00476 {
00477 s << area_valid_ << ' '
00478 << area_ << ' '
00479 << nbins_ << ' '
00480 << range_ << ' '
00481 << delta_ << ' '
00482 << min_prob_ << ' '
00483 << min_ << ' '
00484 << max_ << ' ';
00485 for (unsigned i = 0; i < counts_.size() ; ++i)
00486 s << counts_[i] << ' ';
00487
00488 return s << '\n';
00489 }
00490
00491 template <class T>
00492 vcl_istream& bsta_histogram<T>::read(vcl_istream& s)
00493 {
00494 s >> area_valid_
00495 >> area_
00496 >> nbins_
00497 >> range_
00498 >> delta_
00499 >> min_prob_
00500 >> min_
00501 >> max_;
00502 counts_.resize(nbins_);
00503 for (unsigned i = 0; i < counts_.size() ; ++i)
00504 s >> counts_[i] ;
00505 return s;
00506 }
00507
00508
00509 template <class T>
00510 vcl_ostream& operator<<(vcl_ostream& s, bsta_histogram<T> const& h)
00511 {
00512 return h.write(s);
00513 }
00514
00515
00516 template <class T>
00517 vcl_istream& operator>>(vcl_istream& is, bsta_histogram<T>& h)
00518 {
00519 return h.read(is);
00520 }
00521
00522
00523 #undef BSTA_HISTOGRAM_INSTANTIATE
00524 #define BSTA_HISTOGRAM_INSTANTIATE(T) \
00525 template class bsta_histogram<T >;\
00526 template vcl_istream& operator>>(vcl_istream&, bsta_histogram<T >&);\
00527 template vcl_ostream& operator<<(vcl_ostream&, bsta_histogram<T > const&)
00528
00529 #endif // bsta_histogram_txx_