contrib/brl/bbas/bsta/algo/bsta_gaussian_stats.h
Go to the documentation of this file.
00001 // This is brl/bbas/bsta/algo/bsta_gaussian_stats.h
00002 #ifndef bsta_gaussian_stats_h_
00003 #define bsta_gaussian_stats_h_
00004 //:
00005 // \file
00006 // \brief Statistics using Gaussians
00007 // \author Matt Leotta (mleotta@lems.brown.edu)
00008 // \date January 26, 2006
00009 //
00010 // \verbatim
00011 //  Modifications
00012 //   (none yet)
00013 // \endverbatim
00014 
00015 #include <bsta/bsta_gaussian_sphere.h>
00016 #include <bsta/bsta_gaussian_indep.h>
00017 #include <bsta/bsta_gaussian_full.h>
00018 #include <bsta/bsta_mixture.h>
00019 #include <bsta/bsta_attributes.h>
00020 
00021 
00022 //: An updater that normalizes weights of a mixture based on number of observations
00023 // Each components is weighted as num_observation / total_observations
00024 // The original weights are ignored
00025 template <class comp_dist_ >
00026 class bsta_mixture_weight_by_obs_updater
00027 {
00028   private:
00029     typedef bsta_num_obs<comp_dist_> comp_obs_dist_;
00030     typedef bsta_mixture<comp_obs_dist_> mix_dist_;
00031     typedef typename comp_dist_::math_type T;
00032 
00033   public:
00034     //: The main function
00035     void operator() ( mix_dist_& mix ) const
00036     {
00037       T total = 0;
00038       vcl_vector<T> new_weights(mix.num_components(),T(0));
00039       for (unsigned int i=0; i<new_weights.size(); ++i){
00040         comp_obs_dist_& d = mix.distribution(i);
00041         total += d.num_observations;
00042         new_weights[i] = d.num_observations;
00043       }
00044       for (unsigned int i=0; i<new_weights.size(); ++i)
00045         mix.set_weight(i, new_weights[i]/total);
00046     }
00047 };
00048 
00049 
00050 //: Unrol the power calculation
00051 template <class T, unsigned n>
00052 struct bsta_compute_pow
00053 {
00054   static inline T value(const T& v)
00055   { return v * bsta_compute_pow<T,n-1>::value(v); }
00056 };
00057 
00058 //: base case
00059 // this is partial specialization: expect MSVC6 to complain
00060 template <class T>
00061 struct bsta_compute_pow<T,0>
00062 {
00063   static inline T value(const T& /*v*/) { return 1; }
00064 };
00065 
00066 
00067 //: Used to sort a mixture of gaussians in decreasing order of fitness
00068 template <class gaussian_>
00069 struct bsta_gaussian_fitness
00070 {
00071   private:
00072     typedef typename gaussian_::math_type T;
00073     enum { n = gaussian_::dimension };
00074   public:
00075     static bool order (const gaussian_& d1, const T& w1,
00076                        const gaussian_& d2, const T& w2)
00077     {
00078       return bsta_compute_pow<T,n>::value(w1*w1)/d1.det_covar() >
00079              bsta_compute_pow<T,n>::value(w2*w2)/d2.det_covar();
00080     }
00081 };
00082 
00083 
00084 //: Used to sort a mixture of gaussians in decreasing order of fitness
00085 // Partial specialization optimized for the spherical case
00086 template <class T, unsigned n>
00087 struct bsta_gaussian_fitness<bsta_gaussian_sphere<T,n> >
00088 {
00089   static bool order (const bsta_gaussian_sphere<T,n>& d1, const T& w1,
00090                      const bsta_gaussian_sphere<T,n>& d2, const T& w2)
00091   {
00092     return w1*w1/d1.var() > w2*w2/d2.var();
00093   }
00094 };
00095 
00096 
00097 #endif // bsta_gaussian_stats_h_