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_