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
1.5.3