Go to the documentation of this file.00001
00002 #ifndef bsta_adaptive_updater_txx_
00003 #define bsta_adaptive_updater_txx_
00004
00005
00006 #include "bsta_adaptive_updater.h"
00007 #include "bsta_gaussian_updater.h"
00008 #include "bsta_gaussian_stats.h"
00009
00010 #include <vcl_iostream.h>
00011 #include <vcl_limits.h>
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 template <class mix_dist_>
00023 void
00024 bsta_mg_statistical_updater<mix_dist_>::update( mix_dist_& mix, const vector_& sample, T alpha ) const
00025 {
00026 const unsigned num_components = mix.num_components();
00027
00028
00029 static vcl_vector<T> probs;
00030 probs.resize(num_components,T(0));
00031 static vcl_vector<unsigned int> matched;
00032 matched.clear();
00033
00034 for (unsigned int i=0; i<num_components; ++i) {
00035 obs_gaussian_& g = mix.distribution(i);
00036 T sqr_dist = g.sqr_mahalanobis_dist(sample);
00037 if (sqr_dist < gt2_) {
00038 matched.push_back(i);
00039 probs[i] = sqr_dist;
00040 }
00041 }
00042
00043
00044 if (matched.empty()) {
00045 this->insert(mix,sample,alpha);
00046 mix.normalize_weights();
00047 }
00048 else
00049 {
00050
00051 for (unsigned int i=0; i<num_components; ++i) {
00052 T weight = (T(1)-alpha) * mix.weight(i);
00053 mix.set_weight(i,weight);
00054 }
00055
00056 if (matched.size() == 1) {
00057 unsigned int m_idx = matched.front();
00058 mix.set_weight(m_idx,mix.weight(m_idx)+alpha);
00059 obs_gaussian_& g = mix.distribution(m_idx);
00060 g.num_observations += T(1);
00061 T rho =(T(1)-alpha)/g.num_observations + alpha;
00062 bsta_update_gaussian(g, rho, sample, min_var_);
00063 }
00064 else {
00065
00066 typedef typename vcl_vector<unsigned int>::iterator m_itr;
00067 T sum_probs = T(0);
00068 for (m_itr itr = matched.begin(); itr != matched.end(); ++itr) {
00069 const unsigned int i = *itr;
00070 obs_gaussian_& g = mix.distribution(i);
00071 probs[i] = g.dist_prob_density(probs[i]) * mix.weight(i);
00072 sum_probs += probs[i];
00073 }
00074
00075 for (m_itr itr = matched.begin(); itr != matched.end(); ++itr) {
00076 const unsigned int i = *itr;
00077 if (sum_probs != 0) {
00078 probs[i] /= sum_probs;
00079 }
00080 mix.set_weight(i,mix.weight(i)+alpha*probs[i]);
00081 obs_gaussian_& g = mix.distribution(i);
00082 g.num_observations += probs[i];
00083 T rho = probs[i] * ((1-alpha)/g.num_observations + alpha);
00084 bsta_update_gaussian(g, rho, sample, min_var_);
00085 }
00086 }
00087 }
00088
00089 mix.sort(bsta_gaussian_fitness<gaussian_>::order);
00090
00091
00092 if (mix.weight(mix.num_components()-1) < vcl_numeric_limits<T>::epsilon()) {
00093 mix.remove_last();
00094 T sum = 0;
00095 for (unsigned int i=0; i<mix.num_components(); ++i) {
00096 sum += mix.weight(i);
00097 }
00098 vcl_cout << "removed, total weight = " << sum << vcl_endl;
00099 mix.normalize_weights();
00100 }
00101 }
00102
00103
00104
00105 template <class mix_dist_>
00106 void
00107 bsta_mg_grimson_statistical_updater<mix_dist_>::update( mix_dist_& mix,
00108 const vector_& sample,
00109 T alpha ) const
00110 {
00111 int match = -1;
00112 unsigned int mix_nc = mix.num_components();
00113 for (unsigned int i=0; i<mix_nc; ++i) {
00114 obs_gaussian_& g = mix.distribution(i);
00115 T weight = (T(1)-alpha) * mix.weight(i);
00116 if (match<0 && g.sqr_mahalanobis_dist(sample) < gt2_) {
00117 weight += alpha;
00118 g.num_observations += T(1);
00119 T rho = (T(1)-alpha)/g.num_observations + alpha;
00120 bsta_update_gaussian(g, rho, sample, min_var_);
00121 match = i;
00122 }
00123 mix.set_weight(i, weight);
00124 }
00125 if (match<0) {
00126 this->insert(mix,sample,alpha);
00127 match = mix.num_components()-1;
00128 }
00129
00130 if (match>0)
00131 mix.sort(bsta_gaussian_fitness<gaussian_>::order, match);
00132 }
00133
00134
00135 #define BSTA_ADAPTIVE_UPDATER_INSTANTIATE(T) \
00136 template class bsta_mg_statistical_updater<T >; \
00137 template class bsta_mg_grimson_statistical_updater<T >
00138
00139
00140 #endif // bsta_adaptive_updater_txx_