00001 #ifndef bsta_joint_histogram_txx_
00002 #define bsta_joint_histogram_txx_
00003
00004
00005 #include "bsta_joint_histogram.h"
00006
00007 #include <vcl_cmath.h>
00008 #include <vcl_iostream.h>
00009 #include "bsta_gauss.h"
00010 #include <vnl/vnl_math.h>
00011 template <class T>
00012 bsta_joint_histogram<T>::bsta_joint_histogram()
00013 : volume_valid_(false), volume_(0),
00014 nbins_a_(1), nbins_b_(1),
00015 range_a_(0), range_b_(0),
00016 delta_a_(0), delta_b_(0),
00017 min_a_(0), max_a_(0),
00018 min_b_(0), max_b_(0),
00019 min_prob_(0),
00020 counts_(1, 1, T(0))
00021 {
00022 }
00023
00024 template <class T>
00025 bsta_joint_histogram<T>::bsta_joint_histogram(const T range,
00026 const unsigned int nbins,
00027 const T min_prob)
00028 : volume_valid_(false), volume_(0), nbins_a_(nbins), nbins_b_(nbins),
00029 range_a_(range), range_b_(range),delta_a_(0),delta_b_(0), min_a_(0),
00030 max_a_(range), min_b_(0), max_b_(range), min_prob_(min_prob),
00031 counts_(nbins, nbins, T(0))
00032 {
00033 if (nbins_a_>0&&nbins_b_>0)
00034 {
00035 delta_a_ = range_a_/nbins_a_;
00036 delta_b_ = range_b_/nbins_b_;
00037 }
00038 }
00039
00040 template <class T>
00041 bsta_joint_histogram<T>::bsta_joint_histogram(const T range_a,
00042 const unsigned int nbins_a,
00043 const T range_b,
00044 const unsigned int nbins_b,
00045 const T min_prob)
00046 : volume_valid_(false), volume_(0), nbins_a_(nbins_a), nbins_b_(nbins_b),
00047 range_a_(range_a), range_b_(range_b),delta_a_(0),delta_b_(0),min_a_(0),
00048 max_a_(range_a), min_b_(0), max_b_(range_b), min_prob_(min_prob),
00049 counts_(nbins_a, nbins_b, T(0))
00050 {
00051 if (nbins_a_>0&&nbins_b_>0)
00052 {
00053 delta_a_ = range_a_/nbins_a_;
00054 delta_b_ = range_b_/nbins_b_;
00055 }
00056 }
00057
00058 template <class T>
00059 bsta_joint_histogram<T>::bsta_joint_histogram(const T min_a, const T max_a,
00060 const unsigned int nbins_a,
00061 const T min_b, const T max_b,
00062 const unsigned int nbins_b,
00063 const T min_prob)
00064 : volume_valid_(false), volume_(0), nbins_a_(nbins_a), nbins_b_(nbins_b),
00065 min_a_(min_a), max_a_(max_a), min_b_(min_b), max_b_(max_b),
00066 min_prob_(min_prob), counts_(nbins_a, nbins_b, T(0))
00067 {
00068 if (nbins_a>0) {
00069 range_a_ = max_a-min_a;
00070 delta_a_ = range_a_/nbins_a;
00071 }
00072 else {
00073 range_a_ = 0;
00074 delta_a_ = 0;
00075 }
00076 if (nbins_b>0) {
00077 range_b_ = max_b-min_b;
00078 delta_b_ = range_b_/nbins_b;
00079 }
00080 else {
00081 range_b_ = 0;
00082 delta_b_ = 0;
00083 }
00084 }
00085
00086 template <class T>
00087 void bsta_joint_histogram<T>::upcount(T a, T mag_a,
00088 T b, T mag_b)
00089 {
00090 if (a<min_a_||a>max_a_)
00091 return;
00092 if (b<min_b_||b>max_b_)
00093 return;
00094 int bin_a =0, bin_b = 0;
00095 for (unsigned int i = 0; i<nbins_a_; i++)
00096 if ((i+1)*delta_a_>=(a-min_a_))
00097 {
00098 bin_a = i;
00099 break;
00100 }
00101 for (unsigned int i = 0; i<nbins_b_; i++)
00102 if ((i+1)*delta_b_>=(b-min_b_))
00103 {
00104 bin_b = i;
00105 break;
00106 }
00107 T v = counts_[bin_a][bin_b]+ mag_a + mag_b;
00108 counts_.put(bin_a, bin_b, v);
00109 volume_valid_ = false;
00110 }
00111
00112 template <class T>
00113 void bsta_joint_histogram<T>::compute_volume() const
00114 {
00115 volume_=0;
00116 for (unsigned int a = 0; a<nbins_a_; a++)
00117 for (unsigned int b =0; b<nbins_b_; b++)
00118 volume_ += counts_[a][b];
00119 volume_valid_ = true;
00120 }
00121
00122 template <class T>
00123 T bsta_joint_histogram<T>::p(unsigned int a, unsigned int b) const
00124 {
00125 if (a>=nbins_a_)
00126 return 0;
00127 if (b>=nbins_b_)
00128 return 0;
00129 if (!volume_valid_)
00130 compute_volume();
00131 if (volume_ == T(0))
00132 return 0;
00133 else
00134 return counts_[a][b]/volume_;
00135 }
00136
00137 template <class T>
00138 T bsta_joint_histogram<T>::p(T a, T b) const
00139 {
00140 if (a<min_a_||a>max_a_)
00141 return 0;
00142 if (b<min_b_||b>max_b_)
00143 return 0;
00144 if (!volume_valid_)
00145 compute_volume();
00146 if (volume_ == T(0))
00147 return 0;
00148 unsigned r = 0, c = 0;
00149 bool found = false;
00150 for (unsigned ia = 0; (ia<nbins_a_)&&!found; ++ia)
00151 if ((ia+1)*delta_a_>=(a-min_a_)) {
00152 r = ia;
00153 found = true;
00154 }
00155 if (!found)
00156 return 0;
00157 found = false;
00158 for (unsigned ib = 0; (ib<nbins_b_)&&!found; ++ib)
00159 if ((ib+1)*delta_b_>=(b-min_b_)) {
00160 c = ib;
00161 found = true;
00162 }
00163 if (!found)
00164 return false;
00165 return counts_[r][c]/volume_;
00166 }
00167
00168
00169
00170 template <class T>
00171 bool bsta_joint_histogram<T>::avg_and_variance_bin_for_row_a(const unsigned int a, T & avg, T & var) const
00172 {
00173 if (a >= nbins_a_)
00174 return false;
00175
00176 T sum = 0;
00177 for (unsigned int b =0; b<nbins_b_; b++)
00178 sum += counts_[a][b];
00179
00180 if (sum <= 0)
00181 return false;
00182
00183 avg = 0;
00184 for (unsigned int b =0; b<nbins_b_; b++)
00185 avg += ((b+1)*delta_b_/2)*(counts_[a][b]/sum);
00186
00187 var = 0;
00188 for (unsigned int b =0; b<nbins_b_; b++) {
00189 T dif = (b+1)*delta_b_/2-avg;
00190 var += vcl_pow(dif, T(2.0))*(counts_[a][b]/sum);
00191 }
00192
00193 return true;
00194 }
00195
00196 template <class T>
00197 T bsta_joint_histogram<T>::volume() const
00198 {
00199 if (!volume_valid_)
00200 compute_volume();
00201 return volume_;
00202 }
00203
00204 template <class T>
00205 T bsta_joint_histogram<T>::entropy() const
00206 {
00207 T ent = 0;
00208 for (unsigned int i = 0; i<nbins_a_; ++i)
00209 for (unsigned int j = 0; j<nbins_b_; ++j)
00210 {
00211 T pij = this->p(i,j);
00212 if (pij>min_prob_)
00213 ent -= pij*T(vcl_log(pij));
00214 }
00215 ent *= (T)vnl_math::log2e;
00216 return ent;
00217 }
00218
00219 template <class T>
00220 T bsta_joint_histogram<T>::renyi_entropy() const
00221 {
00222 T ent = 0, sum = 0;
00223 for (unsigned int i = 0; i<nbins_a_; ++i)
00224 for (unsigned int j = 0; j<nbins_b_; ++j)
00225 {
00226 T pij = this->p(i,j);
00227 sum += pij*pij;
00228 }
00229 if (sum>min_prob_)
00230 ent = - T(vcl_log(sum))*(T)vnl_math::log2e;
00231 return ent;
00232 }
00233
00234 template <class T>
00235 void bsta_joint_histogram<T>::parzen(const T sigma)
00236 {
00237 if (sigma<=0)
00238 return;
00239 double sd = (double)sigma;
00240 vbl_array_2d<double> in(nbins_a_, nbins_b_), out;
00241 for (unsigned int row = 0; row<nbins_a_; row++)
00242 for (unsigned int col = 0; col<nbins_b_; col++)
00243 in[row][col] = (double)counts_[row][col];
00244
00245 bsta_gauss::bsta_2d_gaussian(sd, in, out);
00246
00247 for (unsigned int row = 0; row<nbins_a_; row++)
00248 for (unsigned int col = 0; col<nbins_b_; col++)
00249 counts_[row][col] = (T)out[row][col];
00250 }
00251
00252 template <class T>
00253 T bsta_joint_histogram<T>::get_count(T a, T b) const
00254 {
00255 T pv = this->p(a,b);
00256 if (volume_valid_)
00257 return pv*volume_;
00258 return pv*this->volume();
00259 }
00260
00261 template <class T>
00262 void bsta_joint_histogram<T>::print(vcl_ostream& os) const
00263 {
00264 for (unsigned int a = 0; a<nbins_a_; a++)
00265 for (unsigned int b = 0; b<nbins_b_; b++)
00266 if (p(a,b) > 0)
00267 os << "p[" << a << "][" << b << "]=" << p(a,b) << '\n';
00268 }
00269
00270 template <class T>
00271 void bsta_joint_histogram<T>::print_to_vrml(vcl_ostream& os) const
00272 {
00273
00274 T max = (T)0;
00275 for (unsigned int a = 0; a<nbins_a_; a++)
00276 for (unsigned int b = 0; b<nbins_b_; b++)
00277 if (p(a,b) > max)
00278 max = p(a,b);
00279 float avg = static_cast<float>(0.5*(nbins_a_ + nbins_b_));
00280 os << "#VRML V2.0 utf8\n"
00281 << "Group { children [\n";
00282
00283 for (unsigned int a = 0; a<nbins_a_; a++)
00284 {
00285 for (unsigned int b = 0; b<nbins_b_; b++)
00286 {
00287 float height = float((p(a,b)/max)*avg);
00288 os << "Transform {\n"
00289 << " translation " << a << ' ' << b << ' ' << height << vcl_endl
00290 << " children Shape {\n"
00291 << " geometry Sphere { radius 0.2 }\n"
00292 << " appearance DEF A1 Appearance {"
00293 << " material Material {\n"
00294 << " diffuseColor 1 0 0\n"
00295 << " emissiveColor .3 0 0\n"
00296 << " }\n"
00297 << " }\n"
00298 << " }\n"
00299 << "}\n"
00300 << "Transform {\n"
00301 << " translation " << a << ' ' << b << ' ' << height/2.0 << '\n'
00302 << " rotation 1 0 0 " << vnl_math::pi/2.0 << '\n'
00303 << " children Shape {\n"
00304 << " appearance USE A1\n"
00305 << " geometry Cylinder { radius 0.05 height " << height << " }\n"
00306 << " }\n"
00307 << "}\n";
00308 }
00309 }
00310
00311 os << "Transform {\n"
00312 << " translation " << (nbins_a_-1)/2.0f << ' ' << (nbins_b_-1)/2.0f << " 0\n"
00313 << " children Shape {\n"
00314 << " geometry Box { size " << nbins_a_-1 << ' ' << nbins_b_-1 << " 0.3 }\n"
00315 << " appearance Appearance {\n"
00316 << " material Material { diffuseColor 0.8 0.8 0.8 }\n"
00317 << " }\n"
00318 << " }\n"
00319 << "}\n";
00320
00321
00322 os << "Transform {\n"
00323 << " translation " << (nbins_a_-1)/2.0f << ' ' << (nbins_b_-1)/2.0f << " 0\n"
00324 << " children Shape {\n"
00325 << " geometry Box { size " << nbins_a_-1 << " 0.1 0.3 }\n"
00326 << " appearance Appearance {\n"
00327 << " material Material { diffuseColor 1.0 0.0 0.0 }\n"
00328 << " }\n"
00329 << " }\n"
00330 << "}\n"
00331
00332 << "Background { skyColor 1 1 1 }\n"
00333 << "NavigationInfo { type \"EXAMINE\" }\n"
00334 << "] }\n";
00335 }
00336
00337 template <class T>
00338 void bsta_joint_histogram<T>::print_to_m(vcl_ostream& os) const
00339 {
00340 os << "y = zeros(" << nbins_a_ << ", " << nbins_b_ << ");\n";
00341 for (unsigned int a = 0; a<nbins_a_; a++) {
00342 for (unsigned int b = 0; b<nbins_b_; b++) {
00343 if (p(a,b) > 0) {
00344 os << "y(" << a+1 << ", " << b+1 << ") = " << p(a,b) << "; ";
00345
00346 }
00347 }
00348
00349 }
00350
00351 os << "bar3(y,'detached');\n";
00352 }
00353
00354 #undef BSTA_JOINT_HISTOGRAM_INSTANTIATE
00355 #define BSTA_JOINT_HISTOGRAM_INSTANTIATE(T) \
00356 template class bsta_joint_histogram<T >
00357
00358 #endif // bsta_joint_histogram_txx_