gtsam
Loading...
Searching...
No Matches
GaussianBayesTreeQueries.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
17
18#pragma once
19
23
24#include <Eigen/Cholesky>
25
26namespace gtsam {
27namespace internal {
28
29/* ************************************************************************* */
31inline KeyVector uniqueKeys(const KeyVector& keys) {
32 KeyVector unique;
33 unique.reserve(keys.size());
34 KeySet seen;
35 for (Key key : keys) {
36 if (seen.insert(key).second) {
37 unique.push_back(key);
38 }
39 }
40 return unique;
41}
42
43/* ************************************************************************* */
46inline std::vector<size_t> blockOffsets(const std::vector<size_t>& dims) {
47 std::vector<size_t> offsets(dims.size() + 1, 0);
48 for (size_t i = 0; i < dims.size(); ++i) {
49 offsets[i + 1] = offsets[i] + dims[i];
50 }
51 return offsets;
52}
53
54/* ************************************************************************* */
59inline Matrix informationToCovariance(const Matrix& information) {
60 if (!information.allFinite()) {
61 return Matrix::Zero(information.rows(), information.cols());
62 }
63
64 Eigen::LLT<Matrix> llt(information.selfadjointView<Eigen::Upper>());
65 Matrix covariance = Matrix::Identity(information.rows(), information.cols());
66 llt.solveInPlace(covariance);
67 return covariance;
68}
69
70/* ************************************************************************* */
72inline std::vector<size_t> dimsFromBayesNet(const GaussianBayesNet& bayesNet,
73 const KeyVector& orderedKeys) {
74 FastMap<Key, size_t> dimsByKey;
75 for (const auto& conditional : bayesNet) {
76 for (auto key = conditional->beginFrontals();
77 key != conditional->endFrontals(); ++key) {
78 dimsByKey[*key] = static_cast<size_t>(conditional->getDim(key));
79 }
80 }
81
82 std::vector<size_t> dims;
83 dims.reserve(orderedKeys.size());
84 for (Key key : orderedKeys) {
85 dims.push_back(dimsByKey.at(key));
86 }
87 return dims;
88}
89
90/* ************************************************************************* */
92inline Scatter scatterFromKeysAndDims(const KeyVector& orderedKeys,
93 const std::vector<size_t>& dims) {
94 Scatter scatter;
95 for (size_t index = 0; index < orderedKeys.size(); ++index) {
96 scatter.add(orderedKeys[index], dims.at(index));
97 }
98 return scatter;
99}
100
101/* ************************************************************************* */
105inline Matrix covarianceColumns(const GaussianBayesNet& bayesNet,
106 const KeyVector& orderedKeys,
107 const std::vector<size_t>& dims) {
108 const KeyVector factorKeys = bayesNet.ordering();
109 const std::vector<size_t> factorDims = dimsFromBayesNet(bayesNet, factorKeys);
110 const auto [R, rhs] = bayesNet.matrix(Ordering(factorKeys));
111 (void)rhs;
112
113 const std::vector<size_t> factorOffsets = blockOffsets(factorDims);
114 const std::vector<size_t> outputOffsets = blockOffsets(dims);
115 const size_t totalDim = factorOffsets.back();
116
117 FastMap<Key, size_t> factorIndex;
118 for (size_t index = 0; index < factorKeys.size(); ++index) {
119 factorIndex[factorKeys[index]] = index;
120 }
121
122 // Solve for covariance columns in elimination order, with output columns
123 // laid out in the requested order.
124 Matrix selectors = Matrix::Zero(totalDim, totalDim);
125 for (size_t outputIndex = 0; outputIndex < orderedKeys.size();
126 ++outputIndex) {
127 const size_t factorIndexForKey = factorIndex.at(orderedKeys[outputIndex]);
128 const size_t dim = dims.at(outputIndex);
129 selectors
130 .block(factorOffsets[factorIndexForKey], outputOffsets[outputIndex],
131 dim, dim)
132 .setIdentity();
133 }
134
135 R.transpose().triangularView<Eigen::Lower>().solveInPlace(selectors);
136 R.triangularView<Eigen::Upper>().solveInPlace(selectors);
137
138 // Gather rows in the requested order without changing the factorization
139 // ordering used by the triangular solves above.
140 Matrix covariance = Matrix::Zero(totalDim, totalDim);
141 for (size_t outputRow = 0; outputRow < orderedKeys.size(); ++outputRow) {
142 const size_t factorRow = factorIndex.at(orderedKeys[outputRow]);
143 const size_t rowDim = dims.at(outputRow);
144 for (size_t outputColumn = 0; outputColumn < orderedKeys.size();
145 ++outputColumn) {
146 const size_t columnDim = dims.at(outputColumn);
147 covariance.block(outputOffsets[outputRow], outputOffsets[outputColumn],
148 rowDim, columnDim) =
149 selectors.block(factorOffsets[factorRow], outputOffsets[outputColumn],
150 rowDim, columnDim);
151 }
152 }
153 return covariance;
154}
155
156/* ************************************************************************* */
159inline JointMarginal jointMarginalFromMatrix(const Matrix& matrix,
160 const KeyVector& orderedKeys,
161 const std::vector<size_t>& dims) {
162 return JointMarginal(matrix, scatterFromKeysAndDims(orderedKeys, dims));
163}
164
165/* ************************************************************************* */
168 return JointMarginal(Matrix(), Scatter());
169}
170
171/* ************************************************************************* */
176template <class BAYESTREE, class SINGLE_BUILDER, class MULTI_BUILDER>
178 const BAYESTREE& bayesTree, const KeyVector& queryKeys,
179 const typename BAYESTREE::FactorGraphType::Eliminate& eliminate,
180 const SINGLE_BUILDER& singleBuilder, const MULTI_BUILDER& multiBuilder) {
181 const KeyVector orderedKeys = uniqueKeys(queryKeys);
182 if (orderedKeys.empty()) {
183 return emptyJointMarginal();
184 }
185
186 if (orderedKeys.size() == 1) {
187 const Matrix matrix = singleBuilder(orderedKeys.front());
188 return jointMarginalFromMatrix(matrix, orderedKeys,
189 {static_cast<size_t>(matrix.rows())});
190 }
191
192 const GaussianBayesNet bayesNet =
193 *bayesTree.jointBayesNet(orderedKeys, eliminate);
194 return multiBuilder(bayesNet, orderedKeys);
195}
196
197/* ************************************************************************* */
199template <class BAYESTREE>
201 const BAYESTREE& bayesTree, Key key,
202 const typename BAYESTREE::FactorGraphType::Eliminate& eliminate) {
203 return bayesTree.marginalFactor(key, eliminate)->information();
204}
205
206/* ************************************************************************* */
208template <class BAYESTREE>
210 const BAYESTREE& bayesTree, const KeyVector& queryKeys,
211 const typename BAYESTREE::FactorGraphType::Eliminate& eliminate) {
212 return buildJointMarginal(
213 bayesTree, queryKeys, eliminate,
214 [&bayesTree, &eliminate](Key key) {
215 return marginalInformation(bayesTree, key, eliminate);
216 },
217 [](const GaussianBayesNet& bayesNet, const KeyVector& orderedKeys) {
218 const auto [R, rhs] = bayesNet.matrix(Ordering(orderedKeys));
219 (void)rhs;
220 return jointMarginalFromMatrix(R.transpose() * R, orderedKeys,
221 dimsFromBayesNet(bayesNet, orderedKeys));
222 });
223}
224
225/* ************************************************************************* */
227template <class BAYESTREE>
229 const BAYESTREE& bayesTree, const KeyVector& queryKeys,
230 const typename BAYESTREE::FactorGraphType::Eliminate& eliminate) {
231 return buildJointMarginal(
232 bayesTree, queryKeys, eliminate,
233 [&bayesTree, &eliminate](Key key) {
235 marginalInformation(bayesTree, key, eliminate));
236 },
237 [](const GaussianBayesNet& bayesNet, const KeyVector& orderedKeys) {
238 const std::vector<size_t> dims =
239 dimsFromBayesNet(bayesNet, orderedKeys);
241 covarianceColumns(bayesNet, orderedKeys, dims), orderedKeys, dims);
242 });
243}
244
245} // namespace internal
246} // namespace gtsam
Variable ordering for the elimination algorithm.
Block access to joint Gaussian covariance or information matrices.
Chordal Bayes Net, the result of eliminating a factor graph.
JointMarginal emptyJointMarginal()
Construct an empty joint marginal.
Definition GaussianBayesTreeQueries.h:167
JointMarginal jointMarginalInformation(const BAYESTREE &bayesTree, const KeyVector &queryKeys, const typename BAYESTREE::FactorGraphType::Eliminate &eliminate)
Return joint marginal information with blocks in query-key order.
Definition GaussianBayesTreeQueries.h:209
KeyVector uniqueKeys(const KeyVector &keys)
Return unique keys in their first-occurrence order.
Definition GaussianBayesTreeQueries.h:31
Matrix marginalInformation(const BAYESTREE &bayesTree, Key key, const typename BAYESTREE::FactorGraphType::Eliminate &eliminate)
Return marginal information for one key using the requested elimination.
Definition GaussianBayesTreeQueries.h:200
std::vector< size_t > dimsFromBayesNet(const GaussianBayesNet &bayesNet, const KeyVector &orderedKeys)
Return variable dimensions from a Bayes net in the requested key order.
Definition GaussianBayesTreeQueries.h:72
JointMarginal buildJointMarginal(const BAYESTREE &bayesTree, const KeyVector &queryKeys, const typename BAYESTREE::FactorGraphType::Eliminate &eliminate, const SINGLE_BUILDER &singleBuilder, const MULTI_BUILDER &multiBuilder)
Build a joint marginal while sharing empty, single-key, and multi-key query handling between informat...
Definition GaussianBayesTreeQueries.h:177
Scatter scatterFromKeysAndDims(const KeyVector &orderedKeys, const std::vector< size_t > &dims)
Construct a scatter with entries in the supplied key and dimension order.
Definition GaussianBayesTreeQueries.h:92
Matrix informationToCovariance(const Matrix &information)
Convert information to covariance using Cholesky solves, returning zeros when the information contain...
Definition GaussianBayesTreeQueries.h:59
JointMarginal jointMarginalCovariance(const BAYESTREE &bayesTree, const KeyVector &queryKeys, const typename BAYESTREE::FactorGraphType::Eliminate &eliminate)
Return joint marginal covariance with blocks in query-key order.
Definition GaussianBayesTreeQueries.h:228
JointMarginal jointMarginalFromMatrix(const Matrix &matrix, const KeyVector &orderedKeys, const std::vector< size_t > &dims)
Construct a joint marginal from a dense matrix and ordered block metadata.
Definition GaussianBayesTreeQueries.h:159
std::vector< size_t > blockOffsets(const std::vector< size_t > &dims)
Return the scalar offsets corresponding to a sequence of block dimensions.
Definition GaussianBayesTreeQueries.h:46
Matrix covarianceColumns(const GaussianBayesNet &bayesNet, const KeyVector &orderedKeys, const std::vector< size_t > &dims)
Compute covariance blocks in the requested key order using triangular solves in the Bayes net's elimi...
Definition GaussianBayesTreeQueries.h:105
Global functions in a separate testing namespace.
Definition chartTesting.h:28
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
Definition Key.h:91
std::uint64_t Key
Integer nonlinear key type.
Definition types.h:43
FastMap is a thin wrapper around std::map that uses the boost fast_pool_allocator instead of the defa...
Definition FastMap.h:40
Definition Ordering.h:33
GaussianBayesNet is a Bayes net made from linear-Gaussian conditionals.
Definition GaussianBayesNet.h:36
std::pair< Matrix, Vector > matrix(const Ordering &ordering) const
Return (dense) upper-triangular matrix representation Will return upper-triangular matrix only when u...
Definition GaussianBayesNet.cpp:192
Ordering ordering() const
Return ordering corresponding to a topological sort.
Definition GaussianBayesNet.cpp:174
A class to store and access a joint marginal, returned from Gaussian and nonlinear covariance query A...
Definition JointMarginal.h:34
Scatter is an intermediate data structure used when building a HessianFactor incrementally,...
Definition Scatter.h:49
GTSAM_EXPORT void add(Key key, size_t dim)
Add a key/dim pair.
Definition Scatter.cpp:75