00001
00002 #ifndef bsta_gaussian_updater_h_
00003 #define bsta_gaussian_updater_h_
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <bsta/bsta_gaussian_sphere.h>
00017 #include <bsta/bsta_gaussian_indep.h>
00018 #include <bsta/bsta_gaussian_full.h>
00019 #include <bsta/bsta_mixture.h>
00020 #include <bsta/bsta_attributes.h>
00021 #include <vcl_algorithm.h>
00022
00023
00024
00025
00026 template <class T>
00027 void bsta_update_gaussian(bsta_gaussian_sphere<T,1>& gaussian, T rho,
00028 const T& sample )
00029 {
00030
00031 T rho_comp = 1.0f - rho;
00032
00033 const T& old_mean = gaussian.mean();
00034
00035 T diff = sample - old_mean;
00036 T new_var = rho_comp * gaussian.var();
00037 new_var += (rho * rho_comp) * diff*diff;
00038
00039 gaussian.set_var(new_var);
00040 gaussian.set_mean((old_mean) + (rho * diff));
00041 }
00042
00043
00044
00045
00046 template <class T, unsigned n>
00047 void bsta_update_gaussian(bsta_gaussian_sphere<T,n>& gaussian, T rho,
00048 const vnl_vector_fixed<T,n>& sample )
00049 {
00050
00051 T rho_comp = 1.0f - rho;
00052
00053 const vnl_vector_fixed<T,n>& old_mean = gaussian.mean();
00054
00055 vnl_vector_fixed<T,n> diff(sample - old_mean);
00056 T new_var = rho_comp * gaussian.var();
00057 new_var += (rho * rho_comp) * dot_product(diff,diff);
00058
00059 gaussian.set_var(new_var);
00060 gaussian.set_mean((old_mean) + (rho * diff));
00061 }
00062
00063
00064
00065
00066 template <class T, unsigned n>
00067 void bsta_update_gaussian(bsta_gaussian_indep<T,n>& gaussian, T rho,
00068 const vnl_vector_fixed<T,n>& sample )
00069 {
00070
00071 T rho_comp = 1.0f - rho;
00072
00073 const vnl_vector_fixed<T,n>& old_mean = gaussian.mean();
00074
00075 vnl_vector_fixed<T,n> diff(sample - old_mean);
00076
00077 vnl_vector_fixed<T,n> new_covar(rho_comp * gaussian.diag_covar());
00078 new_covar += (rho * rho_comp) * element_product(diff,diff);
00079
00080 gaussian.set_covar(new_covar);
00081 gaussian.set_mean((old_mean) + (rho * diff));
00082 }
00083
00084
00085
00086
00087 template <class T, unsigned n>
00088 void bsta_update_gaussian(bsta_gaussian_full<T,n>& gaussian, T rho,
00089 const vnl_vector_fixed<T,n>& sample )
00090 {
00091
00092 T rho_comp = 1.0f - rho;
00093
00094 const vnl_vector_fixed<T,n>& old_mean = gaussian.mean();
00095
00096 vnl_vector_fixed<T,n> diff(sample - old_mean);
00097
00098 vnl_matrix_fixed<T,n,n> new_covar(rho_comp * gaussian.covar());
00099 new_covar += (rho * rho_comp) * outer_product(diff,diff);
00100
00101 gaussian.set_covar(new_covar);
00102 gaussian.set_mean((old_mean) + (rho * diff));
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112 template <class T>
00113 inline T element_max(const T& a, const T& b)
00114 {
00115 return vcl_max(a,b);
00116 }
00117
00118
00119
00120 template <class T, unsigned n>
00121 vnl_vector_fixed<T,n> element_max(const vnl_vector_fixed<T,n>& a_vector,
00122 const T& b)
00123 {
00124 vnl_vector_fixed<T,n> min_vector;
00125 T* r = min_vector.data_block();
00126 const T* a = a_vector.data_block();
00127 for (unsigned i=0; i<n; ++i, ++r, ++a)
00128 *r = vcl_max(*a,b);
00129 return min_vector;
00130 }
00131
00132
00133
00134 template <class T, unsigned n>
00135 vnl_vector_fixed<T,n> element_max(const vnl_vector_fixed<T,n>& a_vector,
00136 const vnl_vector_fixed<T,n>& b_vector)
00137 {
00138 vnl_vector_fixed<T,n> min_vector;
00139 T* r = min_vector.data_block();
00140 const T* a = a_vector.data_block();
00141 const T* b = b_vector.data_block();
00142 for (unsigned i=0; i<n; ++i, ++r, ++a, ++b)
00143 *r = vcl_max(*a,*b);
00144 return min_vector;
00145 }
00146
00147
00148
00149 template <class T, unsigned n>
00150 vnl_matrix_fixed<T,n,n> element_max(const vnl_matrix_fixed<T,n,n>& a_matrix,
00151 const T& b)
00152 {
00153 vnl_matrix_fixed<T,n,n> min_matrix(a_matrix);
00154 T* r = min_matrix.data_block();
00155 const T* a = a_matrix.data_block();
00156 const unsigned step = n+1;
00157 for (unsigned i=0; i<n; ++i, r+=step, a+=step)
00158 *r = vcl_max(*a,b);
00159 return min_matrix;
00160 }
00161
00162
00163
00164 template <class T, unsigned n>
00165 vnl_matrix_fixed<T,n,n> element_max(const vnl_matrix_fixed<T,n,n>& a_matrix,
00166 const vnl_matrix_fixed<T,n,n>& b_matrix)
00167 {
00168 vnl_matrix_fixed<T,n,n> min_matrix;
00169 T* r = min_matrix.data_block();
00170 const T* a = a_matrix.data_block();
00171 const T* b = b_matrix.data_block();
00172 const unsigned num_elements = n*n;
00173 for (unsigned i=0; i<num_elements; ++i, ++r, ++a, ++b)
00174 *r = vcl_max(*a,*b);
00175 return min_matrix;
00176 }
00177
00178
00179
00180
00181
00182 template <class gauss_>
00183 inline void bsta_update_gaussian(gauss_& gaussian,
00184 typename gauss_::math_type rho,
00185 const typename gauss_::vector_type& sample,
00186 const typename gauss_::covar_type& min_covar)
00187 {
00188 bsta_update_gaussian(gaussian, rho, sample);
00189 gaussian.set_covar(element_max(gaussian.covar(),min_covar));
00190 }
00191
00192
00193
00194
00195
00196 template <class T, unsigned n>
00197 inline void bsta_update_gaussian(bsta_gaussian_indep<T,n>& gaussian, T rho,
00198 const vnl_vector_fixed<T,n>& sample,
00199 T min_var)
00200 {
00201 bsta_update_gaussian(gaussian, rho, sample);
00202 gaussian.set_covar(element_max(gaussian.covar(),min_var));
00203 }
00204
00205
00206
00207
00208
00209 template <class T, unsigned n>
00210 inline void bsta_update_gaussian(bsta_gaussian_full<T,n>& gaussian, T rho,
00211 const vnl_vector_fixed<T,n>& sample,
00212 T min_var)
00213 {
00214 bsta_update_gaussian(gaussian, rho, sample);
00215 gaussian.set_covar(element_max(gaussian.covar(),min_var));
00216 }
00217
00218
00219
00220
00221
00222
00223 template <class gauss_>
00224 class bsta_gaussian_updater
00225 {
00226 typedef bsta_num_obs<gauss_> obs_gauss_;
00227 typedef typename gauss_::math_type T;
00228 typedef vnl_vector_fixed<T,gauss_::dimension> vector_;
00229 public:
00230
00231
00232 typedef typename gauss_::field_type field_type;
00233 typedef gauss_ distribution_type;
00234
00235
00236
00237
00238 void operator() ( obs_gauss_& d, const vector_& sample ) const
00239 {
00240 d.num_observations += T(1);
00241 bsta_update_gaussian(d, T(1)/d.num_observations, sample);
00242 }
00243 };
00244
00245
00246
00247
00248
00249 template <class gauss_>
00250 class bsta_gaussian_window_updater
00251 {
00252 typedef bsta_num_obs<gauss_> obs_gauss_;
00253 typedef typename gauss_::math_type T;
00254 typedef vnl_vector_fixed<T,gauss_::dimension> vector_;
00255 public:
00256
00257
00258 typedef typename gauss_::field_type field_type;
00259 typedef gauss_ distribution_type;
00260
00261
00262
00263 bsta_gaussian_window_updater(unsigned int ws) : window_size(ws) {}
00264
00265
00266
00267 void operator() ( obs_gauss_& d, const vector_& sample) const
00268 {
00269 if (d.num_observations < window_size)
00270 d.num_observations += T(1);
00271 bsta_update_gaussian(d, T(1)/d.num_observations, sample);
00272 }
00273
00274 unsigned int window_size;
00275 };
00276
00277
00278 #endif // bsta_gaussian_updater_h_