9 #ifndef MRPT_DATA_UTILS_MATH_H 10 #define MRPT_DATA_UTILS_MATH_H 35 template <
class VECTORLIKE1,
class VECTORLIKE2,
class MAT>
37 const VECTORLIKE1& X,
const VECTORLIKE2& MU,
const MAT& COV)
40 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES) 43 ASSERT_(X.size() ==
size(COV, 1) && COV.isSquare());
45 const size_t N = X.size();
46 Eigen::Matrix<typename MAT::Scalar, Eigen::Dynamic, 1> X_MU(N);
47 for (
size_t i = 0; i < N; i++) X_MU[i] = X[i] - MU[i];
48 const Eigen::Matrix<typename MAT::Scalar, Eigen::Dynamic, 1>
z =
49 COV.llt().solve(X_MU);
58 template <
class VECTORLIKE1,
class VECTORLIKE2,
class MAT>
60 const VECTORLIKE1& X,
const VECTORLIKE2& MU,
const MAT& COV)
71 template <
class VECTORLIKE,
class MAT1,
class MAT2,
class MAT3>
73 const VECTORLIKE& mean_diffs,
const MAT1& COV1,
const MAT2& COV2,
74 const MAT3& CROSS_COV12)
77 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES) 80 ASSERT_(COV1.isSquare() && COV2.isSquare());
85 COV.substract_An(CROSS_COV12, 2);
87 COV.inv_fast(COV_inv);
98 template <
class VECTORLIKE,
class MAT1,
class MAT2,
class MAT3>
100 const VECTORLIKE& mean_diffs,
const MAT1& COV1,
const MAT2& COV2,
101 const MAT3& CROSS_COV12)
111 template <
class VECTORLIKE,
class MATRIXLIKE>
113 const VECTORLIKE& delta_mu,
const MATRIXLIKE&
cov)
116 ASSERTDEB_(
size_t(
cov.getColCount()) ==
size_t(delta_mu.size()))
125 template <
class VECTORLIKE,
class MATRIXLIKE>
127 const VECTORLIKE& delta_mu,
const MATRIXLIKE&
cov)
137 template <
typename T>
142 const size_t vector_dim = mean_diffs.size();
147 const T cov_det = C.det();
151 return std::pow(
M_2PI, -0.5 * vector_dim) * (1.0 / std::sqrt(cov_det)) *
152 exp(-0.5 * mean_diffs.multiply_HCHt_scalar(C_inv));
160 template <
typename T,
size_t DIM>
162 const std::vector<T>& mean_diffs,
166 ASSERT_(mean_diffs.size() == DIM);
170 const T cov_det = C.det();
174 return std::pow(
M_2PI, -0.5 * DIM) * (1.0 / std::sqrt(cov_det)) *
175 exp(-0.5 * mean_diffs.multiply_HCHt_scalar(C_inv));
182 template <
typename T,
class VECLIKE,
class MATLIKE1,
class MATLIKE2>
184 const VECLIKE& mean_diffs,
const MATLIKE1& COV1,
const MATLIKE2& COV2,
185 T& maha2_out, T& intprod_out,
const MATLIKE1* CROSS_COV12 =
nullptr)
187 const size_t vector_dim = mean_diffs.size();
197 const T cov_det = C.det();
201 maha2_out = mean_diffs.multiply_HCHt_scalar(C_inv);
202 intprod_out = std::pow(
M_2PI, -0.5 * vector_dim) *
203 (1.0 / std::sqrt(cov_det)) * exp(-0.5 * maha2_out);
211 template <
typename T,
class VECLIKE,
class MATRIXLIKE>
213 const VECLIKE& diff_mean,
const MATRIXLIKE&
cov, T& maha2_out,
218 ASSERTDEB_(
size_t(
cov.getColCount()) ==
size_t(diff_mean.size()))
225 ::log(static_cast<typename MATRIXLIKE::Scalar>(
M_2PI)) +
234 template <
typename T,
class VECLIKE,
class MATRIXLIKE>
236 const VECLIKE& diff_mean,
const MATRIXLIKE&
cov, T& maha2_out, T& pdf_out)
239 pdf_out = std::exp(pdf_out);
262 template<
class VECTOR_OF_VECTORS,
class MATRIXLIKE,
class VECTORLIKE,
class VECTORLIKE2,
class VECTORLIKE3>
264 const VECTOR_OF_VECTORS &elements,
265 MATRIXLIKE &covariances,
267 const VECTORLIKE2 *weights_mean,
268 const VECTORLIKE3 *weights_cov,
269 const bool *elem_do_wrap2pi =
nullptr 273 elements.size() != 0,
274 "No samples provided, so there is no way to deduce the output size.")
276 const size_t DIM = elements[0].size();
278 covariances.setSize(DIM, DIM);
279 const size_t nElms = elements.size();
280 const T NORM = 1.0 / nElms;
283 ASSERTDEB_(
size_t(weights_mean->size()) ==
size_t(nElms))
286 for (
size_t i = 0; i < DIM; i++)
289 if (!elem_do_wrap2pi || !elem_do_wrap2pi[i])
293 for (
size_t j = 0; j < nElms; j++)
294 accum += (*weights_mean)[j] * elements[j][i];
298 for (
size_t j = 0; j < nElms; j++) accum += elements[j][i];
305 double accum_L = 0, accum_R = 0;
306 double Waccum_L = 0, Waccum_R = 0;
307 for (
size_t j = 0; j < nElms; j++)
309 double ang = elements[j][i];
311 weights_mean !=
nullptr ? (*weights_mean)[j] : NORM;
312 if (fabs(ang) > 0.5 *
M_PI)
314 if (ang < 0) ang = (
M_2PI + ang);
324 if (Waccum_L > 0) accum_L /= Waccum_L;
325 if (Waccum_R > 0) accum_R /= Waccum_R;
329 (accum_L * Waccum_L +
335 for (
size_t i = 0; i < DIM; i++)
336 for (
size_t j = 0; j <= i; j++)
341 ASSERTDEB_(
size_t(weights_cov->size()) ==
size_t(nElms))
342 for (
size_t k = 0; k < nElms; k++)
344 const T Ai = (elements[k][i] - means[i]);
345 const T Aj = (elements[k][j] - means[j]);
346 if (!elem_do_wrap2pi || !elem_do_wrap2pi[i])
347 elem += (*weights_cov)[k] * Ai * Aj;
355 for (
size_t k = 0; k < nElms; k++)
357 const T Ai = (elements[k][i] - means[i]);
358 const T Aj = (elements[k][j] - means[j]);
359 if (!elem_do_wrap2pi || !elem_do_wrap2pi[i])
367 covariances.get_unsafe(i, j) = elem;
368 if (i != j) covariances.get_unsafe(j, i) = elem;
385 template <
class VECTOR_OF_VECTORS,
class MATRIXLIKE,
class VECTORLIKE>
387 const VECTOR_OF_VECTORS& elements, MATRIXLIKE& covariances,
388 VECTORLIKE& means,
const bool* elem_do_wrap2pi =
nullptr)
392 elements, covariances, means,
nullptr,
nullptr, elem_do_wrap2pi);
407 template <
class VECTORLIKE1,
class VECTORLIKE2>
409 const VECTORLIKE1&
values,
const VECTORLIKE1&
weights,
float binWidth,
410 VECTORLIKE2& out_binCenters, VECTORLIKE2& out_binValues)
419 static_cast<unsigned>(ceil((
maximum(
values) - minBin) / binWidth));
422 out_binCenters.resize(nBins);
423 out_binValues.clear();
424 out_binValues.resize(nBins, 0);
425 TNum halfBin = TNum(0.5) * binWidth;
427 VECTORLIKE2 binBorders(nBins + 1, minBin - halfBin);
428 for (
unsigned int i = 0; i < nBins; i++)
430 binBorders[i + 1] = binBorders[i] + binWidth;
431 out_binCenters[i] = binBorders[i] + halfBin;
440 int idx =
round(((*itVal) - minBin) / binWidth);
441 if (idx >=
int(nBins)) idx = nBins - 1;
443 out_binValues[idx] += *itW;
447 if (totalSum) out_binValues /= totalSum;
464 template <
class VECTORLIKE1,
class VECTORLIKE2>
466 const VECTORLIKE1&
values,
const VECTORLIKE1& log_weights,
float binWidth,
467 VECTORLIKE2& out_binCenters, VECTORLIKE2& out_binValues)
476 static_cast<unsigned>(ceil((
maximum(
values) - minBin) / binWidth));
479 out_binCenters.resize(nBins);
480 out_binValues.clear();
481 out_binValues.resize(nBins, 0);
482 TNum halfBin = TNum(0.5) * binWidth;
484 VECTORLIKE2 binBorders(nBins + 1, minBin - halfBin);
485 for (
unsigned int i = 0; i < nBins; i++)
487 binBorders[i + 1] = binBorders[i] + binWidth;
488 out_binCenters[i] = binBorders[i] + halfBin;
492 const TNum max_log_weight =
maximum(log_weights);
495 for (itVal =
values.begin(), itW = log_weights.begin();
496 itVal !=
values.end(); ++itVal, ++itW)
498 int idx =
round(((*itVal) - minBin) / binWidth);
499 if (idx >=
int(nBins)) idx = nBins - 1;
501 const TNum
w = exp(*itW - max_log_weight);
502 out_binValues[idx] +=
w;
506 if (totalSum) out_binValues /= totalSum;
void mahalanobisDistance2AndPDF(const VECLIKE &diff_mean, const MATRIXLIKE &cov, T &maha2_out, T &pdf_out)
Computes both, the PDF and the square Mahalanobis distance between a point (given by its difference w...
double averageWrap2Pi(const CVectorDouble &angles)
Computes the average of a sequence of angles in radians taking into account the correct wrapping in t...
GLboolean GLenum GLenum GLvoid * values
size_t size(const MATRIXLIKE &m, const int dim)
Column vector, like Eigen::MatrixX*, but automatically initialized to zeros since construction...
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 (a scalar) = H * C * H^t (with a vector H and a symmetric matrix C)
const Scalar * const_iterator
void productIntegralAndMahalanobisTwoGaussians(const VECLIKE &mean_diffs, const MATLIKE1 &COV1, const MATLIKE2 &COV2, T &maha2_out, T &intprod_out, const MATLIKE1 *CROSS_COV12=nullptr)
Computes both, the integral of the product of two Gaussians and their square Mahalanobis distance...
GLubyte GLubyte GLubyte GLubyte w
CONTAINER::Scalar minimum(const CONTAINER &v)
A numeric matrix of compile-time fixed size.
void mahalanobisDistance2AndLogPDF(const VECLIKE &diff_mean, const MATRIXLIKE &cov, T &maha2_out, T &log_pdf_out)
Computes both, the logarithm of the PDF and the square Mahalanobis distance between a point (given by...
void covariancesAndMean(const VECTOR_OF_VECTORS &elements, MATRIXLIKE &covariances, VECTORLIKE &means, const bool *elem_do_wrap2pi=nullptr)
Computes covariances and mean of any vector of containers.
double averageLogLikelihood(const CVectorDouble &logLikelihoods)
A numerically-stable method to compute average likelihood values with strongly different ranges (unwe...
CONTAINER::Scalar maximum(const CONTAINER &v)
T wrapToPi(T a)
Modifies the given angle to translate it into the ]-pi,pi] range.
MAT::Scalar mahalanobisDistance2(const VECTORLIKE1 &X, const VECTORLIKE2 &MU, const MAT &COV)
Computes the squared mahalanobis distance of a vector X given the mean MU and the covariance inverse ...
void weightedHistogram(const VECTORLIKE1 &values, const VECTORLIKE1 &weights, float binWidth, VECTORLIKE2 &out_binCenters, VECTORLIKE2 &out_binValues)
Computes the weighted histogram for a vector of values and their corresponding weights.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
#define ASSERTDEB_(f)
Defines an assertion mechanism - only when compiled in debug.
void covariancesAndMeanWeighted(const VECTOR_OF_VECTORS &elements, MATRIXLIKE &covariances, VECTORLIKE &means, const VECTORLIKE2 *weights_mean, const VECTORLIKE3 *weights_cov, const bool *elem_do_wrap2pi=nullptr)
Computes covariances and mean of any vector of containers, given optional weights for the different s...
VECTORLIKE1::Scalar mahalanobisDistance(const VECTORLIKE1 &X, const VECTORLIKE2 &MU, const MAT &COV)
Computes the mahalanobis distance of a vector X given the mean MU and the covariance inverse COV_inv ...
T productIntegralTwoGaussians(const std::vector< T > &mean_diffs, const CMatrixTemplateNumeric< T > &COV1, const CMatrixTemplateNumeric< T > &COV2)
Computes the integral of the product of two Gaussians, with means separated by "mean_diffs" and covar...
A matrix of dynamic size.
int round(const T value)
Returns the closer integer (int) to x.
CONTAINER::value_type element_t
Eigen::Matrix< typename MATRIX::Scalar, MATRIX::ColsAtCompileTime, MATRIX::ColsAtCompileTime > cov(const MATRIX &v)
Computes the covariance matrix from a list of samples in an NxM matrix, where each row is a sample...
dynamic_vector< double > CVectorDouble
Column vector, like Eigen::MatrixXd, but automatically initialized to zeros since construction...
void weightedHistogramLog(const VECTORLIKE1 &values, const VECTORLIKE1 &log_weights, float binWidth, VECTORLIKE2 &out_binCenters, VECTORLIKE2 &out_binValues)
Computes the weighted histogram for a vector of values and their corresponding log-weights.
#define ASSERTMSG_(f, __ERROR_MSG)