indii/ml/aux/DiracMixturePdf.hpp

00001 #ifndef INDII_ML_AUX_DIRACMIXTUREPDF_HPP
00002 #define INDII_ML_AUX_DIRACMIXTUREPDF_HPP
00003 
00004 #include "MixturePdf.hpp"
00005 #include "DiracPdf.hpp"
00006 
00007 namespace indii {
00008   namespace ml {
00009     namespace aux {
00010     
00011       class KDTreeNode;
00012     
00013 /**
00014  * Dirac mixture probability density.
00015  *
00016  * @author Lawrence Murray <lawrence@indii.org>
00017  * @version $Rev: 538 $
00018  * @date $Date: 2008-08-31 14:41:10 +0100 (Sun, 31 Aug 2008) $
00019  *
00020  * @see MixturePdf for more information regarding the serialization
00021  * and parallelisation features of this class.
00022  */
00023 class DiracMixturePdf : public MixturePdf<DiracPdf> {
00024 public:
00025   /**
00026    * Default constructor.
00027    *
00028    * Initialises the mixture with zero dimensions. This should
00029    * generally only be used when the object is to be restored from a
00030    * serialization. Indeed, there is no other way to resize the
00031    * mixture to nonzero dimensionality except by subsequently
00032    * restoring from a serialization.
00033    */
00034   DiracMixturePdf();
00035 
00036   /**
00037    * Sampling constructor.
00038    *
00039    * @param o Distribution to approximate.
00040    * @param P Number of samples with which to approximate the
00041    * distribution.
00042    * 
00043    * Initialises the mixture by drawing @c P equally weighted samples
00044    * from the distribution @c o.
00045    */
00046   DiracMixturePdf(Pdf& o, const unsigned int P);
00047 
00048   /**
00049    * Constructor. One or more components should be added with
00050    * addComponent() after construction.
00051    *
00052    * @param N Dimensionality of the distribution.
00053    */
00054   DiracMixturePdf(const unsigned int N);
00055 
00056   /**
00057    * Destructor.
00058    */
00059   virtual ~DiracMixturePdf();
00060 
00061   /**
00062    * Calculate effective sample size on the local node.
00063    *
00064    * @return Effective sample size of the components on the local node.
00065    */
00066   double calculateEss();
00067   
00068   /**
00069    * Calculate effective sample size of the full distribution.
00070    *
00071    * @return Effective sample size of the full distribution.
00072    */
00073   double calculateDistributedEss();
00074 
00075   /**
00076    * Standardise components on the local node to zero mean and identity
00077    * covariance.
00078    */
00079   virtual void standardise();
00080 
00081   /**
00082    * Standardise components on the local node using given mean and 
00083    * standard deviation.
00084    *
00085    * @param mu Mean to use for standardisation.
00086    * @param sd Standard deviation to use for standardisation.
00087    */
00088   virtual void standardise(const vector& mu,
00089       const lower_triangular_matrix& sd);
00090 
00091   /**
00092    * Standardise components on the local node using given mean and 
00093    * covariance.
00094    *
00095    * @param mu Mean to use for standardisation.
00096    * @param sigma Covariance to use for standardisation.
00097    */
00098   virtual void standardise(const vector& mu, const symmetric_matrix& sigma);
00099 
00100   /**
00101    * Standardise components across all nodes to zero mean and identity
00102    * covariance.
00103    */
00104   virtual void distributedStandardise();
00105 
00106   virtual void setDimensions(const unsigned int N,
00107       const bool preserve = false);
00108 
00109   virtual const symmetric_matrix& getCovariance();
00110 
00111   /**
00112    * Get the covariance of the full distribution.
00113    *
00114    * @return \f$\Sigma\f$; covariance of the full distribution.
00115    */
00116   symmetric_matrix getDistributedCovariance();
00117 
00118   /**
00119    * Get the standard deviation of the distribution.
00120    *
00121    * @return \f$\Sigma^{1/2}\f$; standard deviation of the distribution.
00122    */
00123   lower_triangular_matrix getStandardDeviation();
00124 
00125   /**
00126    * Get the standard deviation of the full distribution.
00127    *
00128    * @return \f$\Sigma^{1/2}\f$; standard deviation of the full
00129    * distribution.
00130    */
00131   lower_triangular_matrix getDistributedStandardDeviation();
00132 
00133   /**
00134    * Redistribute components across nodes by space. This builds a shallow
00135    * \f$kd\f$ tree distributed across all nodes such that the number of
00136    * leaves equals the number of nodes in the parallel environment. Using 
00137    * \f$n\f$th element splits, the algorithm ensures the same number of 
00138    * samples in each leaf node. Each node in the parallel environment then
00139    * adopts all the samples at one of these leaf nodes. In this way, there
00140    * is some spatial locality to all the samples on one node, ideal for 
00141    * further building of a distributed mixture of \f$kd\f$ trees using
00142    * KernelDensityMixturePdf.
00143    */
00144   void redistributeBySpace();
00145 
00146 protected:
00147   virtual void dirty();
00148 
00149 private:
00150   /**
00151    * Last calculated covariance.
00152    */
00153   symmetric_matrix sigma;
00154 
00155   /**
00156    * Last calculated unnormalized covariance.
00157    */
00158   symmetric_matrix Zsigma;
00159 
00160   /**
00161    * Is the last calculated covariance up to date?
00162    */
00163   bool haveSigma;
00164 
00165   /**
00166    * Calculate covariance from current components.
00167    */
00168   void calculateCovariance();
00169 
00170   /**
00171    * Build kd tree node for redistributeBySpace().
00172    *
00173    * @param is Indices of components over which to build tree.
00174    * @param depth Depth of the node in the tree.
00175    * @param nodes Number of nodes over which to distribute components at
00176    * this node.
00177    */
00178   KDTreeNode* distributedBuild(const std::vector<unsigned int>& is,
00179       const unsigned int depth, const unsigned int nodes);
00180 
00181   /**
00182    * Serialize.
00183    */
00184   template<class Archive>
00185   void save(Archive& ar, const unsigned int version) const;
00186 
00187   /**
00188    * Restore from serialization.
00189    */
00190   template<class Archive>
00191   void load(Archive& ar, const unsigned int version);
00192 
00193   /*
00194    * Boost.Serialization requirements.
00195    */
00196   BOOST_SERIALIZATION_SPLIT_MEMBER()
00197   friend class boost::serialization::access;
00198 
00199 };
00200 
00201     }
00202   }
00203 }
00204 
00205 #include "boost/serialization/base_object.hpp"
00206 
00207 template <class Archive>
00208 void indii::ml::aux::DiracMixturePdf::save(Archive& ar,
00209     const unsigned int version) const {
00210   ar & boost::serialization::base_object<MixturePdf<DiracPdf> >(*this);
00211 }
00212 
00213 template <class Archive>
00214 void indii::ml::aux::DiracMixturePdf::load(Archive& ar,
00215     const unsigned int version) {
00216   ar & boost::serialization::base_object<MixturePdf<DiracPdf> >(*this);
00217 
00218   sigma.resize(getDimensions(), false);
00219   Zsigma.resize(getDimensions(), false);
00220   haveSigma = false;
00221 }
00222 
00223 #endif
00224 

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