core/vpdl/vpdt/vpdt_mixture_accessors.h
Go to the documentation of this file.
00001 // This is  core/vpdl/vpdt/vpdt_mixture_accessors.h
00002 #ifndef vpdt_mixture_accessors_h_
00003 #define vpdt_mixture_accessors_h_
00004 //:
00005 // \file
00006 // \brief Accessor functors that apply to all mixture distributions
00007 // \author Matt Leotta (mleotta@lems.brown.edu)
00008 // \date March 15, 2009
00009 //
00010 // \verbatim
00011 //  Modifications
00012 //   (none yet)
00013 // \endverbatim
00014 
00015 #include <vpdl/vpdt/vpdt_dist_traits.h>
00016 #include <vpdl/vpdt/vpdt_enable_if.h>
00017 
00018 
00019 //: A functor to return the number of components in a mixture
00020 // This is a dummy class for non-mixture types; it always fails
00021 template <class mixture_type, class Disambiguate=void>
00022 class vpdt_num_components_accessor
00023 {
00024  public:
00025   //: the functor return type
00026   typedef unsigned int return_type;
00027   //: the distribution operated on by the functor
00028   typedef mixture_type distribution_type;
00029   //: is this functor valid for its distribution type
00030   static const bool valid_functor = false;
00031   
00032   //: rebind this functor to another distribution type
00033   template <class other_dist> 
00034   struct rebind {
00035     typedef vpdt_num_components_accessor<other_dist> other;
00036   };
00037   
00038   //: The main function
00039   bool operator() ( const mixture_type& mix, return_type& retval ) const
00040   {
00041     return false;
00042   }
00043 };
00044 
00045 //
00046 //: A functor to return the number of components in a mixture
00047 template <class mixture_type>
00048 class vpdt_num_components_accessor<mixture_type, 
00049           typename vpdt_enable_if<vpdt_is_mixture<mixture_type> >::type>
00050 {
00051  public:
00052   //: the functor return type
00053   typedef unsigned int return_type;
00054   //: the distribution operated on by the functor
00055   typedef mixture_type distribution_type;
00056   //: is this functor valid for its distribution type
00057   static const bool valid_functor = true;
00058 
00059   //: rebind this functor to another distribution type
00060   template <class other_dist> 
00061   struct rebind {
00062     typedef vpdt_num_components_accessor<other_dist> other;
00063   };
00064 
00065   //: The main function
00066   bool operator() ( const mixture_type& mix, return_type& retval ) const
00067   {
00068     retval = mix.num_components();
00069     return true;
00070   }
00071 };
00072 
00073 
00074 //: A functor to return the weight of the component with given index
00075 template <class mixture_type, class Disambiguate=void>
00076 class vpdt_weight_accessor
00077 {
00078  public:
00079   //: the functor return type
00080   typedef typename vpdt_dist_traits<mixture_type>::scalar_type return_type;
00081   //: the distribution operated on by the functor
00082   typedef mixture_type distribution_type;
00083   //: is this functor valid for its distribution type
00084   static const bool valid_functor = false;
00085   
00086   //: rebind this functor to another distribution type
00087   template <class other_dist> 
00088   struct rebind {
00089     typedef vpdt_weight_accessor<other_dist> other;
00090   };
00091 
00092   //: Constructor
00093   vpdt_weight_accessor(unsigned int index = 0) {}
00094 
00095   //: The main function
00096   bool operator() ( const mixture_type& mix, return_type& retval ) const
00097   {
00098     return false;
00099   }
00100 };
00101 
00102 
00103 //: A functor to return the weight of the component with given index
00104 template <class mixture_type>
00105 class vpdt_weight_accessor<mixture_type,
00106           typename vpdt_enable_if<vpdt_is_mixture<mixture_type> >::type>
00107 {
00108  public:
00109   //: the functor return type
00110   typedef typename vpdt_dist_traits<mixture_type>::scalar_type return_type;
00111   //: the distribution operated on by the functor
00112   typedef mixture_type distribution_type;
00113   //: is this functor valid for its distribution type
00114   static const bool valid_functor = true;
00115 
00116   //: rebind this functor to another distribution type
00117   template <class other_dist> 
00118   struct rebind {
00119     typedef vpdt_weight_accessor<other_dist> other;
00120   };
00121 
00122   //: Constructor
00123   vpdt_weight_accessor(unsigned int index = 0) : idx(index) {}
00124 
00125   //: The main function
00126   bool operator() ( const mixture_type& mix, return_type& retval ) const
00127   {
00128     if (idx < mix.num_components()){
00129       retval = mix.weight(idx);
00130       return true;
00131     }
00132     return false;
00133   }
00134 
00135   //: The component index
00136   unsigned int idx;
00137 };
00138 
00139 
00140 //: A functor to apply another functor to the component with given index
00141 template <class mixture_type, class accessor_type, class Disambiguate=void>
00142 class vpdt_mixture_accessor
00143 {
00144  public:
00145   //: the functor return type
00146   typedef typename accessor_type::return_type return_type;
00147   //: the distribution operated on by the functor
00148   typedef mixture_type distribution_type;
00149   //: is this functor valid for its distribution type
00150   static const bool valid_functor = false;
00151     
00152   //: rebind this functor to another distribution type
00153   template <class other_dist, class other_accessor = accessor_type> 
00154   struct rebind {
00155     typedef vpdt_mixture_accessor<other_dist,other_accessor> other;
00156   };
00157   
00158   //: Constructor
00159   vpdt_mixture_accessor(unsigned int index = 0) {}
00160   
00161   //: Constructor
00162   vpdt_mixture_accessor(const accessor_type& a, unsigned int index = 0) {}
00163   
00164   //: The main function
00165   bool operator() ( const mixture_type& mix, return_type& retval ) const
00166   {
00167     return false;
00168   }
00169 };
00170 
00171 
00172 //: A functor to apply another functor to the component with given index
00173 template <class mixture_type, class accessor_type>
00174 class vpdt_mixture_accessor<mixture_type,accessor_type,
00175           typename vpdt_enable_if<vpdt_is_mixture<mixture_type> >::type>
00176 {
00177  public:
00178   //: the functor return type
00179   typedef typename accessor_type::return_type return_type;
00180   //: the distribution operated on by the functor
00181   typedef mixture_type distribution_type;
00182   //: is this functor valid for its distribution type
00183   static const bool valid_functor = true;
00184 
00185   //: rebind this functor to another distribution type
00186   template <class other_dist, class other_accessor = accessor_type> 
00187   struct rebind {
00188     typedef vpdt_mixture_accessor<other_dist,other_accessor> other;
00189   };
00190 
00191   //: Constructor
00192   vpdt_mixture_accessor(unsigned int index = 0) 
00193   : accessor(), idx(index) {}
00194 
00195   //: Constructor
00196   vpdt_mixture_accessor(const accessor_type& a, unsigned int index = 0) 
00197   : accessor(a), idx(index) {}
00198 
00199   //: The main function
00200   bool operator() ( const mixture_type& mix, return_type& retval ) const
00201   {
00202     if (idx < mix.num_components()){
00203       return accessor(mix.distribution(idx),retval);
00204     }
00205     return false;
00206   }
00207 
00208   //: The accessor to apply
00209   accessor_type accessor;
00210   //: The component index
00211   unsigned int idx;
00212 };
00213 
00214 
00215 //: A specialization to make the weight accessor work as a mixture accessor
00216 template <class mixture_type>
00217 class vpdt_mixture_accessor<mixture_type, 
00218           vpdt_weight_accessor<typename mixture_type::component_type>,
00219           typename vpdt_enable_if<vpdt_is_mixture<mixture_type> >::type>
00220 {
00221  public:
00222   //: the accessor type
00223   typedef vpdt_weight_accessor<typename mixture_type::component_type> accessor_type;
00224   //: the functor return type
00225   typedef typename vpdt_dist_traits<mixture_type>::scalar_type return_type;
00226   //: the distribution operated on by the functor
00227   typedef mixture_type distribution_type;
00228   //: is this functor valid for its distribution type
00229   static const bool valid_functor = true;
00230   
00231   //: rebind this functor to another distribution type
00232   template <class other_dist, class other_accessor = accessor_type> 
00233   struct rebind {
00234     typedef vpdt_mixture_accessor<other_dist,other_accessor> other;
00235   };
00236 
00237   //: Constructor
00238   vpdt_mixture_accessor(unsigned int index = 0) 
00239   : idx(index) {}
00240 
00241   //: Constructor
00242   vpdt_mixture_accessor(const accessor_type& a, unsigned int index = 0) 
00243   : idx(index) {}
00244 
00245   //: The main function
00246   bool operator() ( const mixture_type& mix, return_type& retval ) const
00247   {
00248     if (idx < mix.num_components()){
00249       retval = mix.weight(idx);
00250       return true;
00251     }
00252     return false;
00253   }
00254 
00255   //: The component index
00256   unsigned int idx;
00257 };
00258 
00259 
00260 #endif // vpdt_mixture_accessors_h_