contrib/brl/bbas/bsta/algo/bsta_bayes_functor.h
Go to the documentation of this file.
00001 // This is brl/bbas/bsta/algo/bsta_bayes_functor.h
00002 #ifndef bsta_bayes_functor_h_
00003 #define bsta_bayes_functor_h_
00004 //:
00005 // \file
00006 // \brief Functors for Bayesian classification
00007 // \author Matt Leotta (mleotta@lems.brown.edu)
00008 // \date July 27, 2005
00009 //
00010 // \verbatim
00011 //  Modifications
00012 //   (none yet)
00013 // \endverbatim
00014 
00015 #include <vcl_limits.h>
00016 #include <bsta/bsta_attributes.h> // for bsta_num_obs<T>
00017 #include <bsta/bsta_mixture.h>
00018 
00019 //: A functor that classifies a sample as one of the components of the mixture
00020 template <class comp_dist_>
00021 class bsta_bayes_functor
00022 {
00023   private:
00024     typedef bsta_num_obs<comp_dist_> comp_obs_dist_;
00025     typedef bsta_mixture<comp_obs_dist_> mix_dist_;
00026     typedef typename comp_dist_::math_type T;
00027     typedef vnl_vector_fixed<T,comp_dist_::dimension> vector_;
00028 
00029   public:
00030     typedef int return_T;
00031     enum { return_dim = 1 };
00032 
00033     //: The main function
00034     bool operator() ( const mix_dist_& mix,
00035                       const vector_& sample,
00036                       return_T& best_index ) const
00037     {
00038       best_index = -1;
00039       T best_probability = T(0);
00040       for (unsigned int i=0; i<mix.num_components(); ++i){
00041         T weight = mix.weight(i);
00042         if (weight > best_probability){
00043           T prob = mix.distribution(i).prob_density(sample) * weight;
00044           if (prob > best_probability){
00045             best_index = i;
00046             best_probability = prob;
00047           }
00048         }
00049       }
00050       return best_index >= 0;
00051     }
00052 };
00053 
00054 
00055 //: A functor that computes the probability of each component in a mixture
00056 template <class comp_dist_>
00057 class bsta_mixture_prob_functor
00058 {
00059   private:
00060     typedef bsta_num_obs<comp_dist_> comp_obs_dist_;
00061     typedef bsta_mixture<comp_obs_dist_> mix_dist_;
00062     typedef typename comp_dist_::math_type T;
00063     typedef vnl_vector_fixed<T,comp_dist_::dimension> vector_;
00064 
00065   public:
00066     typedef vector_ return_T;
00067     enum { return_dim = comp_dist_::dimension };
00068 
00069     bsta_mixture_prob_functor(bool normalize = true, unsigned int num_cmps=3)
00070     : num_cmps_(num_cmps), normalize_(normalize) {}
00071 
00072     //: The main function
00073     bool operator() ( const mix_dist_& mix,
00074                       const vector_& sample,
00075                       return_T& result ) const
00076     {
00077       result = return_T();
00078       if (num_cmps_==0)
00079         return false;
00080 
00081       double tmp = 0.0;
00082       for (unsigned int i=0; i<mix.num_components(); ++i){
00083         T w = mix.weight(i);
00084         if (w > T(0)){
00085           result[i] = w * mix.distribution(i).prob_density(sample);
00086           tmp += result[i];
00087         }
00088       }
00089       if (normalize_){
00090         if (tmp > vcl_numeric_limits<T>::epsilon()){
00091           for (unsigned int i=0; i<mix.num_components(); ++i){
00092             result[i] /= tmp;
00093           }
00094         }
00095         else{
00096           for (unsigned int i=0; i<mix.num_components(); ++i)
00097             result[i] = mix.weight(i);
00098         }
00099       }
00100       return true;
00101     }
00102 
00103   protected:
00104     unsigned int num_cmps_;
00105     bool normalize_;
00106 };
00107 
00108 
00109 #endif // bsta_bayes_functor_h_