00001
00002 #ifndef bsta_basic_functors_h_
00003 #define bsta_basic_functors_h_
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <vcl_vector.h>
00016 #include <bsta/bsta_attributes.h>
00017 #include <bsta/bsta_gaussian_indep.h>
00018 #include <bsta/bsta_gaussian_sphere.h>
00019 #include <vpdl/vpdt/vpdt_enable_if.h>
00020 #include <vpdl/vpdt/vpdt_dist_traits.h>
00021 #include <vpdl/vpdt/vpdt_mixture_accessors.h>
00022
00023
00024 template <class dist_>
00025 class bsta_prob_density_functor
00026 {
00027 public:
00028 typedef typename dist_::math_type T;
00029 typedef typename dist_::vector_type vector_;
00030 typedef T return_T;
00031 typedef return_T return_type;
00032 enum { return_dim = 1 };
00033
00034
00035 bool operator() ( const dist_& d, const vector_& sample, return_T& retval ) const
00036 {
00037 retval = d.prob_density(sample);
00038 return true;
00039 }
00040 };
00041
00042
00043 template <class mix_dist_>
00044 class bsta_prob_density_addcovar_functor
00045 {
00046 public:
00047 typedef typename mix_dist_::dist_type::math_type T;
00048 typedef typename mix_dist_::dist_type::vector_type vector_;
00049 typedef typename mix_dist_::dist_type::covar_type covar_t_;
00050 typedef T return_T;
00051 typedef return_T return_type;
00052 enum { return_dim = 1 };
00053
00054 bool operator() ( const mix_dist_& d, const vector_& sample,
00055 const covar_t_& add_covar, return_T& retval ) const
00056 {
00057 unsigned nc = d.num_components();
00058 vcl_vector<covar_t_> initial_covars(nc);
00059 mix_dist_& non_const_d = const_cast<mix_dist_&>(d);
00060 for (unsigned i = 0; i<nc; ++i) {
00061 initial_covars[i]=(d.distribution(i)).covar();
00062 non_const_d.distribution(i).set_covar(initial_covars[i]+add_covar);
00063 }
00064 retval = non_const_d.prob_density(sample);
00065 for (unsigned i = 0; i<nc; ++i)
00066 non_const_d.distribution(i).set_covar(initial_covars[i]);
00067 return true;
00068 }
00069 };
00070
00071
00072
00073 template <class dist_>
00074 class bsta_probability_functor
00075 {
00076 public:
00077 typedef typename dist_::math_type T;
00078 typedef typename dist_::vector_type vector_;
00079 typedef T return_T;
00080 typedef return_T return_type;
00081 enum { return_dim = 1 };
00082
00083
00084 bool operator() ( const dist_& d, const vector_& min_pt,
00085 const vector_& max_pt, return_T& retval ) const
00086 {
00087 retval = d.probability(min_pt,max_pt);
00088 return true;
00089 }
00090 };
00091
00092
00093 template <class mix_dist_>
00094 class bsta_probability_addcovar_functor
00095 {
00096 public:
00097 typedef typename mix_dist_::dist_type::math_type T;
00098 typedef typename mix_dist_::dist_type::vector_type vector_;
00099 typedef typename mix_dist_::dist_type::covar_type covar_t_;
00100 typedef T return_T;
00101 typedef return_T return_type;
00102 enum { return_dim = 1 };
00103
00104 bool operator() ( const mix_dist_& d,
00105 const vector_& min_pt,
00106 const vector_& max_pt,
00107 const covar_t_& add_covar,
00108 return_T& retval ) const
00109 {
00110 unsigned nc = d.num_components();
00111 mix_dist_& non_const_d = const_cast<mix_dist_&>(d);
00112 vcl_vector<covar_t_> initial_covars(nc);
00113 for (unsigned i = 0; i<nc; ++i){
00114 initial_covars[i]=(d.distribution(i)).covar();
00115 non_const_d.distribution(i).set_covar(initial_covars[i]+add_covar);
00116 }
00117 retval = d.probability(min_pt, max_pt);
00118 for (unsigned i = 0; i<nc; ++i)
00119 non_const_d.distribution(i).set_covar(initial_covars[i]);
00120 return true;
00121 }
00122 };
00123
00124
00125
00126 template <class dist_, class Disambiguate = void>
00127 class bsta_mean_functor
00128 {
00129 public:
00130 typedef typename dist_::math_type T;
00131 typedef typename dist_::vector_type vector_;
00132 typedef vector_ return_T;
00133 typedef return_T return_type;
00134
00135 static const bool valid_functor = true;
00136 enum { return_dim = dist_::dimension };
00137
00138
00139 template <class other_dist>
00140 struct rebind {
00141 typedef bsta_mean_functor<other_dist> other;
00142 };
00143
00144
00145 bool operator() ( const dist_& d, return_T& retval ) const
00146 {
00147 retval = d.mean();
00148 return true;
00149 }
00150 };
00151
00152
00153 template <class dist_>
00154 class bsta_mean_functor<dist_, typename vpdt_enable_if<vpdt_is_mixture<dist_> >::type >
00155 {
00156 public:
00157 typedef typename dist_::field_type return_type;
00158 enum { return_dim = dist_::dimension };
00159
00160 static const bool valid_functor = false;
00161
00162
00163 template <class other_dist>
00164 struct rebind {
00165 typedef bsta_mean_functor<other_dist> other;
00166 };
00167
00168
00169 bool operator() ( const dist_& , return_type& ) const
00170 {
00171 return false;
00172 }
00173 };
00174
00175
00176
00177
00178 template <class dist_>
00179 class bsta_var_functor
00180 {
00181 public:
00182 typedef typename dist_::math_type T;
00183 typedef T return_T;
00184 typedef return_T return_type;
00185 enum { return_dim = 1 };
00186
00187 static const bool valid_functor = false;
00188
00189
00190 template <class other_dist>
00191 struct rebind {
00192 typedef bsta_var_functor<other_dist> other;
00193 };
00194
00195
00196 #if 0
00197 bool operator() (dist_ const& d, return_T& retval) const
00198 {
00199 retval = d.var();
00200 return true;
00201 }
00202 #else
00203 bool operator() (dist_ const&, return_T&) const
00204 {
00205 return false;
00206 }
00207 #endif
00208 };
00209
00210
00211
00212
00213
00214
00215
00216 template <class T>
00217 class bsta_var_functor<bsta_num_obs<bsta_gaussian_sphere<T,1> > >
00218 {
00219 public:
00220 typedef bsta_gaussian_sphere<T,1> dist_;
00221 typedef typename dist_::vector_type vector_;
00222 typedef vector_ return_T;
00223 typedef return_T return_type;
00224 enum { return_dim = dist_::dimension };
00225
00226 static const bool valid_functor = true;
00227
00228
00229 template <class other_dist>
00230 struct rebind {
00231 typedef bsta_var_functor<other_dist> other;
00232 };
00233
00234
00235 bool operator() ( const dist_& d, return_T& retval ) const
00236 {
00237 retval = d.var();
00238 return true;
00239 }
00240 };
00241
00242
00243
00244
00245
00246 template <class dist_>
00247 class bsta_diag_covar_functor
00248 {
00249 public:
00250 typedef typename dist_::math_type T;
00251 typedef typename dist_::vector_type vector_;
00252 typedef vector_ return_T;
00253 typedef return_T return_type;
00254 enum { return_dim = dist_::dimension };
00255
00256 static const bool valid_functor = false;
00257
00258
00259 template <class other_dist>
00260 struct rebind {
00261 typedef bsta_diag_covar_functor<other_dist> other;
00262 };
00263
00264
00265 #if 0
00266 bool operator() (dist_ const& d, return_T& retval) const
00267 {
00268 retval = d.var();
00269 return true;
00270 }
00271 #else
00272 bool operator() (dist_ const&, return_T&) const
00273 {
00274 return false;
00275 }
00276 #endif
00277 };
00278
00279
00280
00281
00282
00283
00284
00285
00286 template <class T, unsigned n>
00287 class bsta_diag_covar_functor<bsta_num_obs<bsta_gaussian_indep<T,n> > >
00288 {
00289 public:
00290 typedef bsta_gaussian_indep<T,n> dist_;
00291 typedef typename dist_::vector_type vector_;
00292 typedef vector_ return_T;
00293 typedef return_T return_type;
00294 enum { return_dim = dist_::dimension };
00295
00296 static const bool valid_functor = true;
00297
00298
00299 template <class other_dist>
00300 struct rebind {
00301 typedef bsta_diag_covar_functor<other_dist> other;
00302 };
00303
00304
00305 bool operator() ( const dist_& d, return_T& retval ) const
00306 {
00307 retval = d.diag_covar();
00308 return true;
00309 }
00310 };
00311
00312
00313
00314
00315 template <class dist_>
00316 class bsta_det_covar_functor
00317 {
00318 public:
00319 typedef typename dist_::math_type T;
00320 typedef T return_T;
00321 typedef return_T return_type;
00322 enum { return_dim = 1 };
00323
00324
00325 bool operator() ( const dist_& d, return_T& retval ) const
00326 {
00327 retval = d.det_covar();
00328 return true;
00329 }
00330 };
00331
00332
00333
00334
00335
00336 template <class mixture_, class Disambiguate=void>
00337 class bsta_weight_functor
00338 {
00339 public:
00340 typedef typename mixture_::math_type T;
00341 typedef T return_T;
00342 typedef return_T return_type;
00343 enum { return_dim = 1 };
00344
00345 static const bool valid_functor = false;
00346
00347
00348 template <class other_dist>
00349 struct rebind {
00350 typedef bsta_weight_functor<other_dist> other;
00351 };
00352
00353
00354 bsta_weight_functor(unsigned int index = 0) {}
00355
00356
00357 bool operator() ( const mixture_& mix, return_T& retval ) const
00358 {
00359 return false;
00360 }
00361 };
00362
00363
00364
00365
00366 template <class mixture_>
00367 class bsta_weight_functor<mixture_,
00368 typename vpdt_enable_if<vpdt_is_mixture<mixture_> >::type>
00369 {
00370 public:
00371 typedef typename mixture_::math_type T;
00372 typedef T return_T;
00373 typedef return_T return_type;
00374 enum { return_dim = 1 };
00375
00376 static const bool valid_functor = true;
00377
00378
00379 template <class other_dist>
00380 struct rebind {
00381 typedef bsta_weight_functor<other_dist> other;
00382 };
00383
00384
00385 bsta_weight_functor(unsigned int index = 0) : idx(index) {}
00386
00387
00388 bool operator() ( const mixture_& mix, return_T& retval ) const
00389 {
00390 if (idx < mix.num_components()){
00391 retval = mix.weight(idx);
00392 return true;
00393 }
00394 return false;
00395 }
00396
00397 unsigned int idx;
00398 };
00399
00400
00401
00402
00403
00404 template <class mixture_>
00405 class vpdt_mixture_accessor<mixture_,
00406 bsta_weight_functor<typename mixture_::component_type>,
00407 typename vpdt_enable_if<vpdt_is_mixture<mixture_> >::type>
00408 {
00409 public:
00410
00411 typedef bsta_weight_functor<typename mixture_::component_type> accessor_type;
00412
00413 typedef typename vpdt_dist_traits<mixture_>::scalar_type return_type;
00414
00415 typedef mixture_ distribution_type;
00416
00417 static const bool valid_functor = true;
00418
00419
00420 template <class other_dist, class other_accessor = accessor_type>
00421 struct rebind {
00422 typedef vpdt_mixture_accessor<other_dist,other_accessor> other;
00423 };
00424
00425
00426 vpdt_mixture_accessor(unsigned int index = 0)
00427 : idx(index) {}
00428
00429
00430 vpdt_mixture_accessor(const accessor_type& a, unsigned int index = 0)
00431 : idx(index) {}
00432
00433
00434 bool operator() ( const mixture_& mix, return_type& retval ) const
00435 {
00436 if (idx < mix.num_components()){
00437 retval = mix.weight(idx);
00438 return true;
00439 }
00440 return false;
00441 }
00442
00443
00444 unsigned int idx;
00445 };
00446
00447
00448
00449
00450 template <class mixture_, class functor_>
00451 class bsta_mixture_functor
00452 {
00453 public:
00454 typedef typename mixture_::math_type T;
00455 typedef typename functor_::return_T return_T;
00456 typedef return_T return_type;
00457 enum { return_dim = functor_::return_dim };
00458
00459
00460 bsta_mixture_functor(const functor_& f, unsigned int index = 0 )
00461 : functor(f), idx(index) {}
00462
00463
00464 bool operator() ( const mixture_& mix, return_T& retval ) const
00465 {
00466 if (idx < mix.num_components() && mix.weight(idx) > T(0)){
00467 return functor(mix.distribution(idx),retval);
00468 }
00469 return false;
00470 }
00471
00472
00473 functor_ functor;
00474
00475 unsigned int idx;
00476 };
00477
00478
00479
00480
00481 template <class mixture_, class functor_>
00482 class bsta_mixture_data_functor
00483 {
00484 public:
00485 typedef typename mixture_::math_type T;
00486 typedef typename functor_::return_T return_T;
00487 typedef return_T return_type;
00488 typedef typename mixture_::vector_type vector_;
00489 enum { return_dim = functor_::return_dim };
00490
00491
00492 bsta_mixture_data_functor(const functor_& f, unsigned int index = 0 )
00493 : functor(f), idx(index) {}
00494
00495
00496 bool operator() ( const mixture_& mix, const vector_& sample, return_T& retval ) const
00497 {
00498 if (idx < mix.num_components() && mix.weight(idx) > T(0)){
00499 return functor(mix.distribution(idx),sample,retval);
00500 }
00501 return false;
00502 }
00503
00504
00505 functor_ functor;
00506
00507 unsigned int idx;
00508 };
00509
00510
00511
00512
00513 template <class mixture_, class functor_>
00514 class bsta_weighted_sum_functor
00515 {
00516 public:
00517 typedef typename mixture_::math_type T;
00518 typedef typename functor_::return_T return_T;
00519 typedef return_T return_type;
00520 enum { return_dim = functor_::return_dim };
00521
00522
00523 bsta_weighted_sum_functor() : functor() {}
00524
00525 bsta_weighted_sum_functor(const functor_& f)
00526 : functor(f) {}
00527
00528
00529 bool operator() ( const mixture_& mix, return_T& retval ) const
00530 {
00531 const unsigned int nc = mix.num_components();
00532 if (nc > 0) {
00533 return_T temp;
00534 if ( !functor(mix.distribution(0),temp) )
00535 return false;
00536 retval = mix.weight(0) * temp;
00537 for (unsigned int idx=1; idx<nc; ++idx){
00538 if ( !functor(mix.distribution(idx),temp) )
00539 return false;
00540 retval += mix.weight(idx) * temp;
00541 }
00542 return true;
00543 }
00544 return false;
00545 }
00546
00547
00548 functor_ functor;
00549 };
00550
00551
00552
00553
00554 template <class mixture_, class functor_>
00555 class bsta_weighted_sum_data_functor
00556 {
00557 public:
00558 typedef typename mixture_::math_type T;
00559 typedef typename functor_::return_T return_T;
00560 typedef return_T return_type;
00561 typedef typename mixture_::vector_type vector_;
00562 enum { return_dim = functor_::return_dim };
00563
00564
00565 bsta_weighted_sum_data_functor() : functor() {}
00566
00567 bsta_weighted_sum_data_functor(const functor_& f)
00568 : functor(f) {}
00569
00570
00571 bool operator() ( const mixture_& mix, const vector_& sample, return_T& retval ) const
00572 {
00573 const unsigned int nc = mix.num_components();
00574 if (nc > 0)
00575 {
00576 return_T temp;
00577 if ( !functor(mix.distribution(0),sample,temp) )
00578 return false;
00579 retval = mix.weight(0) * temp;
00580 for (unsigned int idx=1; idx<nc; ++idx){
00581 if ( !functor(mix.distribution(idx),sample,temp) )
00582 return false;
00583 retval += mix.weight(idx) * temp;
00584 }
00585 return true;
00586 }
00587 return false;
00588 }
00589
00590
00591 functor_ functor;
00592 };
00593
00594
00595
00596
00597 template <class mixture_>
00598 class bsta_mixture_size_functor
00599 {
00600 public:
00601 typedef typename mixture_::math_type T;
00602 typedef unsigned int return_T;
00603 typedef return_T return_type;
00604 enum { return_dim = 1 };
00605
00606
00607 bool operator() ( const mixture_& mix, return_T& retval ) const
00608 {
00609 retval = mix.num_components();
00610 return true;
00611 }
00612 };
00613
00614
00615 #endif // bsta_basic_functors_h_