MRPT  2.0.2
distributions.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 #pragma once
10 
12 #include <mrpt/math/math_frwds.h>
13 #include <mrpt/math/ops_matrices.h>
14 #include <mrpt/math/ops_vectors.h>
15 
16 namespace mrpt::math
17 {
18 /** \addtogroup stats_grp Statistics functions, probability distributions
19  * \ingroup mrpt_math_grp
20  * @{ */
21 
22 /** Evaluates the univariate normal (Gaussian) distribution at a given point
23  * "x".
24  */
25 double normalPDF(double x, double mu, double std);
26 
27 /** Evaluates the multivariate normal (Gaussian) distribution at a given point
28  * "x".
29  * \param x A vector or column or row matrix with the point at which to
30  * evaluate the pdf.
31  * \param mu A vector or column or row matrix with the Gaussian mean.
32  * \param cov_inv The inverse covariance (information) matrix of the
33  * Gaussian.
34  * \param scaled_pdf If set to true, the PDF will be scaled to be in the
35  * range [0,1], in contrast to its integral from [-inf,+inf] being 1.
36  */
37 template <class VECTORLIKE1, class VECTORLIKE2, class MATRIXLIKE>
39  const VECTORLIKE1& x, const VECTORLIKE2& mu, const MATRIXLIKE& cov_inv,
40  const bool scaled_pdf = false)
41 {
43  using T = typename MATRIXLIKE::Scalar;
44  ASSERTDEB_(cov_inv.isSquare());
45  ASSERTDEB_(
46  size_t(cov_inv.cols()) == size_t(x.size()) &&
47  size_t(cov_inv.cols()) == size_t(mu.size()));
48  T ret = ::exp(
49  static_cast<T>(-0.5) *
50  mrpt::math::multiply_HtCH_scalar(x - mu, cov_inv));
51  return scaled_pdf
52  ? ret
53  : ret * ::sqrt(
54  cov_inv.det() / ::pow(
55  static_cast<T>(M_2PI),
56  static_cast<T>(cov_inv.rows())));
57  MRPT_END
58 }
59 
60 /** Evaluates the multivariate normal (Gaussian) distribution at a given point
61  * "x".
62  * \param x A vector or column or row matrix with the point at which to
63  * evaluate the pdf.
64  * \param mu A vector or column or row matrix with the Gaussian mean.
65  * \param cov The covariance matrix of the Gaussian.
66  * \param scaled_pdf If set to true, the PDF will be scaled to be in the
67  * range [0,1], in contrast to its integral from [-inf,+inf] being 1.
68  */
69 template <class VECTORLIKE1, class VECTORLIKE2, class MATRIXLIKE>
70 inline typename MATRIXLIKE::Scalar normalPDF(
71  const VECTORLIKE1& x, const VECTORLIKE2& mu, const MATRIXLIKE& cov,
72  const bool scaled_pdf = false)
73 {
74  return normalPDFInf(x, mu, cov.inverse(), scaled_pdf);
75 }
76 
77 /** Evaluates the multivariate normal (Gaussian) distribution at a given point
78  * given its distance vector "d" from the Gaussian mean.
79  */
80 template <typename VECTORLIKE, typename MATRIXLIKE>
82  const VECTORLIKE& d, const MATRIXLIKE& cov)
83 {
86  ASSERTDEB_(size_t(cov.cols()) == size_t(d.size()));
87  return std::exp(
88  static_cast<typename MATRIXLIKE::Scalar>(-0.5) *
90  (::pow(
91  static_cast<typename MATRIXLIKE::Scalar>(M_2PI),
92  static_cast<typename MATRIXLIKE::Scalar>(0.5 * cov.cols())) *
93  ::sqrt(cov.det()));
94  MRPT_END
95 }
96 
97 /** Kullback-Leibler divergence (KLD) between two independent multivariate
98  * Gaussians.
99  *
100  * \f$ D_\mathrm{KL}(\mathcal{N}_0 \| \mathcal{N}_1) = { 1 \over 2 } ( \log_e (
101  * { \det \Sigma_1 \over \det \Sigma_0 } ) + \mathrm{tr} ( \Sigma_1^{-1}
102  * \Sigma_0 ) + ( \mu_1 - \mu_0 )^\top \Sigma_1^{-1} ( \mu_1 - \mu_0 ) - N ) \f$
103  */
104 template <
105  typename VECTORLIKE1, typename MATRIXLIKE1, typename VECTORLIKE2,
106  typename MATRIXLIKE2>
108  const VECTORLIKE1& mu0, const MATRIXLIKE1& cov0, const VECTORLIKE2& mu1,
109  const MATRIXLIKE2& cov1)
110 {
111  MRPT_START
112  ASSERT_(
113  size_t(mu0.size()) == size_t(mu1.size()) &&
114  size_t(mu0.size()) == size_t(cov0.rows()) &&
115  size_t(mu0.size()) == size_t(cov1.cols()) && cov0.isSquare() &&
116  cov1.isSquare());
117  const size_t N = mu0.size();
118  MATRIXLIKE2 cov1_inv;
119  cov1.inverse_LLt(cov1_inv);
120  const VECTORLIKE1 mu_difs = mu0 - mu1;
121  return 0.5 * (log(cov1.det() / cov0.det()) + (cov1_inv * cov0).trace() +
122  multiply_HCHt_scalar(mu_difs, cov1_inv) - N);
123  MRPT_END
124 }
125 
126 /** Evaluates the Gaussian distribution quantile for the probability value
127  * p=[0,1].
128  * The employed approximation is that from Peter J. Acklam
129  * (pjacklam@online.no),
130  * freely available in http://home.online.no/~pjacklam.
131  */
132 double normalQuantile(double p);
133 
134 /** Evaluates the Gaussian cumulative density function.
135  * The employed approximation is that from W. J. Cody
136  * freely available in http://www.netlib.org/specfun/erf
137  * \note Equivalent to MATLAB normcdf(x,mu,s) with p=(x-mu)/s
138  */
139 double normalCDF(double p);
140 
141 /** The "quantile" of the Chi-Square distribution, for dimension "dim" and
142  * probability 0<P<1 (the inverse of chi2CDF)
143  * An aproximation from the Wilson-Hilferty transformation is used.
144  * \note Equivalent to MATLAB chi2inv(), but note that this is just an
145  * approximation, which becomes very poor for small values of "P".
146  */
147 double chi2inv(double P, unsigned int dim = 1);
148 
149 /*! Cumulative non-central chi square distribution (approximate).
150 
151  Computes approximate values of the cumulative density of a chi square
152 distribution with \a degreesOfFreedom,
153  and noncentrality parameter \a noncentrality at the given argument
154  \a arg, i.e. the probability that a random number drawn from the
155 distribution is below \a arg
156  It uses the approximate transform into a normal distribution due to Wilson
157 and Hilferty
158  (see Abramovitz, Stegun: "Handbook of Mathematical Functions", formula
159 26.3.32).
160  The algorithm's running time is independent of the inputs. The accuracy is
161 only
162  about 0.1 for few degrees of freedom, but reaches about 0.001 above dof = 5.
163 
164  \note Function code from the Vigra project
165 (http://hci.iwr.uni-heidelberg.de/vigra/); code under "MIT X11 License", GNU
166 GPL-compatible.
167 * \sa noncentralChi2PDF_CDF
168 */
169 double noncentralChi2CDF(
170  unsigned int degreesOfFreedom, double noncentrality, double arg);
171 
172 /*! Cumulative chi square distribution.
173 
174  Computes the cumulative density of a chi square distribution with \a
175  degreesOfFreedom
176  and tolerance \a accuracy at the given argument \a arg, i.e. the probability
177  that
178  a random number drawn from the distribution is below \a arg
179  by calling <tt>noncentralChi2CDF(degreesOfFreedom, 0.0, arg, accuracy)</tt>.
180 
181  \note Function code from the Vigra project
182  (http://hci.iwr.uni-heidelberg.de/vigra/); code under "MIT X11 License", GNU
183  GPL-compatible.
184 */
185 double chi2CDF(unsigned int degreesOfFreedom, double arg);
186 
187 /*! Chi square distribution PDF.
188  * Computes the density of a chi square distribution with \a degreesOfFreedom
189  * and tolerance \a accuracy at the given argument \a arg
190  * by calling <tt>noncentralChi2(degreesOfFreedom, 0.0, arg, accuracy)</tt>.
191  * \note Function code from the Vigra project
192  *(http://hci.iwr.uni-heidelberg.de/vigra/); code under "MIT X11 License", GNU
193  *GPL-compatible.
194  *
195  * \note Equivalent to MATLAB's chi2pdf(arg,degreesOfFreedom)
196  */
197 double chi2PDF(
198  unsigned int degreesOfFreedom, double arg, double accuracy = 1e-7);
199 
200 /** Returns the 'exact' PDF (first) and CDF (second) of a Non-central
201  * chi-squared probability distribution, using an iterative method.
202  * \note Equivalent to MATLAB's ncx2cdf(arg,degreesOfFreedom,noncentrality)
203  */
204 std::pair<double, double> noncentralChi2PDF_CDF(
205  unsigned int degreesOfFreedom, double noncentrality, double arg,
206  double eps = 1e-7);
207 
208 /** Return the mean and the 10%-90% confidence points (or with any other
209  * confidence value) of a set of samples by building the cummulative CDF of all
210  * the elements of the container.
211  * The container can be any MRPT container (CArray, matrices, vectors).
212  * \param confidenceInterval A number in the range (0,1) such as the confidence
213  * interval will be [100*confidenceInterval, 100*(1-confidenceInterval)].
214  */
215 template <typename CONTAINER, typename T>
217  const CONTAINER& data, T& out_mean, T& out_lower_conf_interval,
218  T& out_upper_conf_interval, const double confidenceInterval = 0.1,
219  const size_t histogramNumBins = 1000)
220 {
221  MRPT_START
222  // don't use .empty() here to allow using matrices
223  ASSERT_(data.size() != 0);
224  ASSERT_(confidenceInterval > 0 && confidenceInterval < 1);
225 
226  out_mean = mean(data);
227  const auto x_min = data.minCoeff();
228  const auto x_max = data.maxCoeff();
229  const auto binWidth = (x_max - x_min) / histogramNumBins;
230 
231  const std::vector<double> H =
232  mrpt::math::histogram(data, x_min, x_max, histogramNumBins);
233  std::vector<double> Hc;
234  cumsum(H, Hc); // CDF
235  Hc *= 1.0 / mrpt::math::maximum(Hc);
236 
237  auto it_low = std::lower_bound(Hc.begin(), Hc.end(), confidenceInterval);
238  ASSERT_(it_low != Hc.end());
239  auto it_high =
240  std::upper_bound(Hc.begin(), Hc.end(), 1 - confidenceInterval);
241  ASSERT_(it_high != Hc.end());
242  const size_t idx_low = std::distance(Hc.begin(), it_low);
243  const size_t idx_high = std::distance(Hc.begin(), it_high);
244  out_lower_conf_interval = x_min + idx_low * binWidth;
245  out_upper_conf_interval = x_min + idx_high * binWidth;
246 
247  MRPT_END
248 }
249 
250 /** @} */
251 
252 } // namespace mrpt::math
MAT_C::Scalar multiply_HtCH_scalar(const VECTOR_H &H, const MAT_C &C)
r (scalar) = H^t*C*H (H: column vector, C: symmetric matrix)
Definition: ops_matrices.h:54
double Scalar
Definition: KmUtils.h:43
#define MRPT_START
Definition: exceptions.h:241
#define M_2PI
Definition: common.h:58
double normalCDF(double p)
Evaluates the Gaussian cumulative density function.
Definition: math.cpp:134
This file implements miscelaneous matrix and matrix/vector operations, and internal functions in mrpt...
MAT_C::Scalar multiply_HCHt_scalar(const VECTOR_H &H, const MAT_C &C)
r (scalar) = H*C*H^t (H: row vector, C: symmetric matrix)
Definition: ops_matrices.h:63
bool isSquare() const
returns true if matrix is NxN
STL namespace.
double KLD_Gaussians(const VECTORLIKE1 &mu0, const MATRIXLIKE1 &cov0, const VECTORLIKE2 &mu1, const MATRIXLIKE2 &cov1)
Kullback-Leibler divergence (KLD) between two independent multivariate Gaussians. ...
double normalQuantile(double p)
Evaluates the Gaussian distribution quantile for the probability value p=[0,1].
Definition: math.cpp:80
#define ASSERT_(f)
Defines an assertion mechanism.
Definition: exceptions.h:120
This base provides a set of functions for maths stuff.
std::pair< double, double > noncentralChi2PDF_CDF(unsigned int degreesOfFreedom, double noncentrality, double arg, double eps=1e-7)
Returns the &#39;exact&#39; PDF (first) and CDF (second) of a Non-central chi-squared probability distributio...
Definition: math.cpp:528
Derived inverse() const
Returns the inverse of a general matrix using LU.
void confidenceIntervals(const CONTAINER &data, T &out_mean, T &out_lower_conf_interval, T &out_upper_conf_interval, const double confidenceInterval=0.1, const size_t histogramNumBins=1000)
Return the mean and the 10%-90% confidence points (or with any other confidence value) of a set of sa...
double chi2PDF(unsigned int degreesOfFreedom, double arg, double accuracy=1e-7)
Definition: math.cpp:595
CONTAINER::Scalar maximum(const CONTAINER &v)
const double eps
Scalar det() const
Determinant of matrix.
Derived inverse_LLt() const
Returns the inverse of a symmetric matrix using LLt.
CMatrixDouble cov(const MATRIX &v)
Computes the covariance matrix from a list of samples in an NxM matrix, where each row is a sample...
Definition: ops_matrices.h:149
size_type cols() const
Number of columns in the matrix.
MATRIXLIKE::Scalar normalPDFInf(const VECTORLIKE1 &x, const VECTORLIKE2 &mu, const MATRIXLIKE &cov_inv, const bool scaled_pdf=false)
Evaluates the multivariate normal (Gaussian) distribution at a given point "x".
Definition: distributions.h:38
void cumsum(const CONTAINER1 &in_data, CONTAINER2 &out_cumsum)
double chi2CDF(unsigned int degreesOfFreedom, double arg)
Definition: math.cpp:505
double chi2inv(double P, unsigned int dim=1)
The "quantile" of the Chi-Square distribution, for dimension "dim" and probability 0<P<1 (the inverse...
Definition: math.cpp:42
#define ASSERTDEB_(f)
Defines an assertion mechanism - only when compiled in debug.
Definition: exceptions.h:190
#define MRPT_END
Definition: exceptions.h:245
std::vector< double > histogram(const CONTAINER &v, double limit_min, double limit_max, size_t number_bins, bool do_normalization=false, std::vector< double > *out_bin_centers=nullptr)
Computes the normalized or normal histogram of a sequence of numbers given the number of bins and the...
double mean(const CONTAINER &v)
Computes the mean value of a vector.
double noncentralChi2CDF(unsigned int degreesOfFreedom, double noncentrality, double arg)
Definition: math.cpp:603
double normalPDF(double x, double mu, double std)
Evaluates the univariate normal (Gaussian) distribution at a given point "x".
Definition: math.cpp:33
double distance(const TPoint2D &p1, const TPoint2D &p2)
Gets the distance between two points in a 2D space.
Definition: geometry.cpp:1807
static struct FontData data
Definition: gltext.cpp:144



Page generated by Doxygen 1.8.14 for MRPT 2.0.2 Git: 9b4fd2465 Mon May 4 16:59:08 2020 +0200 at lun may 4 17:26:07 CEST 2020