ISDDistance.h
Go to the documentation of this file.
1/*
2* This file is part of ArmarX.
3*
4* ArmarX is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License version 2 as
6* published by the Free Software Foundation.
7*
8* ArmarX is distributed in the hope that it will be useful, but
9* WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program. If not, see <http://www.gnu.org/licenses/>.
15*
16* @package MemoryX::GaussianMixtureHelpers
17* @author Alexey Kozlov <kozlov@kit.edu>
18* @copyright 2013 Alexey Kozlov
19* @license http://www.gnu.org/licenses/gpl-2.0.txt
20* GNU General Public License
21*/
22
23#pragma once
24
25#include <memory>
26#include <string>
27
28#include <Eigen/LU>
29
31
32#include "GMMDistance.h"
34
35namespace memoryx
36{
37
38 /**
39 * @class ISDDistance
40 * @ingroup CommonPlacesLearner
41 */
43 {
44 public:
45 /**
46 * Creates a new ISDDistance
47 */
49 {
50 }
51
52 /**
53 *
54 *
55 */
56 float
57 getDistance(const GaussianMixtureDistributionBasePtr& gmm1,
58 const GaussianMixtureDistributionBasePtr& gmm2,
59 bool normalize)
60 {
61 // preprocessing
62 std::vector<NormalDistributionPtr> g1, g2;
63 std::vector<float> w1, w2;
64 preprocessGMM(gmm1, g1, w1);
65 preprocessGMM(gmm2, g2, w2);
66
67 const float d11 = calcCrossSum(gmm1, g1, w1, gmm1, g1, w1);
68 const float d22 = calcCrossSum(gmm2, g2, w2, gmm2, g2, w2);
69 const float d12 = calcCrossSum(gmm1, g1, w1, gmm2, g2, w2);
70
71 const float isd = d11 + d22 - 2 * d12;
72 return normalize ? (isd / (d11 + d22)) : isd;
73 }
74
75 float
76 getDistance(const GaussianMixtureDistributionBasePtr& gmm1,
77 const GaussianMixtureDistributionBasePtr& gmm2) override
78 {
79 return getDistance(gmm1, gmm2, false);
80 }
81
82 float
83 getDistance(const GaussianMixtureDistributionBasePtr& gmm1,
84 const GaussianMixtureDistributionBasePtr& gmm2,
85 float d11)
86 {
87 // preprocessing
88 std::vector<NormalDistributionPtr> g1, g2;
89 std::vector<float> w1, w2;
90 preprocessGMM(gmm1, g1, w1);
91 preprocessGMM(gmm2, g2, w2);
92
93 const float d22 = calcCrossSum(gmm2, g2, w2, gmm2, g2, w2);
94 const float d12 = calcCrossSum(gmm1, g1, w1, gmm2, g2, w2);
95
96 return d11 + d22 - 2 * d12;
97 }
98
99 float
100 getDistance(const GaussianMixtureComponent& comp1,
101 const GaussianMixtureComponent& comp2) override
102 {
103 return 0.; // NYI
104 }
105
106 float
107 calcSelfLikeness(const GaussianMixtureDistributionBasePtr& gmm)
108 {
109 std::vector<NormalDistributionPtr> g;
110 std::vector<float> w;
111 preprocessGMM(gmm, g, w);
112
113 return calcCrossSum(gmm, g, w, gmm, g, w);
114 }
115
116
117 private:
118 void
119 preprocessGMM(const GaussianMixtureDistributionBasePtr& gmm,
120 std::vector<NormalDistributionPtr>& g,
121 std::vector<float>& w)
122 {
123
124 for (int i = 0; i < gmm->size(); ++i)
125 {
126 GaussianMixtureComponent c = gmm->getComponent(i);
127 g.push_back(NormalDistributionPtr::dynamicCast(c.gaussian));
128 w.push_back(c.weight);
129 }
130 }
131
132 float
133 calcCrossSum(const GaussianMixtureDistributionBasePtr& gmm1,
134 std::vector<NormalDistributionPtr>& g1,
135 std::vector<float>& w1,
136 const GaussianMixtureDistributionBasePtr& gmm2,
137 std::vector<NormalDistributionPtr>& g2,
138 std::vector<float>& w2)
139 {
140 float s = 0;
141
142 const int GMM2_SIZE = gmm2->size();
143
144 for (int i = 0; i < gmm1->size(); ++i)
145 {
146 const float wi = w1[i];
147 const Eigen::Vector3f mi = g1[i]->toEigenMean();
148 const Eigen::Matrix3f pi = g1[i]->toEigenCovariance();
149
150 for (int j = 0; j < GMM2_SIZE; ++j)
151 {
152 const float f = evaluate3DGaussian(
153 mi, g2[j]->toEigenMean(), pi + g2[j]->toEigenCovariance());
154 s += wi * w2[j] * f;
155 }
156 }
157
158 return s;
159 }
160
161 float
162 evaluate3DGaussian(const Eigen::Vector3f& point,
163 const Eigen::Vector3f& mean,
164 const Eigen::Matrix3f& cov)
165 {
166 return evaluate3DGaussian(point, mean, cov.inverse(), cov.determinant());
167 }
168
169 float
170 evaluate3DGaussian(const Eigen::Vector3f& point,
171 const Eigen::Vector3f& mean,
172 const Eigen::Matrix3f& covInv,
173 float covDet)
174 {
175 const float inner = -0.5 * (point - mean).transpose() * covInv * (point - mean);
176 const float e = expf(inner);
177
178 static const float pm = powf(2 * M_PI, -1.5f);
179 return pm * powf(covDet, -0.5) * e;
180 }
181 };
182
183 using ISDDistancePtr = std::shared_ptr<ISDDistance>;
184} // namespace memoryx
#define pi
#define ARMARXCORE_IMPORT_EXPORT
#define M_PI
Definition MathTools.h:17
constexpr T c
GMMDistance()
Creates a new GMMDistance.
Definition GMMDistance.h:45
float getDistance(const GaussianMixtureDistributionBasePtr &gmm1, const GaussianMixtureDistributionBasePtr &gmm2) override
Definition ISDDistance.h:76
float getDistance(const GaussianMixtureDistributionBasePtr &gmm1, const GaussianMixtureDistributionBasePtr &gmm2, bool normalize)
Definition ISDDistance.h:57
float getDistance(const GaussianMixtureComponent &comp1, const GaussianMixtureComponent &comp2) override
float calcSelfLikeness(const GaussianMixtureDistributionBasePtr &gmm)
ISDDistance()
Creates a new ISDDistance.
Definition ISDDistance.h:48
float getDistance(const GaussianMixtureDistributionBasePtr &gmm1, const GaussianMixtureDistributionBasePtr &gmm2, float d11)
Definition ISDDistance.h:83
double s(double t, double s0, double v0, double a0, double j)
Definition CtrlUtil.h:33
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)
VirtualRobot headers.
std::shared_ptr< ISDDistance > ISDDistancePtr