gtsam
Loading...
Searching...
No Matches
ConcentratedGaussian.h
Go to the documentation of this file.
1/* ----------------------------------------------------------------------------
2
3 * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4 * Atlanta, Georgia 30332-0415
5 * All Rights Reserved
6 * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7
8 * See LICENSE for the license information
9
10 * -------------------------------------------------------------------------- */
11
18
19#pragma once
20
21#include <gtsam/base/utilities.h>
24
25namespace gtsam {
26
32template <class T>
34 public:
35 using Base = ExtendedPriorFactor<T>;
36 using Gaussian = typename Base::Gaussian;
37 using sharedGaussianNoiseModel = noiseModel::Gaussian::shared_ptr;
38
41
44
46 ConcentratedGaussian(Key key, const T& origin,
47 const sharedGaussianNoiseModel& model)
48 : Base(key, origin, model) {}
49
51 ConcentratedGaussian(Key key, const T& origin, const Vector& mean,
52 const sharedGaussianNoiseModel& model)
53 : Base(key, origin, mean, model) {
54 if (mean.size() != static_cast<Eigen::Index>(model->dim()))
55 throw std::invalid_argument(
56 "ConcentratedGaussian: mean dimension does not match noise model");
57 }
58
60 ConcentratedGaussian(Key key, const T& origin, const Matrix& covariance)
61 : Base(key, origin, covariance) {}
62
64 ConcentratedGaussian(Key key, const T& origin, const Vector& mean,
65 const Matrix& covariance)
66 : Base(key, origin, mean, covariance) {
67 if (mean.size() != covariance.rows())
68 throw std::invalid_argument(
69 "ConcentratedGaussian: mean dimension does not match covariance");
70 if (covariance.rows() != covariance.cols())
71 throw std::invalid_argument(
72 "ConcentratedGaussian: covariance matrix is not square");
73 }
74
78
79 ~ConcentratedGaussian() override {}
80
84
86 void print(const std::string& s, const KeyFormatter& keyFormatter =
87 DefaultKeyFormatter) const override {
88 std::cout << s << "ConcentratedGaussian on " << keyFormatter(this->key())
89 << "\n";
90 traits<T>::Print(this->origin_, " origin: ");
91 if (this->mean_) gtsam::print(*this->mean_, " tangent space mean: ");
92 if (this->noiseModel_)
93 this->noiseModel_->print(" noise model: ");
94 else
95 std::cout << "no noise model\n";
96 }
97
99 bool equals(const NonlinearFactor& expected,
100 double tol = 1e-9) const override {
101 const auto* e = dynamic_cast<const ConcentratedGaussian*>(&expected);
102 return e && Base::equals(*e, tol);
103 }
104
108
110 T retractMean(Matrix* xHm) const {
111 const size_t n = this->dim();
112 const bool zeroMean = !this->mean_;
113 if (xHm && zeroMean) xHm->setIdentity(n, n);
114 return zeroMean
115 ? this->origin_
116 : traits<T>::Retract(this->origin_, *(this->mean_), {}, xHm);
117 }
118
120 T retractMean() const { return retractMean(nullptr); }
121
123 T retractMean(Matrix& xHm) const { return retractMean(&xHm); }
124
131 double negLogConstant() const {
132 const size_t n = this->dim();
133 auto gaussian = this->gaussianModel("ConcentratedGaussian::negLogConstant",
134 /* throw */ true);
135 constexpr double log2pi = 1.8378770664093454835606594728112; // log(2*pi)
136 const double logDetSigma = gaussian->logDeterminant(); // log |Σ|
137 return 0.5 * n * log2pi + 0.5 * logDetSigma;
138 }
139
146 double logProbability(const T& x) const {
147 return -(negLogConstant() + this->error(x));
148 }
149
155 double logProbability(const Values& values) const {
156 const T& x = values.at<T>(this->key());
157 return logProbability(x);
158 }
159
164 double evaluate(const T& x) const { return exp(logProbability(x)); }
165
167 double evaluate(const Values& values) const {
168 return exp(logProbability(values));
169 }
170
174
181 if (!this->mean_) return *this; // already zero-mean
182 auto g =
183 this->gaussianModel("ConcentratedGaussian::reset", /* throw */ true);
184
185 Matrix hatJm;
186 const T x_hat = retractMean(&hatJm);
187 const Matrix covHat = hatJm * g->covariance() * hatJm.transpose();
188
189 return ConcentratedGaussian(this->key(), x_hat, Symmetrize(covHat));
190 }
191
198 ConcentratedGaussian transportTo(const T& x_hat) const {
199 auto g = this->gaussianModel("ConcentratedGaussian::transportTo",
200 /* throw */ true);
201
202 Matrix xHm; // ∂Retract(origin,m)/∂m
203 const T x = retractMean(&xHm);
204
205 Matrix hatHx; // ∂Local(x̂,x)/∂x
206 Vector muHat = traits<T>::Local(x_hat, x, {}, hatHx);
207 const Matrix hatJm = hatHx * xHm; // chain rule
208 const Matrix covHat = hatJm * g->covariance() * hatJm.transpose();
209
210 return ConcentratedGaussian(this->key(), x_hat, muHat, Symmetrize(covHat));
211 }
212
224 // 0) Sanity checks
225 if (this->key() != other.key())
226 throw std::invalid_argument(
227 "ConcentratedGaussian::operator*: keys differ");
228 if (this->dim() != other.dim())
229 throw std::invalid_argument(
230 "ConcentratedGaussian::operator*: dimension mismatch");
231
232 // 1) Transport other to our chart
233 ConcentratedGaussian o = other.transportTo(this->origin_);
234
235 // 2) Fuse the Gaussians in our tangent space
236 const auto g1 = this->gaussian("ConcentratedGaussian::operator*", true);
237 const auto g2 = o.gaussian("ConcentratedGaussian::operator*", true);
238 auto [m, P] = Fuse(*g1, *g2);
239
240 // 3) Create a fused ConcentratedGaussian at our origin with fused mean
241 ConcentratedGaussian ecg(this->key(), this->origin_, m, P);
242
243 // 4) Reset to zero mean
244 return ecg.reset();
245 }
246
248
249 private:
251 static Matrix Symmetrize(const Matrix& matrix) {
252 return 0.5 * (matrix + matrix.transpose());
253 }
254
256 static Gaussian Fuse(const Gaussian& g1, const Gaussian& g2) {
257 const Matrix& P1 = g1.second;
258 const Matrix& P2 = g2.second;
259 const Vector& m1 = g1.first;
260 const Vector& m2 = g2.first;
261
262 const Matrix W1 = P1.inverse();
263 const Matrix W2 = P2.inverse();
264 const Matrix P = (W1 + W2).inverse();
265 const Vector m = P * (W1 * m1 + W2 * m2);
266 return {m, Symmetrize(P)};
267 }
268
269#if GTSAM_ENABLE_BOOST_SERIALIZATION
271 friend class boost::serialization::access;
272 template <class ARCHIVE>
273 void serialize(ARCHIVE& ar, const unsigned int /*version*/) {
274 ar& boost::serialization::make_nvp(
275 "ExtendedPriorFactor", boost::serialization::base_object<Base>(*this));
276 }
277#endif
278};
279
280} // namespace gtsam
A non-templated config holding any types of Manifold-group elements.
Global functions in a separate testing namespace.
Definition chartTesting.h:28
KeyFormatter DefaultKeyFormatter
Assign default key formatter.
Definition Key.cpp:30
void print(const Matrix &A, const string &s, ostream &stream)
print without optional string, must specify cout yourself
Definition Matrix.cpp:143
std::function< std::string(Key)> KeyFormatter
Typedef for a function to format a key, i.e. to convert it to a string.
Definition Key.h:35
std::uint64_t Key
Integer nonlinear key type.
Definition types.h:43
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition Group.h:37
A nonlinear density, inherits from ExtendedPriorFactor.
Definition ConcentratedGaussian.h:33
T retractMean(Matrix *xHm) const
Return T element corresponding to the mean, with optional Jacobian.
Definition ConcentratedGaussian.h:110
double logProbability(const Values &values) const
Log-probability overload taking a Values container.
Definition ConcentratedGaussian.h:155
T retractMean(Matrix &xHm) const
Return the mean and write its Jacobian into xHm.
Definition ConcentratedGaussian.h:123
double negLogConstant() const
Calculate the normalization constant for the density.
Definition ConcentratedGaussian.h:131
double evaluate(const T &x) const
Evaluate the probability density at the given value.
Definition ConcentratedGaussian.h:164
double logProbability(const T &x) const
Calculate the log-probability of the given value.
Definition ConcentratedGaussian.h:146
ConcentratedGaussian(Key key, const T &origin, const Matrix &covariance)
Constructor with covariance matrix (zero mean in tangent space).
Definition ConcentratedGaussian.h:60
ConcentratedGaussian(Key key, const T &origin, const Vector &mean, const sharedGaussianNoiseModel &model)
Constructor with noise model and optional mean in tangent space.
Definition ConcentratedGaussian.h:51
ConcentratedGaussian transportTo(const T &x_hat) const
Transport this density to a new origin x̂, returning a density at x̂ with nonzero mean in that chart.
Definition ConcentratedGaussian.h:198
ConcentratedGaussian operator*(const ConcentratedGaussian &other) const
Fusion operator implementing the (approximate) three-step Fusion method in: Y.
Definition ConcentratedGaussian.h:223
bool equals(const NonlinearFactor &expected, double tol=1e-9) const override
equals
Definition ConcentratedGaussian.h:99
T retractMean() const
Return the mean without requesting its Jacobian.
Definition ConcentratedGaussian.h:120
ConcentratedGaussian(Key key, const T &origin, const sharedGaussianNoiseModel &model)
Constructor with noise model and optional mean in tangent space.
Definition ConcentratedGaussian.h:46
void print(const std::string &s, const KeyFormatter &keyFormatter=DefaultKeyFormatter) const override
print
Definition ConcentratedGaussian.h:86
ConcentratedGaussian()
Default constructor for serialization.
Definition ConcentratedGaussian.h:43
ConcentratedGaussian reset() const
Create a new ConcentratedGaussian with zero mean by moving the origin to x̂ = Retract(origin,...
Definition ConcentratedGaussian.h:180
ConcentratedGaussian(Key key, const T &origin, const Vector &mean, const Matrix &covariance)
Constructor with mean (in tangent space) and covariance matrix.
Definition ConcentratedGaussian.h:64
double evaluate(const Values &values) const
Evaluate density P(x) using a Values container.
Definition ConcentratedGaussian.h:167
noiseModel::Gaussian::shared_ptr gaussianModel(const std::string &method="<unknown>", bool throwOnFailure=false) const
Definition ExtendedPriorFactor.h:192
double error(const T &x) const
Definition ExtendedPriorFactor.h:177
std::optional< Vector > mean_
Definition ExtendedPriorFactor.h:54
bool equals(const NonlinearFactor &expected, double tol=1e-9) const override
Definition ExtendedPriorFactor.h:125
std::optional< Matrix > covariance(const std::string &method="<unknown>", bool throwOnFailure=false) const
Definition ExtendedPriorFactor.h:217
std::optional< Gaussian > gaussian(const std::string &method="<unknown>", bool throwOnFailure=false) const
Definition ExtendedPriorFactor.h:228
std::pair< Vector, Matrix > Gaussian
Definition ExtendedPriorFactor.h:225
ExtendedPriorFactor()
Definition ExtendedPriorFactor.h:67
Key key() const
Definition NoiseModelFactorN.h:307
Nonlinear factor base class.
Definition NonlinearFactor.h:70
size_t dim() const override
get the dimension of the factor (number of rows on linearization)
Definition NonlinearFactor.h:251
A non-templated config holding any types of Manifold-group elements.
Definition Values.h:65
const ValueType at(Key j) const
Retrieve a variable by key j.
Definition Values-inl.h:260