math.cpp
Go to the documentation of this file.
1#include "math.h"
2
3#include <Eigen/Eigenvalues>
4
6{
7
8 MultivariateNormal::MultivariateNormal(const Eigen::VectorXf& mu, float std)
9 {
10 mean = mu;
11 covariance = Eigen::MatrixXf::Identity(mean.size(), mean.size()) * std::pow(std, 2);
12 }
13
14 float
15 MultivariateNormal::pdf(const Eigen::VectorXf& x) const
16 {
17 float n = x.rows();
18 float sqrt2pi = std::sqrt(2 * M_PI);
19 float quadform = (x - mean).transpose() * covariance.inverse() * (x - mean);
20 float norm = std::pow(sqrt2pi, -n) * std::pow(covariance.determinant(), -0.5);
21
22 return norm * exp(-0.5 * quadform);
23 }
24
25 Eigen::VectorXf
26 MultivariateNormal::pdf_gradient(const Eigen::VectorXf& x) const
27 {
28 float probability = pdf(x);
29 return -probability * (x - mean) / covariance.determinant();
30 }
31
32 Eigen::VectorXf
33 MultivariateNormal::sample(unsigned int nr_iterations) const
34 {
35 int n = mean.rows();
36
37 // Generate x from the N(0, I) distribution
38 Eigen::VectorXf x(n);
39 Eigen::VectorXf sum(n);
40 sum.setZero();
41 for (unsigned int i = 0; i < nr_iterations; i++)
42 {
43 x.setRandom();
44 x = 0.5 * (x + Eigen::VectorXf::Ones(n));
45 sum = sum + x;
46 }
47 sum = sum - (static_cast<double>(nr_iterations) / 2) * Eigen::VectorXf::Ones(n);
48 x = sum / (std::sqrt(static_cast<double>(nr_iterations) / 12));
49
50 // Find the eigen vectors of the covariance matrix
51 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXf> eigen_solver(covariance);
52 Eigen::MatrixXf eigenvectors = eigen_solver.eigenvectors().real();
53
54 // Find the eigenvalues of the covariance matrix
55 Eigen::MatrixXf eigenvalues = eigen_solver.eigenvalues().real().asDiagonal();
56
57 // Find the transformation matrix
58 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXf> es(eigenvalues);
59 Eigen::MatrixXf sqrt_eigenvalues = es.operatorSqrt();
60 Eigen::MatrixXf Q = eigenvectors * sqrt_eigenvalues;
61
62 return Q * x + mean;
63 }
64
65 Eigen::VectorXf
66 pdf_gradient(const Eigen::VectorXf& mean, float std, const Eigen::VectorXf& x)
67 {
68 Eigen::MatrixXf covariance =
69 Eigen::MatrixXf::Identity(mean.size(), mean.size()) * std::pow(std, 2);
70 float n = x.rows();
71 float sqrt2pi = std::sqrt(2 * M_PI);
72 float quadform = (x - mean).transpose() * covariance.inverse() * (x - mean);
73 float norm = std::pow(sqrt2pi, -n) * std::pow(covariance.determinant(), -0.5);
74
75 float probability = norm * exp(-0.5 * quadform);
76 return -probability * (x - mean) / covariance.determinant();
77 }
78
79} // namespace armarx::control::common
#define M_PI
Definition MathTools.h:17
float pdf(const Eigen::VectorXf &x) const
Definition math.cpp:15
Eigen::VectorXf pdf_gradient(const Eigen::VectorXf &x) const
Definition math.cpp:26
Eigen::VectorXf sample(unsigned int nr_iterations=20) const
Definition math.cpp:33
MultivariateNormal(const Eigen::VectorXf &mu, const Eigen::MatrixXf &cov)
This file is part of ArmarX.
Eigen::VectorXf pdf_gradient(const Eigen::VectorXf &mean, float std, const Eigen::VectorXf &x)
Definition math.cpp:66
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::optional< float > mean(const boost::circular_buffer< NameValueMap > &buffer, const std::string &key)
std::vector< std::vector< T > > transpose(const std::vector< std::vector< T > > &src, Thrower thrower)
double norm(const Point &a)
Definition point.hpp:102