Gaussian.cpp
Go to the documentation of this file.
1 // *****************************************************************
2 // Filename: Gaussian.h
3 // Copyright: Kai Welke, Chair Prof. Dillmann (IAIM),
4 // Institute for Computer Science and Engineering (CSE),
5 // University of Karlsruhe. All rights reserved.
6 // Author: Kai Welke
7 // Date: 27.05.2012
8 // *****************************************************************
9 
10 // *****************************************************************
11 // includes
12 // *****************************************************************
13 #include "Gaussian.h"
14 
15 #include <cstdio>
16 #include <iostream>
17 
18 // *****************************************************************
19 // construction
20 // *****************************************************************
22 {
23  this->dimension = -1;
24 }
25 
26 Gaussian::Gaussian(int dimension)
27 {
28  this->dimension = dimension;
29 
30  // initialize valid distribution
31  this->cov = covariance_type::Identity(dimension, dimension);
32  this->mean = value_type::Zero(dimension, 1);
33 }
34 
35 Gaussian::Gaussian(const Gaussian& prototype)
36 {
37  *this = prototype;
38 }
39 
41 {
42  this->cov = covariance;
43  this->mean = mean;
44 
45  dimension = cov.rows();
46 
47  if (mean.rows() != dimension)
48  {
50  }
51 }
52 
53 // *****************************************************************
54 // readouts
55 // *****************************************************************
56 double
58 {
59  if (dimension == -1)
60  {
62  }
63 
64  if (point.rows() != dimension)
65  {
67  }
68 
70  -0.5 * (point - mean).transpose() * cov.inverse() * (point - mean);
71  double e = exp(inner(0, 0));
72 
73  covariance_type i = cov;
74  return pow(2 * M_PI, -getDimensions() / 2.0f) * pow(i.determinant(), -0.5) * e;
75 }
76 
77 double
79 {
80  if (dimension == -1)
81  {
83  }
84 
85  if (point.rows() != dimension)
86  {
88  }
89 
91  dist = (point - mean).transpose() * cov.inverse() * (point - mean);
92 
93  return std::sqrt(dist(0, 0));
94 }
95 
96 // generic draw sample for arbitrary covariance matrix
99 {
100  if (dimension == -1)
101  {
103  }
104 
105  // go through all dimensions and calculate independen random processes on unit
106  // gaussian using Box-Muller method
107 
108  float fRand1, fRand2;
109  value_type gaussianSample(getDimensions());
110 
111  // calculate gaussian distributed with Cov=I and mean = 0 (ndimension independant box muller gaussians)
112  for (int d = 0; d < getDimensions(); d++)
113  {
114  fRand1 = float(rand()) / RAND_MAX;
115  fRand2 = float(rand()) / RAND_MAX;
116 
117  // calculate standard normal distribution sample (Box-Muller)
118  gaussianSample(d) = sqrt(-2 * log(fRand1)) * cos(2 * M_PI * fRand2);
119  }
120 
121  // in order to retrieve samples distributed according to cov
122  // use cholesky decomposition:
123  // A * A^t = cov
124  // ==> random_vector=A * gaussianSample
125  // (can be proved by X=AY, D= cov(Y) (with D=I, produced by above code), C=cov(X) (which is desired cov), C= E(XX^T)=E(AY(AY)^t)=AE(YY^t)A^t=ADA^t)
126  // thus only matrx A has to be found
127  covariance_type A = cov.llt().matrixL();
128 
129  value_type sample = A * gaussianSample + mean;
130 
131  return sample;
132 }
133 
134 // draw sample for cases where only elements in diagonal of cov (can be used with zero in diagonal)
137 {
138  if (dimension == -1)
139  {
141  }
142 
143  // go through all dimensions and calculate independen random processes on unit
144  // gaussian using Box-Muller method
145 
146  float fRand1, fRand2;
147  value_type gaussianSample(getDimensions());
148 
149  // calculate gaussian distributed with Cov=I and mean = 0 (ndimension independant box muller gaussians)
150  for (int d = 0; d < getDimensions(); d++)
151  {
152  fRand1 = float(rand()) / RAND_MAX;
153  fRand2 = float(rand()) / RAND_MAX;
154 
155  // calculate standard normal distribution sample (Box-Muller)
156  gaussianSample(d) = sqrt(-2 * log(fRand1)) * cos(2 * M_PI * fRand2);
157  }
158 
159  // generate matrix A
161 
162  for (int i = 0; i < getDimensions(); i++)
163  for (int u = 0; u < getDimensions(); u++)
164  if (i == u)
165  {
166  A(i, u) = sqrt(cov(i, u));
167  }
168  else
169  {
170  A(i, u) = 0;
171  }
172 
173  value_type sample = A * gaussianSample + mean;
174 
175  return sample;
176 }
177 
178 // *****************************************************************
179 // content manipulation
180 // *****************************************************************
181 void
183 {
184  if (dimension == -1)
185  {
187  }
188 
189  if (samples.rows() != dimension)
190  {
192  }
193 
194  int numberSamples = samples.cols();
195 
196  // calculate mean
197  mean = value_type::Zero(dimension, 1);
198 
199  for (int i = 0; i < numberSamples; i++)
200  {
201  mean += samples.block(0, i, mean.rows(), 1);
202  }
203 
204  mean = mean / numberSamples;
205 
206  samples_type meanadj = samples;
207 
208  // mean adjust
209  for (int s = 0; s < numberSamples; s++)
210  {
211  meanadj.block(0, s, meanadj.rows(), 1) -= mean;
212  }
213 
214  // calculate covariance
215  cov = meanadj * meanadj.transpose() / numberSamples;
216 }
217 
218 void
219 Gaussian::set(const Gaussian& prototype)
220 {
221  if ((dimension != prototype.getDimensions()))
222  {
224  }
225 
226  this->mean = prototype.getMean();
227  this->cov = prototype.getCovariance();
228 }
229 
230 void
232 {
233  // isSymmetric(cov);
234 
235  if ((dimension != -1) && (mean.rows() != dimension))
236  {
238  }
239 
240  if ((dimension != -1) && (cov.rows() != dimension))
241  {
243  }
244 
245  if (dimension == -1)
246  {
247  dimension = cov.rows();
248  }
249 
250  this->mean = mean;
251  this->cov = cov;
252 }
253 
254 void
256 {
257  if ((dimension != -1) && (mean.rows() != dimension))
258  {
260  }
261 
262  if (dimension == -1)
263  {
264  dimension = mean.rows();
265  this->cov = Eigen::MatrixXd::Identity(dimension, dimension);
266  }
267 
268  this->mean = mean;
269 }
270 
271 void
273 {
274  if ((dimension != -1) && (cov.rows() != dimension))
275  {
277  }
278 
279  if ((dimension != -1) && (cov.cols() != dimension))
280  {
282  }
283 
284  if ((dimension == -1) && (cov.rows() != cov.cols()))
285  {
287  }
288 
289  if (dimension == -1)
290  {
291  dimension = cov.rows();
292  this->mean = Eigen::VectorXd::Zero(dimension);
293  }
294 
295  this->cov = cov;
296 }
297 
298 // *****************************************************************
299 // content manipulation
300 // *****************************************************************
301 void
302 Gaussian::isSymmetric(const covariance_type& matrix)
303 {
304  if (matrix.rows() != matrix.cols())
305  {
307  }
308 
309  for (int r = 0; r < matrix.rows(); r++)
310  {
311  for (int c = 0; c < matrix.cols(); c++)
312  {
313  if (matrix(r, c) != matrix(c, r))
314  {
316  }
317  }
318  }
319 }
Gaussian::getCovariance
const covariance_type & getCovariance() const
Definition: Gaussian.h:82
Gaussian::covariance_type
Eigen::MatrixXd covariance_type
Definition: Gaussian.h:57
Gaussian::mahalanobis
double mahalanobis(const value_type &point)
Definition: Gaussian.cpp:78
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
CovarianceNotSymmetricException
Definition: Gaussian.h:38
Gaussian::evaluate
double evaluate(const value_type &point)
Definition: Gaussian.cpp:57
Gaussian::getDimensions
int getDimensions() const
Definition: Gaussian.h:94
InvalidDimensionException
Definition: Gaussian.h:20
Gaussian::samples_type
Eigen::MatrixXd samples_type
Definition: Gaussian.h:58
GfxTL::Identity
void Identity(MatrixXX< N, N, T > *a)
Definition: MatrixXX.h:570
armarx::mean
std::optional< float > mean(const boost::circular_buffer< NameValueMap > &buffer, const std::string &key)
Definition: KinematicUnitGuiPlugin.cpp:1620
M_PI
#define M_PI
Definition: MathTools.h:17
Gaussian::setMean
void setMean(const value_type &mean)
Definition: Gaussian.cpp:255
Gaussian::drawSample
value_type drawSample()
Definition: Gaussian.cpp:98
Gaussian::setCovariance
void setCovariance(const covariance_type &cov)
Definition: Gaussian.cpp:272
Gaussian::value_type
Eigen::VectorXd value_type
Definition: Gaussian.h:56
Gaussian.h
A
class A(deque< T, A >)) ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class T
Enables hashing of std::list.
GfxTL::sqrt
VectorXD< D, T > sqrt(const VectorXD< D, T > &a)
Definition: VectorXD.h:704
float
#define float
Definition: 16_Level.h:22
Gaussian::drawSampleDiagonalCovariance
value_type drawSampleDiagonalCovariance()
Definition: Gaussian.cpp:136
Eigen::Matrix
Definition: EigenForwardDeclarations.h:27
GaussianNotInitializedException
Definition: Gaussian.h:29
Gaussian::getMean
const value_type & getMean() const
Definition: Gaussian.h:88
Gaussian
Definition: Gaussian.h:50
armarx::transpose
std::vector< std::vector< T > > transpose(const std::vector< std::vector< T >> &src, Thrower thrower)
Definition: SimoxCSpace.cpp:772
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
Gaussian::generateFromSamples
void generateFromSamples(const samples_type &samples)
Definition: Gaussian.cpp:182
Gaussian::Gaussian
Gaussian()
Definition: Gaussian.cpp:21
Gaussian::set
void set(const Gaussian &prototype)
Definition: Gaussian.cpp:219