⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kerneldensitypdf.hpp

📁 dysii is a C++ library for distributed probabilistic inference and learning in large-scale dynamical
💻 HPP
字号:
#ifndef INDII_ML_AUX_KERNELDENSITYPDF_HPP#define INDII_ML_AUX_KERNELDENSITYPDF_HPP#include "Pdf.hpp"#include "PartitionTree.hpp"#include "Almost2Norm.hpp"#include "AlmostGaussianKernel.hpp"#include "kde.hpp"namespace indii {  namespace ml {    namespace aux {/** * %Kernel density estimator. * * @author Lawrence Murray <lawrence@indii.org> * @version $Rev: 584 $ * @date $Date: 2008-12-15 17:26:36 +0000 (Mon, 15 Dec 2008) $ * * @param NT Norm type. * @param KT Kernel type. * * The kernel density estimator is constructed over a KDTree for efficient * evaluations. After construction, it acts as any other Pdf. * * @section Serialization * * This class supports serialization through the Boost.Serialization * library. * * @section KernelDensityPdf_references References *  * @anchor Silverman1986 * Silverman, B.W. <i>Density Estimation for Statistics and Data * Analysis</i>. Chapman and Hall, <b>1986</b>. */template <class NT = Almost2Norm, class KT = AlmostGaussianKernel>class KernelDensityPdf : public Pdf {public:  /**   * Default constructor.   *   * Initialises the distribution with zero dimensions. This should   * generally only be used when the object is to be restored from a   * serialization.   */  KernelDensityPdf();  /**   * Constructor.   *   * @param tree Partition tree over which to define distribution. Caller   * has ownership.   * @param N \f$\|\mathbf{x}\|_p\f$; a norm.   * @param K \f$K(\|\mathbf{x}\|_p) \f$; density kernel.   */  KernelDensityPdf(PartitionTree* tree, const NT& N, const KT& K);    /**   * Destructor.   */  virtual ~KernelDensityPdf();  /**   * Not supported.   *   * @see Pdf::setDimensions()   */  virtual void setDimensions(const unsigned int N,      const bool preserve = false);  virtual const vector& getExpectation();  virtual const symmetric_matrix& getCovariance();  virtual vector sample();  virtual double densityAt(const vector& x);  /**   * Calculate the density for all points in a tree.   *   * @param tree Query tree.   *   * @return Density at all points in the tree, ordered according to the    * underlying DiracMixturePdf ordering.   *   * Uses a dual-tree algorithm to efficiently calculate the density at   * all points in the query tree.   */  vector densityAt(PartitionTree& tree);private:  /**   * Partition tree.   */  PartitionTree* tree;    /**   * \f$\|\mathbf{x}\|_p\f$; the norm.   */  NT N;    /**   * \f$K(\|\mathbf{x}\|_p) \f$; the density kernel.   */  KT K;    /**   * \f$\mathbf{\mu}\f$; the mean.   */  vector mu;    /**   * \f$\Sigma\f$; the covariance.   */  symmetric_matrix sigma;  /**   * Has the mean been calculated?   */  bool haveMu;    /**   * Has the covariance been calculated?   */  bool haveSigma;    /**   * Calculate the mean.   */  void calculateExpectation();    /**   * Calculate the covariance.   */  void calculateCovariance();    /**   * Serialize.   */  template<class Archive>  void save(Archive& ar, const unsigned int version) const;  /**   * Restore from serialization.   */  template<class Archive>  void load(Archive& ar, const unsigned int version);  /*   * Boost.Serialization requirements.   */  BOOST_SERIALIZATION_SPLIT_MEMBER()  friend class boost::serialization::access;};    }  }}#include "boost/serialization/base_object.hpp"#include <stack>template <class NT, class KT>indii::ml::aux::KernelDensityPdf<NT,KT>::KernelDensityPdf() : tree(NULL),    mu(0), sigma(0), haveMu(false), haveSigma(false) {  //}template <class NT, class KT>indii::ml::aux::KernelDensityPdf<NT,KT>::KernelDensityPdf(    PartitionTree* tree, const NT& N, const KT& K) :    Pdf(tree->getData()->getDimensions()), tree(tree), N(N), K(K),    mu(tree->getData()->getDimensions()),    sigma(tree->getData()->getDimensions()), haveMu(false), haveSigma(false) {  //}  template <class NT, class KT>indii::ml::aux::KernelDensityPdf<NT,KT>::~KernelDensityPdf() {  //}template <class NT, class KT>void indii::ml::aux::KernelDensityPdf<NT,KT>::setDimensions(    const unsigned int N, const bool preserve) {  assert (false);}template <class NT, class KT>const indii::ml::aux::vector&    indii::ml::aux::KernelDensityPdf<NT,KT>::getExpectation() {  if (!haveMu) {    calculateExpectation();    assert (haveMu);  }  return mu;}template <class NT, class KT>const indii::ml::aux::symmetric_matrix&    indii::ml::aux::KernelDensityPdf<NT,KT>::getCovariance() {  if (!haveSigma) {    calculateCovariance();    assert (haveSigma);  }  return sigma;}template <class NT, class KT>indii::ml::aux::vector indii::ml::aux::KernelDensityPdf<NT,KT>::sample() {  /* pre-condition */  assert (tree != NULL);  /* sampling from the underlying weighted sample set and adding a kernel   * sample is more efficient than working down the tree. */  return tree->getData()->sample() + K.sample() * N.sample(getDimensions());}template <class NT, class KT>double indii::ml::aux::KernelDensityPdf<NT,KT>::densityAt(const vector& x) {  if (tree->getRoot() == NULL) {    return 0.0;  }  PartitionTreeNode* node = tree->getRoot();  DiracMixturePdf* p = tree->getData();  std::stack<PartitionTreeNode*> nodes;  vector d(x.size());  double result = 0.0;  std::vector<unsigned int> is;  unsigned int i;  nodes.push(node);  while (!nodes.empty()) {    node = nodes.top();    nodes.pop();        if (node->isLeaf()) {      i = node->getIndex();      noalias(d) = p->get(i) - x;      result += p->getWeight(i) * K(N(d));    } else if (node->isPrune()) {      is = node->getIndices();      for (i = 0; i < is.size(); i++) {        noalias(d) = p->get(is[i]) - x;        result += p->getWeight(is[i]) * K(N(d));      }    } else {      /* should we recurse? */      node->difference(x, d);      if (K(N(d)) > 0.0) {        nodes.push(node->getLeft());        nodes.push(node->getRight());      }     }  }    return result / p->getTotalWeight();}template <class NT, class KT>indii::ml::aux::vector    indii::ml::aux::KernelDensityPdf<NT,KT>::densityAt(PartitionTree& tree) {  /* pre-condition */  assert (getDimensions() == tree.getData()->getDimensions());  return aux::dualTreeDensity(tree, *this->tree,      this->tree->getData()->getWeights(), N, K);}template <class NT, class KT>void indii::ml::aux::KernelDensityPdf<NT,KT>::calculateExpectation() {  std::vector<PartitionTreeNode*> nodes;  PartitionTreeNode* node = tree->getRoot();  DiracMixturePdf* p = tree->getData();  assert (node != NULL);  std::vector<unsigned int> is;  unsigned int i;  mu.clear();  nodes.push_back(node);  while (!nodes.empty()) {    node = nodes.back();    nodes.pop_back();    if (node->isLeaf()) {      i = node->getIndex();      mu += p->getWeight(i) * p->get(i);    } else if (node->isPrune()) {      is = node->getIndices();      for (i = 0; i < is.size(); i++) {        mu += p->getWeight(is[i]) * p->get(is[i]);      }    } else {      /* recurse */      nodes.push_back(node->getLeft());      nodes.push_back(node->getRight());    }  }    mu /= p->getTotalWeight();  haveMu = true;}template <class NT, class KT>void indii::ml::aux::KernelDensityPdf<NT,KT>::calculateCovariance() {  if (!haveMu) {    calculateExpectation();    assert (haveMu);  }   std::vector<PartitionTreeNode*> nodes;  PartitionTreeNode* node = tree->getRoot();  DiracMixturePdf* p = tree->getData();  assert (node != NULL);  std::vector<unsigned int> is;  unsigned int i;  sigma.clear();  nodes.push_back(node);  while (!nodes.empty()) {    node = nodes.back();    nodes.pop_back();    if (node->isLeaf()) {      i = node->getIndex();      vector& x = p->get(i);      sigma += p->getWeight(i) * outer_prod(x, x);    } else if (node->isPrune()) {      is = node->getIndices();      for (i = 0; i < is.size(); i++) {        vector& x = p->get(is[i]);        sigma += p->getWeight(is[i]) * outer_prod(x, x);      }    } else {      /* recurse */      nodes.push_back(node->getLeft());      nodes.push_back(node->getRight());    }  }    sigma /= p->getTotalWeight();  noalias(sigma) -= outer_prod(mu, mu);  haveSigma = true;}template <class NT, class KT>template <class Archive>void indii::ml::aux::KernelDensityPdf<NT,KT>::save(Archive& ar,    const unsigned int version) const {  ar & boost::serialization::base_object<Pdf>(*this);  ar & tree;  ar & N;  ar & K;}template <class NT, class KT>template <class Archive>void indii::ml::aux::KernelDensityPdf<NT,KT>::load(Archive& ar,    const unsigned int version) {  ar & boost::serialization::base_object<Pdf>(*this);  ar & tree;  ar & N;  ar & K;  mu.resize(tree->getData()->getDimensions(), false);  sigma.resize(tree->getData()->getDimensions(), false);  haveMu = false;  haveSigma = false;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -