bpp-core3  3.0.0
AdaptiveKernelDensityEstimation.cpp
Go to the documentation of this file.
1 //
2 // File: AdaptiveKernelDensityEstimation.cpp
3 // Authors:
4 // Julien Dutheil
5 // Created: 2009-11-05 13:25:07
6 //
7 
8 /*
9  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
10 
11  This software is a computer program whose purpose is to provide classes
12  for numerical calculus. This file is part of the Bio++ project.
13 
14  This software is governed by the CeCILL license under French law and
15  abiding by the rules of distribution of free software. You can use,
16  modify and/ or redistribute the software under the terms of the CeCILL
17  license as circulated by CEA, CNRS and INRIA at the following URL
18  "http://www.cecill.info".
19 
20  As a counterpart to the access to the source code and rights to copy,
21  modify and redistribute granted by the license, users are provided only
22  with a limited warranty and the software's author, the holder of the
23  economic rights, and the successive licensors have only limited
24  liability.
25 
26  In this respect, the user's attention is drawn to the risks associated
27  with loading, using, modifying and/or developing or reproducing the
28  software by the user in light of its specific status of free software,
29  that may mean that it is complicated to manipulate, and that also
30  therefore means that it is reserved for developers and experienced
31  professionals having in-depth computer knowledge. Users are therefore
32  encouraged to load and test the software's suitability as regards their
33  requirements in conditions enabling the security of their systems and/or
34  data to be ensured and, more generally, to use and operate it in the
35  same conditions as regards security.
36 
37  The fact that you are presently reading this means that you have had
38  knowledge of the CeCILL license and that you accept its terms.
39 */
40 
41 
43 #include "Matrix/MatrixTools.h"
44 #include "NumConstants.h"
45 
46 using namespace bpp;
47 using namespace std;
48 
50 {
51  // Compute the covariance matrix of the sample:
52  MatrixTools::covar(x_, covar_);
53 
54  // Compute the mean vector
55  sampleMean_(x_, xMean_);
56 
57  // Compute the inverse of the square root of the covariance matrix:
58  MatrixTools::pow<double>(covar_, -0.5, invSqrtCovar_);
59 
60  // Compute the bandwidth:
61  h_ = std::pow(4. / ((2 * static_cast<double>(r_) + 1.) * static_cast<double>(n_)), 1. / (static_cast<double>(r_) + 4.));
62  // Compute as much as we can in advance to simplify the density calculation:
63  c1_ = 1. / (std::sqrt(MatrixTools::det(covar_)) * static_cast<double>(n_) * std::pow(h_, static_cast<int>(r_)));
64 
65  // Now compute the local tuning of the bandwidth.
66  // First estimate the pilot density:
67  vector<double> xi(r_);
68  LinearMatrix<double> diff_xi(r_, 1);
69  LinearMatrix<double> std_xi(r_, 1);
70  for (unsigned int i = 0; i < n_; i++)
71  {
72  // Get the current xi point to evaluate:
73  for (unsigned int k = 0; k < r_; k++)
74  {
75  xi[k] = x_(k, i);
76  }
77 
78  // Sum loop, over all xi's:
79  double sum = 0;
80  for (unsigned int j = 0; j < n_; j++)
81  {
82  for (unsigned int k = 0; k < r_; k++)
83  {
84  diff_xi(k, 0) = xi[k] - x_(k, j);
85  }
86  MatrixTools::mult(invSqrtCovar_, diff_xi, std_xi);
87  MatrixTools::scale(std_xi, 1. / h_);
88  sum += kernel_(std_xi);
89  }
90  pilot_[i] = c1_ * sum;
91  }
92 
93  // Compute the tuning parameters:
94  double g = 0;
95  for (unsigned int i = 0; i < n_; i++)
96  {
97  g += std::log(pilot_[i]);
98  }
99  g = std::exp(g / static_cast<double>(n_));
100  for (unsigned int i = 0; i < n_; i++)
101  {
102  lambda_[i] = std::pow(g / pilot_[i], gamma_);
103  }
104 
105  // Compute as much as we can in advance to simplify the density calculation:
106  for (unsigned int i = 0; i < n_; i++)
107  {
108  c2_[i] = std::pow(lambda_[i], -static_cast<double>(r_));
109  }
110 }
111 
112 void AdaptiveKernelDensityEstimation::sampleMean_(const Matrix<double>& x, std::vector<double>& mean)
113 {
114  size_t nc = x.getNumberOfColumns();
115  size_t nr = x.getNumberOfRows();
116  mean.resize(nr);
117  for (size_t i = 0; i < nr; i++)
118  {
119  mean[i] = 0;
120  for (size_t j = 0; j < nc; j++)
121  {
122  mean[i] += x(i, j);
123  }
124  mean[i] /= static_cast<double>(nc);
125  }
126 }
127 
129 {
130  // x is supposed to have only one column and r_ rows.
131  // We compute the scalar product of the column with itself:
132  double scalar = 0;
133  for (size_t i = 0; i < r_; i++)
134  {
135  scalar += std::pow(x(i, 0), 2.);
136  }
137 
138  return std::pow(2. * NumConstants::PI(), -static_cast<double>(r_) / 2.) * std::exp(-0.5 * scalar);
139 }
140 
141 double AdaptiveKernelDensityEstimation::kDensity(const std::vector<double>& x)
142 {
143  LinearMatrix<double> diff_xi(r_, 1);
144  LinearMatrix<double> std_xi(r_, 1);
145  // Sum loop, over all xi's:
146  double sum = 0;
147  for (unsigned int j = 0; j < n_; j++)
148  {
149  for (unsigned int k = 0; k < r_; k++)
150  {
151  diff_xi(k, 0) = x[k] - x_(k, j);
152  }
153  MatrixTools::mult(invSqrtCovar_, diff_xi, std_xi);
154  MatrixTools::scale(std_xi, 1. / (h_ * lambda_[j]));
155  sum += kernel_(std_xi) * c2_[j];
156  }
157  return c1_ * sum;
158 }
void sampleMean_(const Matrix< double > &x, std::vector< double > &mean)
double kernel_(const Matrix< double > &x)
The kernel function.
double kDensity(const std::vector< double > &x)
Matrix storage in one vector.
Definition: Matrix.h:357
static void mult(const Matrix< Scalar > &A, const Matrix< Scalar > &B, Matrix< Scalar > &O)
Definition: MatrixTools.h:256
static void covar(const Matrix< Scalar > &A, Matrix< Scalar > &O)
Compute the variance-covariance matrix of an input matrix.
Definition: MatrixTools.h:912
static void scale(Matrix &A, Scalar a, Scalar b=0)
Multiply all elements of a matrix by a given value, and add a constant.
Definition: MatrixTools.h:239
static double det(const Matrix< Scalar > &A)
Get determinant of a square matrix.
Definition: MatrixTools.h:854
The matrix template interface.
Definition: Matrix.h:61
virtual size_t getNumberOfColumns() const =0
virtual size_t getNumberOfRows() const =0
static double PI()
Definition: NumConstants.h:97