gtsam 4.1.1
gtsam
EliminateableFactorGraph-inst.h
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
19#pragma once
20
23#include <boost/tuple/tuple.hpp>
24
25namespace gtsam {
26
27 /* ************************************************************************* */
28 template<class FACTORGRAPH>
29 boost::shared_ptr<typename EliminateableFactorGraph<FACTORGRAPH>::BayesNetType>
31 OptionalOrderingType orderingType, const Eliminate& function,
32 OptionalVariableIndex variableIndex) const {
33 if(!variableIndex) {
34 // If no VariableIndex provided, compute one and call this function again IMPORTANT: we check
35 // for no variable index first so that it's always computed if we need to call COLAMD because
36 // no Ordering is provided. When removing optional from VariableIndex, create VariableIndex
37 // before creating ordering.
38 VariableIndex computedVariableIndex(asDerived());
39 return eliminateSequential(orderingType, function, computedVariableIndex);
40 }
41 else {
42 // Compute an ordering and call this function again. We are guaranteed to have a
43 // VariableIndex already here because we computed one if needed in the previous 'if' block.
44 if (orderingType == Ordering::METIS) {
45 Ordering computedOrdering = Ordering::Metis(asDerived());
46 return eliminateSequential(computedOrdering, function, variableIndex);
47 } else {
48 Ordering computedOrdering = Ordering::Colamd(*variableIndex);
49 return eliminateSequential(computedOrdering, function, variableIndex);
50 }
51 }
52 }
53
54 /* ************************************************************************* */
55 template<class FACTORGRAPH>
56 boost::shared_ptr<typename EliminateableFactorGraph<FACTORGRAPH>::BayesNetType>
58 const Ordering& ordering, const Eliminate& function,
59 OptionalVariableIndex variableIndex) const
60 {
61 if(!variableIndex) {
62 // If no VariableIndex provided, compute one and call this function again
63 VariableIndex computedVariableIndex(asDerived());
64 return eliminateSequential(ordering, function, computedVariableIndex);
65 } else {
66 gttic(eliminateSequential);
67 // Do elimination
68 EliminationTreeType etree(asDerived(), *variableIndex, ordering);
69 boost::shared_ptr<BayesNetType> bayesNet;
70 boost::shared_ptr<FactorGraphType> factorGraph;
71 boost::tie(bayesNet,factorGraph) = etree.eliminate(function);
72 // If any factors are remaining, the ordering was incomplete
73 if(!factorGraph->empty())
75 // Return the Bayes net
76 return bayesNet;
77 }
78 }
79
80 /* ************************************************************************* */
81 template <class FACTORGRAPH>
82 boost::shared_ptr<
85 OptionalOrderingType orderingType, const Eliminate& function,
86 OptionalVariableIndex variableIndex) const {
87 if (!variableIndex) {
88 // If no VariableIndex provided, compute one and call this function again
89 // IMPORTANT: we check for no variable index first so that it's always
90 // computed if we need to call COLAMD because no Ordering is provided.
91 // When removing optional from VariableIndex, create VariableIndex before
92 // creating ordering.
93 VariableIndex computedVariableIndex(asDerived());
94 return eliminateMultifrontal(orderingType, function,
95 computedVariableIndex);
96 } else {
97 // Compute an ordering and call this function again. We are guaranteed to
98 // have a VariableIndex already here because we computed one if needed in
99 // the previous 'if' block.
100 if (orderingType == Ordering::METIS) {
101 Ordering computedOrdering = Ordering::Metis(asDerived());
102 return eliminateMultifrontal(computedOrdering, function, variableIndex);
103 } else {
104 Ordering computedOrdering = Ordering::Colamd(*variableIndex);
105 return eliminateMultifrontal(computedOrdering, function, variableIndex);
106 }
107 }
108 }
109
110 /* ************************************************************************* */
111 template<class FACTORGRAPH>
112 boost::shared_ptr<typename EliminateableFactorGraph<FACTORGRAPH>::BayesTreeType>
114 const Ordering& ordering, const Eliminate& function,
115 OptionalVariableIndex variableIndex) const
116 {
117 if(!variableIndex) {
118 // If no VariableIndex provided, compute one and call this function again
119 VariableIndex computedVariableIndex(asDerived());
120 return eliminateMultifrontal(ordering, function, computedVariableIndex);
121 } else {
122 gttic(eliminateMultifrontal);
123 // Do elimination with given ordering
124 EliminationTreeType etree(asDerived(), *variableIndex, ordering);
125 JunctionTreeType junctionTree(etree);
126 boost::shared_ptr<BayesTreeType> bayesTree;
127 boost::shared_ptr<FactorGraphType> factorGraph;
128 boost::tie(bayesTree,factorGraph) = junctionTree.eliminate(function);
129 // If any factors are remaining, the ordering was incomplete
130 if(!factorGraph->empty())
132 // Return the Bayes tree
133 return bayesTree;
134 }
135 }
137 /* ************************************************************************* */
138 template<class FACTORGRAPH>
139 std::pair<boost::shared_ptr<typename EliminateableFactorGraph<FACTORGRAPH>::BayesNetType>, boost::shared_ptr<FACTORGRAPH> >
141 const Ordering& ordering, const Eliminate& function, OptionalVariableIndex variableIndex) const
142 {
143 if(variableIndex) {
144 gttic(eliminatePartialSequential);
145 // Do elimination
146 EliminationTreeType etree(asDerived(), *variableIndex, ordering);
147 return etree.eliminate(function);
148 } else {
149 // If no variable index is provided, compute one and call this function again
150 VariableIndex computedVariableIndex(asDerived());
151 return eliminatePartialSequential(ordering, function, computedVariableIndex);
152 }
153 }
154
155 /* ************************************************************************* */
156 template<class FACTORGRAPH>
157 std::pair<boost::shared_ptr<typename EliminateableFactorGraph<FACTORGRAPH>::BayesNetType>, boost::shared_ptr<FACTORGRAPH> >
159 const KeyVector& variables, const Eliminate& function, OptionalVariableIndex variableIndex) const
160 {
161 if(variableIndex) {
162 gttic(eliminatePartialSequential);
163 // Compute full ordering
164 Ordering fullOrdering = Ordering::ColamdConstrainedFirst(*variableIndex, variables);
165
166 // Split off the part of the ordering for the variables being eliminated
167 Ordering ordering(fullOrdering.begin(), fullOrdering.begin() + variables.size());
168 return eliminatePartialSequential(ordering, function, variableIndex);
169 } else {
170 // If no variable index is provided, compute one and call this function again
171 VariableIndex computedVariableIndex(asDerived());
172 return eliminatePartialSequential(variables, function, computedVariableIndex);
173 }
174 }
175
176 /* ************************************************************************* */
177 template<class FACTORGRAPH>
178 std::pair<boost::shared_ptr<typename EliminateableFactorGraph<FACTORGRAPH>::BayesTreeType>, boost::shared_ptr<FACTORGRAPH> >
180 const Ordering& ordering, const Eliminate& function, OptionalVariableIndex variableIndex) const
182 if(variableIndex) {
183 gttic(eliminatePartialMultifrontal);
184 // Do elimination
185 EliminationTreeType etree(asDerived(), *variableIndex, ordering);
186 JunctionTreeType junctionTree(etree);
187 return junctionTree.eliminate(function);
188 } else {
189 // If no variable index is provided, compute one and call this function again
190 VariableIndex computedVariableIndex(asDerived());
191 return eliminatePartialMultifrontal(ordering, function, computedVariableIndex);
192 }
193 }
194
195 /* ************************************************************************* */
196 template<class FACTORGRAPH>
197 std::pair<boost::shared_ptr<typename EliminateableFactorGraph<FACTORGRAPH>::BayesTreeType>, boost::shared_ptr<FACTORGRAPH> >
199 const KeyVector& variables, const Eliminate& function, OptionalVariableIndex variableIndex) const
200 {
201 if(variableIndex) {
202 gttic(eliminatePartialMultifrontal);
203 // Compute full ordering
204 Ordering fullOrdering = Ordering::ColamdConstrainedFirst(*variableIndex, variables);
205
206 // Split off the part of the ordering for the variables being eliminated
207 Ordering ordering(fullOrdering.begin(), fullOrdering.begin() + variables.size());
208 return eliminatePartialMultifrontal(ordering, function, variableIndex);
209 } else {
210 // If no variable index is provided, compute one and call this function again
211 VariableIndex computedVariableIndex(asDerived());
212 return eliminatePartialMultifrontal(variables, function, computedVariableIndex);
213 }
214 }
215
216 /* ************************************************************************* */
217 template<class FACTORGRAPH>
218 boost::shared_ptr<typename EliminateableFactorGraph<FACTORGRAPH>::BayesNetType>
220 boost::variant<const Ordering&, const KeyVector&> variables,
221 const Eliminate& function, OptionalVariableIndex variableIndex) const
222 {
223 if(!variableIndex) {
224 // If no variable index is provided, compute one and call this function again
225 VariableIndex index(asDerived());
226 return marginalMultifrontalBayesNet(variables, function, index);
227 } else {
228 // No ordering was provided for the marginalized variables, so order them using constrained
229 // COLAMD.
230 bool unmarginalizedAreOrdered = (boost::get<const Ordering&>(&variables) != 0);
231 const KeyVector* variablesOrOrdering =
232 unmarginalizedAreOrdered ?
233 boost::get<const Ordering&>(&variables) : boost::get<const KeyVector&>(&variables);
234
235 Ordering totalOrdering =
236 Ordering::ColamdConstrainedLast(*variableIndex, *variablesOrOrdering, unmarginalizedAreOrdered);
237
238 // Split up ordering
239 const size_t nVars = variablesOrOrdering->size();
240 Ordering marginalizationOrdering(totalOrdering.begin(), totalOrdering.end() - nVars);
241 Ordering marginalVarsOrdering(totalOrdering.end() - nVars, totalOrdering.end());
242
243 // Call this function again with the computed orderings
244 return marginalMultifrontalBayesNet(marginalVarsOrdering, marginalizationOrdering, function, *variableIndex);
245 }
246 }
247
248 /* ************************************************************************* */
249 template<class FACTORGRAPH>
250 boost::shared_ptr<typename EliminateableFactorGraph<FACTORGRAPH>::BayesNetType>
252 boost::variant<const Ordering&, const KeyVector&> variables,
253 const Ordering& marginalizedVariableOrdering,
254 const Eliminate& function, OptionalVariableIndex variableIndex) const
256 if(!variableIndex) {
257 // If no variable index is provided, compute one and call this function again
258 VariableIndex index(asDerived());
259 return marginalMultifrontalBayesNet(variables, marginalizedVariableOrdering, function, index);
260 } else {
261 gttic(marginalMultifrontalBayesNet);
262 // An ordering was provided for the marginalized variables, so we can first eliminate them
263 // in the order requested.
264 boost::shared_ptr<BayesTreeType> bayesTree;
265 boost::shared_ptr<FactorGraphType> factorGraph;
266 boost::tie(bayesTree,factorGraph) =
267 eliminatePartialMultifrontal(marginalizedVariableOrdering, function, *variableIndex);
268
269 if(const Ordering* varsAsOrdering = boost::get<const Ordering&>(&variables))
271 // An ordering was also provided for the unmarginalized variables, so we can also
272 // eliminate them in the order requested.
273 return factorGraph->eliminateSequential(*varsAsOrdering, function);
274 }
275 else
276 {
277 // No ordering was provided for the unmarginalized variables, so order them with COLAMD.
278 return factorGraph->eliminateSequential(Ordering::COLAMD, function);
279 }
280 }
281 }
282
283 /* ************************************************************************* */
284 template<class FACTORGRAPH>
285 boost::shared_ptr<typename EliminateableFactorGraph<FACTORGRAPH>::BayesTreeType>
287 boost::variant<const Ordering&, const KeyVector&> variables,
288 const Eliminate& function, OptionalVariableIndex variableIndex) const
289 {
290 if(!variableIndex) {
291 // If no variable index is provided, compute one and call this function again
292 VariableIndex computedVariableIndex(asDerived());
293 return marginalMultifrontalBayesTree(variables, function, computedVariableIndex);
294 } else {
295 // No ordering was provided for the marginalized variables, so order them using constrained
296 // COLAMD.
297 bool unmarginalizedAreOrdered = (boost::get<const Ordering&>(&variables) != 0);
298 const KeyVector* variablesOrOrdering =
299 unmarginalizedAreOrdered ?
300 boost::get<const Ordering&>(&variables) : boost::get<const KeyVector&>(&variables);
301
302 Ordering totalOrdering =
303 Ordering::ColamdConstrainedLast(*variableIndex, *variablesOrOrdering, unmarginalizedAreOrdered);
304
305 // Split up ordering
306 const size_t nVars = variablesOrOrdering->size();
307 Ordering marginalizationOrdering(totalOrdering.begin(), totalOrdering.end() - nVars);
308 Ordering marginalVarsOrdering(totalOrdering.end() - nVars, totalOrdering.end());
309
310 // Call this function again with the computed orderings
311 return marginalMultifrontalBayesTree(marginalVarsOrdering, marginalizationOrdering, function, *variableIndex);
312 }
313 }
314
315 /* ************************************************************************* */
316 template<class FACTORGRAPH>
317 boost::shared_ptr<typename EliminateableFactorGraph<FACTORGRAPH>::BayesTreeType>
319 boost::variant<const Ordering&, const KeyVector&> variables,
320 const Ordering& marginalizedVariableOrdering,
321 const Eliminate& function, OptionalVariableIndex variableIndex) const
322 {
323 if(!variableIndex) {
324 // If no variable index is provided, compute one and call this function again
325 VariableIndex computedVariableIndex(asDerived());
326 return marginalMultifrontalBayesTree(variables, marginalizedVariableOrdering, function, computedVariableIndex);
327 } else {
328 gttic(marginalMultifrontalBayesTree);
329 // An ordering was provided for the marginalized variables, so we can first eliminate them
330 // in the order requested.
331 boost::shared_ptr<BayesTreeType> bayesTree;
332 boost::shared_ptr<FactorGraphType> factorGraph;
333 boost::tie(bayesTree,factorGraph) =
334 eliminatePartialMultifrontal(marginalizedVariableOrdering, function, *variableIndex);
335
336 if(const Ordering* varsAsOrdering = boost::get<const Ordering&>(&variables))
337 {
338 // An ordering was also provided for the unmarginalized variables, so we can also
339 // eliminate them in the order requested.
340 return factorGraph->eliminateMultifrontal(*varsAsOrdering, function);
341 }
342 else
343 {
344 // No ordering was provided for the unmarginalized variables, so order them with COLAMD.
345 return factorGraph->eliminateMultifrontal(Ordering::COLAMD, function);
346 }
347 }
348 }
349
350 /* ************************************************************************* */
351 template<class FACTORGRAPH>
352 boost::shared_ptr<FACTORGRAPH>
354 const KeyVector& variables,
355 const Eliminate& function, OptionalVariableIndex variableIndex) const
356 {
357 if(variableIndex)
358 {
359 // Compute a total ordering for all variables
360 Ordering totalOrdering = Ordering::ColamdConstrainedLast(*variableIndex, variables);
361
362 // Split out the part for the marginalized variables
363 Ordering marginalizationOrdering(totalOrdering.begin(), totalOrdering.end() - variables.size());
364
365 // Eliminate and return the remaining factor graph
366 return eliminatePartialMultifrontal(marginalizationOrdering, function, *variableIndex).second;
367 }
368 else
369 {
370 // If no variable index is provided, compute one and call this function again
371 VariableIndex computedVariableIndex(asDerived());
372 return marginal(variables, function, computedVariableIndex);
373 }
374 }
375
376
377}
Exceptions that may be thrown by inference algorithms.
Variable elimination algorithms for factor graphs.
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:86
std::function< EliminationResult(const FactorGraphType &, const Ordering &)> Eliminate
The function type that does a single dense elimination step on a subgraph.
Definition: EliminateableFactorGraph.h:89
EliminationTraitsType::JunctionTreeType JunctionTreeType
Junction tree type that can do multifrontal elimination of this graph.
Definition: EliminateableFactorGraph.h:82
boost::shared_ptr< BayesTreeType > marginalMultifrontalBayesTree(boost::variant< const Ordering &, const KeyVector & > variables, const Eliminate &function=EliminationTraitsType::DefaultEliminate, OptionalVariableIndex variableIndex=boost::none) const
Compute the marginal of the requested variables and return the result as a Bayes tree.
Definition: EliminateableFactorGraph-inst.h:286
boost::optional< const VariableIndex & > OptionalVariableIndex
Typedef for an optional variable index as an argument to elimination functions.
Definition: EliminateableFactorGraph.h:92
boost::shared_ptr< FactorGraphType > marginal(const KeyVector &variables, const Eliminate &function=EliminationTraitsType::DefaultEliminate, OptionalVariableIndex variableIndex=boost::none) const
Compute the marginal factor graph of the requested variables.
Definition: EliminateableFactorGraph-inst.h:353
EliminationTraitsType::EliminationTreeType EliminationTreeType
Elimination tree type that can do sequential elimination of this graph.
Definition: EliminateableFactorGraph.h:76
boost::shared_ptr< BayesNetType > eliminateSequential(OptionalOrderingType orderingType=boost::none, const Eliminate &function=EliminationTraitsType::DefaultEliminate, OptionalVariableIndex variableIndex=boost::none) const
Do sequential elimination of all variables to produce a Bayes net.
Definition: EliminateableFactorGraph-inst.h:30
boost::shared_ptr< BayesTreeType > eliminateMultifrontal(OptionalOrderingType orderingType=boost::none, const Eliminate &function=EliminationTraitsType::DefaultEliminate, OptionalVariableIndex variableIndex=boost::none) const
Do multifrontal elimination of all variables to produce a Bayes tree.
Definition: EliminateableFactorGraph-inst.h:84
boost::optional< Ordering::OrderingType > OptionalOrderingType
Typedef for an optional ordering type.
Definition: EliminateableFactorGraph.h:95
EliminationTraitsType::BayesTreeType BayesTreeType
Bayes tree type produced by multifrontal elimination.
Definition: EliminateableFactorGraph.h:79
std::pair< boost::shared_ptr< BayesNetType >, boost::shared_ptr< FactorGraphType > > eliminatePartialSequential(const Ordering &ordering, const Eliminate &function=EliminationTraitsType::DefaultEliminate, OptionalVariableIndex variableIndex=boost::none) const
Do sequential elimination of some variables, in ordering provided, to produce a Bayes net and a remai...
Definition: EliminateableFactorGraph-inst.h:140
boost::shared_ptr< BayesNetType > marginalMultifrontalBayesNet(boost::variant< const Ordering &, const KeyVector & > variables, const Eliminate &function=EliminationTraitsType::DefaultEliminate, OptionalVariableIndex variableIndex=boost::none) const
Compute the marginal of the requested variables and return the result as a Bayes net.
Definition: EliminateableFactorGraph-inst.h:219
std::pair< boost::shared_ptr< BayesTreeType >, boost::shared_ptr< FactorGraphType > > eliminatePartialMultifrontal(const Ordering &ordering, const Eliminate &function=EliminationTraitsType::DefaultEliminate, OptionalVariableIndex variableIndex=boost::none) const
Do multifrontal elimination of some variables, in ordering provided, to produce a Bayes tree and a re...
Definition: EliminateableFactorGraph-inst.h:179
An inference algorithm was called with inconsistent arguments.
Definition: inferenceExceptions.h:29
Definition: Ordering.h:34
static Ordering Colamd(const FACTOR_GRAPH &graph)
Compute a fill-reducing ordering using COLAMD from a factor graph (see details for note on performanc...
Definition: Ordering.h:82
static Ordering ColamdConstrainedLast(const FACTOR_GRAPH &graph, const KeyVector &constrainLast, bool forceOrder=false)
Compute a fill-reducing ordering using constrained COLAMD from a factor graph (see details for note o...
Definition: Ordering.h:101
static Ordering ColamdConstrainedFirst(const FACTOR_GRAPH &graph, const KeyVector &constrainFirst, bool forceOrder=false)
Compute a fill-reducing ordering using constrained COLAMD from a factor graph (see details for note o...
Definition: Ordering.h:128
static GTSAM_EXPORT Ordering Metis(const MetisIndex &met)
Compute an ordering determined by METIS from a VariableIndex.
Definition: Ordering.cpp:216
The VariableIndex class computes and stores the block column structure of a factor graph.
Definition: VariableIndex.h:43