core/vpdl/vpdl_mixture_of.h
Go to the documentation of this file.
00001 // This is core/vpdl/vpdl_mixture_of.h
00002 #ifndef vpdl_mixture_of_h_
00003 #define vpdl_mixture_of_h_
00004 //:
00005 // \file
00006 // \author Matthew Leotta
00007 // \date February 24, 2009
00008 // \brief A mixture of a fixed type of distributions
00009 //
00010 // \verbatim
00011 // Modifications
00012 //   None
00013 // \endverbatim
00014 
00015 #include <vpdl/vpdl_multi_cmp_dist.h>
00016 #include <vpdl/vpdt/vpdt_access.h>
00017 #include <vpdl/vpdt/vpdt_dist_traits.h>
00018 #include <vpdl/vpdt/vpdt_mixture_of.h>
00019 #include <vpdl/vpdt/vpdt_probability.h>
00020 
00021 //: A mixture of a fixed type of distributions
00022 // A mixture is a weighted linear combination of other mixtures.
00023 // This class represents a mixture of a specific type of distribution.
00024 // Each component in the mixture has its own weight and parameters,
00025 // but each must be of the same type.
00026 // \tparam dist_t is the type of a component distribution
00027 // \sa vpdl_mixture
00028 template<class dist_t>
00029 class vpdl_mixture_of
00030  : public vpdl_multi_cmp_dist<typename vpdt_dist_traits<dist_t>::scalar_type,
00031           vpdt_dist_traits<dist_t>::dimension>
00032 {
00033   vpdt_mixture_of<dist_t> impl_;
00034 
00035  public:
00036   //: the data type to represent a point in the field
00037   typedef typename dist_t::field_type field_type;
00038   //: define the component type
00039   typedef dist_t component_type;
00040 
00041   //: define the fixed dimension (normally specified by template parameter n)
00042   static const unsigned int n = vpdt_field_traits<field_type>::dimension;
00043   //: the data type to represent a point in the field
00044   typedef typename dist_t::field_type F;
00045   //: define the scalar type (normally specified by template parameter T)
00046   typedef typename vpdt_field_traits<field_type>::scalar_type T;
00047   //: define the vector type
00048   typedef typename vpdt_field_traits<field_type>::vector_type vector;
00049   //: the data type used for matrices
00050   typedef typename vpdt_field_traits<field_type>::matrix_type matrix;
00051 
00052   // Default Constructor
00053   vpdl_mixture_of() {}
00054 
00055   // Destructor
00056   virtual ~vpdl_mixture_of() {}
00057 
00058   //: Create a copy on the heap and return base class pointer
00059   virtual vpdl_distribution<T,n>* clone() const
00060   {
00061     return new vpdl_mixture_of<dist_t>(*this);
00062   }
00063 
00064   //: Return the run time dimension
00065   virtual unsigned int dimension() const { return impl_.dimension(); }
00066 
00067   //: Return the number of components in the mixture
00068   unsigned int num_components() const { return impl_.num_components(); }
00069 
00070   //: Access (const) a component distribution of the mixture
00071   const dist_t& distribution(unsigned int index) const
00072   { return impl_.distribution(index); }
00073 
00074   //: Access a component distribution of the mixture
00075   dist_t& distribution(unsigned int index) { return impl_.distribution(index); }
00076 
00077   //: Return the weight of a component in the mixture
00078   T weight(unsigned int index) const { return impl_.weight(index); }
00079 
00080   //: Set the weight of a component in the mixture
00081   void set_weight(unsigned int index, const T& w) { impl_.set_weight(index,w); }
00082 
00083   //: Insert a new component at the end of the vector
00084   bool insert(const dist_t& d, const T& wght = T(0))
00085   { return impl_.insert(d,wght); }
00086 
00087   //: Remove the last component in the vector
00088   bool remove_last() { return impl_.remove_last(); }
00089 
00090   //: Compute the unnormalized density at this point
00091   T density(const vector& pt) const { return impl_.density(pt); }
00092 
00093   //: Compute the probability density at this point
00094   T prob_density(const vector& pt) const { return vpdt_prob_density(impl_,pt); }
00095 
00096   //: Compute the gradient of the unnormalized density at a point
00097   // \return the density at \a pt since it is usually needed as well, and
00098   //         is often trivial to compute while computing gradient
00099   // \retval g the gradient vector
00100   virtual T gradient_density(const vector& pt, vector& g) const
00101   {
00102     return impl_.gradient_density(pt,g);
00103   }
00104 
00105   //: The probability integrated over a box
00106   T box_prob(const vector& min_pt, const vector& max_pt) const
00107   { return vpdt_box_prob(impl_,min_pt,max_pt); }
00108 
00109   //: Evaluate the cumulative distribution function at a point
00110   // This is the integral of the density function from negative infinity
00111   // (in all dimensions) to the point in question
00112   virtual T cumulative_prob(const vector& pt) const
00113   { return impl_.cumulative_prob(pt); }
00114 
00115   //: Compute the mean of the distribution.
00116   // weighted average of the component means
00117   virtual void compute_mean(vector& mean) const { impl_.compute_mean(mean); }
00118 
00119   //: Compute the covariance of the distribution.
00120   virtual void compute_covar(matrix& covar) const { impl_.compute_covar(covar); }
00121 
00122   //: The normalization constant for the density
00123   // When density() is multiplied by this value it becomes prob_density
00124   // norm_const() is reciprocal of the integral of density over the entire field
00125   virtual T norm_const() const { return impl_.norm_const(); }
00126 
00127   //: Normalize the weights of the components to add to 1.
00128   void normalize_weights() { impl_.normalize_weights(); }
00129 
00130   //: Sort the components in order of decreasing weight
00131   void sort() { impl_.sort(); }
00132 
00133   //: Sort the components in the range \a idx1 to \a idx2 in order of decreasing weight
00134   void sort(unsigned int idx1, unsigned int idx2) { impl_.sort(idx1, idx2); }
00135 
00136   //: Sort the components using any StrictWeakOrdering function
00137   // The prototype should be
00138   // \code
00139   // template <class dist_t>
00140   // bool functor(const dist_t& d1, const vpdt_dist_traits<dist_t>::scalar_type& w1,
00141   //              const dist_t& d2, const vpdt_dist_traits<dist_t>::scalar_type& w2);
00142   // \endcode
00143   template <class comp_type_>
00144   void sort(comp_type_ comp) { impl_.sort(comp); }
00145 
00146   //: Sort the components in the range \a idx1 to \a idx2 using any StrictWeakOrdering function
00147   template <class comp_type_>
00148   void sort(comp_type_ comp, unsigned int idx1, unsigned int idx2) { impl_.sort(comp,idx1,idx2); }
00149 };
00150 
00151 
00152 #endif // vpdl_mixture_of_h_