indii/ml/aux/KernelDensityMixturePdf.hpp

00001 #ifndef INDII_ML_AUX_KERNELDENSITYMIXTUREPDF_HPP
00002 #define INDII_ML_AUX_KERNELDENSITYMIXTUREPDF_HPP
00003 
00004 #include "StandardMixturePdf.hpp"
00005 #include "KernelDensityPdf.hpp"
00006 #include "KDTree.hpp"
00007 #include "Almost2Norm.hpp"
00008 #include "AlmostGaussianKernel.hpp"
00009 
00010 namespace indii {
00011   namespace ml {
00012     namespace aux {
00013 /**
00014  * Mixture of kernel density estimators.
00015  *
00016  * @author Lawrence Murray <lawrence@indii.org>
00017  * @version $Rev: 590 $
00018  * @date $Date: 2008-12-17 15:09:40 +0000 (Wed, 17 Dec 2008) $
00019  *
00020  * @param NT Norm type.
00021  * @param KT Kernel type.
00022  *
00023  * @see MixturePdf for more information regarding the serialization
00024  * and parallelisation features of this class.
00025  */
00026 template <class NT = Almost2Norm, class KT = AlmostGaussianKernel>
00027 class KernelDensityMixturePdf :
00028     public StandardMixturePdf<KernelDensityPdf<NT,KT> > {
00029 public:
00030   /**
00031    * Default constructor.
00032    *
00033    * Initialises the mixture with zero dimensions. This should
00034    * generally only be used when the object is to be restored from a
00035    * serialization. Indeed, there is no other way to resize the
00036    * mixture to nonzero dimensionality except by subsequently
00037    * restoring from a serialization.
00038    */
00039   KernelDensityMixturePdf();
00040 
00041   /**
00042    * Constructor. One or more components should be added with
00043    * addComponent() after construction.
00044    *
00045    * @param N Dimensionality of the distribution.
00046    */
00047   KernelDensityMixturePdf(const unsigned int N);
00048 
00049   /**
00050    * Constructor.
00051    *
00052    * @param x The first component.
00053    * @param w Unnormalised weight of the component.
00054    *
00055    * This is particularly useful for creating single component
00056    * mixtures of any type for parallel environments.
00057    */
00058   KernelDensityMixturePdf(const KernelDensityPdf<NT,KT>& x,
00059       const double w = 1.0);
00060 
00061   /**
00062    * Destructor.
00063    */
00064   virtual ~KernelDensityMixturePdf();
00065 
00066   using StandardMixturePdf<KernelDensityPdf<NT,KT> >::densityAt;
00067   
00068   using StandardMixturePdf<KernelDensityPdf<NT,KT> >::distributedDensityAt;
00069 
00070   /**
00071    * Calculate the density on the local node for all points in a tree.
00072    *
00073    * @param tree Query tree.
00074    *
00075    * @return Density at all points in the tree, ordered according to the 
00076    * underlying DiracMixturePdf ordering.
00077    *
00078    * Uses a dual-tree algorithm to efficiently calculate the density at
00079    * all points in the query tree.
00080    *
00081    * @todo Currently requires KDTree rather than PartitionTree due to
00082    * apparent link errors related to Boost.MPI and Boost.Serialization.
00083    */
00084   vector densityAt(PartitionTree& tree);
00085 
00086   /**
00087    * Calculate the density of the full distribution for all points in a
00088    * tree.
00089    *
00090    * @param tree Query tree on this node.
00091    *
00092    * @return Density at all points in the tree on this node, ordered
00093    * according to its underlying DiracMixturePdf ordering.
00094    *
00095    * Uses a dual-tree algorithm to efficiently calculate the density at
00096    * all points in the query tree. Note that while each node is passed only
00097    * its set of points, in the form of a tree, and returns only the density
00098    * calculations for that set of points, all nodes participate in the
00099    * calculation for all points.
00100    *
00101    * @todo Currently requires KDTree rather than PartitionTree due to
00102    * apparent link errors related to Boost.MPI and Boost.Serialization.
00103    */
00104   template <class S>
00105   vector distributedDensityAt(KDTree<S>& tree);
00106 
00107 private:
00108   /**
00109    * Serialize or restore from serialization.
00110    */
00111   template<class Archive>
00112   void serialize(Archive& ar, const unsigned int version);
00113 
00114   /*
00115    * Boost.Serialization requirements.
00116    */
00117   friend class boost::serialization::access;
00118 
00119 };
00120 
00121     }
00122   }
00123 }
00124 
00125 #include "boost/serialization/base_object.hpp"
00126 
00127 template <class NT, class KT>
00128 indii::ml::aux::KernelDensityMixturePdf<NT,KT>::KernelDensityMixturePdf() :
00129     StandardMixturePdf<KernelDensityPdf<NT,KT> >() {
00130   //
00131 }
00132 
00133 template <class NT, class KT>
00134 indii::ml::aux::KernelDensityMixturePdf<NT,KT>::KernelDensityMixturePdf(
00135     const unsigned int N) : StandardMixturePdf<KernelDensityPdf<NT,KT> >(N) {
00136   //
00137 }
00138 
00139 template <class NT, class KT>
00140 indii::ml::aux::KernelDensityMixturePdf<NT,KT>::KernelDensityMixturePdf(
00141     const KernelDensityPdf<NT,KT>& x, const double w) :
00142     indii::ml::aux::StandardMixturePdf<KernelDensityPdf<NT,KT> >(x, w) {
00143   //
00144 }
00145 
00146 template <class NT, class KT>
00147 indii::ml::aux::KernelDensityMixturePdf<NT,KT>::~KernelDensityMixturePdf() {
00148   //
00149 }
00150 
00151 template <class NT, class KT>
00152 indii::ml::aux::vector
00153     indii::ml::aux::KernelDensityMixturePdf<NT,KT>::densityAt(
00154     PartitionTree& tree) {
00155   vector result(tree.getRoot()->getSize());
00156   unsigned int i;
00157   
00158   result.clear();
00159   for (i = 0; i < this->getSize(); i++) {
00160     noalias(result) += this->getWeight(i) * this->get(i).densityAt(tree);
00161   }
00162   result /= this->getTotalWeight();
00163   
00164   return result;
00165 }
00166 
00167 template <class NT, class KT>
00168 template <class S>
00169 indii::ml::aux::vector
00170     indii::ml::aux::KernelDensityMixturePdf<NT,KT>::distributedDensityAt(
00171     KDTree<S>& tree) {
00172   boost::mpi::communicator world;
00173   const unsigned int size = world.size();
00174   unsigned int i;
00175  
00176   vector result(this->getTotalWeight() * this->densityAt(tree));
00177   rotate(*tree.getData());
00178   rotate(tree);
00179   rotate(result);
00180 
00181   for (i = 1; i < size; i++) {
00182     noalias(result) += this->getTotalWeight() * this->densityAt(tree);
00183     rotate(*tree.getData());
00184     rotate(tree);
00185     rotate(result);
00186   }
00187   result /= this->getDistributedTotalWeight();
00188 
00189   return result;
00190 }
00191 
00192 template <class NT, class KT>
00193 template <class Archive>
00194 void indii::ml::aux::KernelDensityMixturePdf<NT,KT>::serialize(Archive& ar,
00195     const unsigned int version) {
00196   ar & boost::serialization::base_object<
00197       indii::ml::aux::StandardMixturePdf<
00198       indii::ml::aux::KernelDensityPdf<NT,KT> > >(*this);
00199 }
00200 
00201 #endif
00202 

Generated on Wed Dec 17 15:11:57 2008 for dysii Dynamical Systems Library by  doxygen 1.5.3