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 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
00132 template <class T>
00133 T bsta_histogram<T>::mean() const
00134 {
00135 return mean(0, nbins_-1);
00136 }
00137
00138
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
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
00178 template <class T>
00179 T bsta_histogram<T>::variance() const
00180 {
00181 return variance(0, nbins_-1);
00182 }
00183
00184
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
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
00269 template <class T>
00270 unsigned bsta_histogram<T>::low_bin()
00271 {
00272 unsigned lowbin=0;
00273 for (; lowbin<nbins_&&counts_[lowbin]==0; ++lowbin) ;
00274 return lowbin;
00275 }
00276
00277
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) ;
00283 return highbin;
00284 }
00285
00286
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
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
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
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
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
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
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_