HybridGaussianFactorGraph.cpp
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 
21 #include <gtsam/base/utilities.h>
34 #include <gtsam/inference/Key.h>
41 
42 #include <algorithm>
43 #include <cstddef>
44 #include <iostream>
45 #include <iterator>
46 #include <memory>
47 #include <stdexcept>
48 #include <utility>
49 #include <vector>
50 
51 namespace gtsam {
52 
54 template class EliminateableFactorGraph<HybridGaussianFactorGraph>;
55 
57 
58 using std::dynamic_pointer_cast;
59 
60 /* ************************************************************************ */
61 // Throw a runtime exception for method specified in string s, and factor f:
62 static void throwRuntimeError(const std::string &s,
63  const std::shared_ptr<Factor> &f) {
64  auto &fr = *f;
65  throw std::runtime_error(s + " not implemented for factor type " +
66  demangle(typeid(fr).name()) + ".");
67 }
68 
69 /* ************************************************************************ */
71  KeySet discrete_keys = graph.discreteKeySet();
72  const VariableIndex index(graph);
74  index, KeyVector(discrete_keys.begin(), discrete_keys.end()), true);
75 }
76 
77 /* ************************************************************************ */
79  const HybridValues &values, const std::string &str,
80  const KeyFormatter &keyFormatter,
81  const std::function<bool(const Factor * /*factor*/,
82  double /*whitenedError*/, size_t /*index*/)>
83  &printCondition) const {
84  std::cout << str << "size: " << size() << std::endl << std::endl;
85 
86  std::stringstream ss;
87 
88  for (size_t i = 0; i < factors_.size(); i++) {
89  auto &&factor = factors_[i];
90  std::cout << "Factor " << i << ": ";
91 
92  // Clear the stringstream
93  ss.str(std::string());
94 
95  if (auto gmf = std::dynamic_pointer_cast<GaussianMixtureFactor>(factor)) {
96  if (factor == nullptr) {
97  std::cout << "nullptr"
98  << "\n";
99  } else {
100  factor->print(ss.str(), keyFormatter);
101  std::cout << "error = ";
102  gmf->errorTree(values.continuous()).print("", keyFormatter);
103  std::cout << std::endl;
104  }
105  } else if (auto hc = std::dynamic_pointer_cast<HybridConditional>(factor)) {
106  if (factor == nullptr) {
107  std::cout << "nullptr"
108  << "\n";
109  } else {
110  factor->print(ss.str(), keyFormatter);
111 
112  if (hc->isContinuous()) {
113  std::cout << "error = " << hc->asGaussian()->error(values) << "\n";
114  } else if (hc->isDiscrete()) {
115  std::cout << "error = ";
116  hc->asDiscrete()->errorTree().print("", keyFormatter);
117  std::cout << "\n";
118  } else {
119  // Is hybrid
120  std::cout << "error = ";
121  hc->asMixture()->errorTree(values.continuous()).print();
122  std::cout << "\n";
123  }
124  }
125  } else if (auto gf = std::dynamic_pointer_cast<GaussianFactor>(factor)) {
126  const double errorValue = (factor != nullptr ? gf->error(values) : .0);
127  if (!printCondition(factor.get(), errorValue, i))
128  continue; // User-provided filter did not pass
129 
130  if (factor == nullptr) {
131  std::cout << "nullptr"
132  << "\n";
133  } else {
134  factor->print(ss.str(), keyFormatter);
135  std::cout << "error = " << errorValue << "\n";
136  }
137  } else if (auto df = std::dynamic_pointer_cast<DiscreteFactor>(factor)) {
138  if (factor == nullptr) {
139  std::cout << "nullptr"
140  << "\n";
141  } else {
142  factor->print(ss.str(), keyFormatter);
143  std::cout << "error = ";
144  df->errorTree().print("", keyFormatter);
145  }
146 
147  } else {
148  continue;
149  }
150 
151  std::cout << "\n";
152  }
153  std::cout.flush();
154 }
155 
156 /* ************************************************************************ */
158  const GaussianFactorGraphTree &gfgTree,
159  const GaussianFactor::shared_ptr &factor) {
160  // If the decision tree is not initialized, then initialize it.
161  if (gfgTree.empty()) {
162  GaussianFactorGraph result{factor};
164  } else {
165  auto add = [&factor](const GaussianFactorGraph &graph) {
166  auto result = graph;
167  result.push_back(factor);
168  return result;
169  };
170  return gfgTree.apply(add);
171  }
172 }
173 
174 /* ************************************************************************ */
175 // TODO(dellaert): it's probably more efficient to first collect the discrete
176 // keys, and then loop over all assignments to populate a vector.
179 
180  for (auto &f : factors_) {
181  // TODO(dellaert): just use a virtual method defined in HybridFactor.
182  if (auto gf = dynamic_pointer_cast<GaussianFactor>(f)) {
183  result = addGaussian(result, gf);
184  } else if (auto gmf = dynamic_pointer_cast<GaussianMixtureFactor>(f)) {
185  result = gmf->add(result);
186  } else if (auto gm = dynamic_pointer_cast<GaussianMixture>(f)) {
187  result = gm->add(result);
188  } else if (auto hc = dynamic_pointer_cast<HybridConditional>(f)) {
189  if (auto gm = hc->asMixture()) {
190  result = gm->add(result);
191  } else if (auto g = hc->asGaussian()) {
193  } else {
194  // Has to be discrete.
195  // TODO(dellaert): in C++20, we can use std::visit.
196  continue;
197  }
198  } else if (dynamic_pointer_cast<DiscreteFactor>(f)) {
199  // Don't do anything for discrete-only factors
200  // since we want to eliminate continuous values only.
201  continue;
202  } else {
203  // TODO(dellaert): there was an unattributed comment here: We need to
204  // handle the case where the object is actually an BayesTreeOrphanWrapper!
205  throwRuntimeError("gtsam::assembleGraphTree", f);
206  }
207  }
208 
209  return result;
210 }
211 
212 /* ************************************************************************ */
213 static std::pair<HybridConditional::shared_ptr, std::shared_ptr<Factor>>
215  const Ordering &frontalKeys) {
217  for (auto &f : factors) {
218  if (auto gf = dynamic_pointer_cast<GaussianFactor>(f)) {
219  gfg.push_back(gf);
220  } else if (auto orphan = dynamic_pointer_cast<OrphanWrapper>(f)) {
221  // Ignore orphaned clique.
222  // TODO(dellaert): is this correct? If so explain here.
223  } else if (auto hc = dynamic_pointer_cast<HybridConditional>(f)) {
224  auto gc = hc->asGaussian();
225  if (!gc) throwRuntimeError("continuousElimination", gc);
226  gfg.push_back(gc);
227  } else {
228  throwRuntimeError("continuousElimination", f);
229  }
230  }
231 
232  auto result = EliminatePreferCholesky(gfg, frontalKeys);
233  return {std::make_shared<HybridConditional>(result.first), result.second};
234 }
235 
236 /* ************************************************************************ */
237 static std::pair<HybridConditional::shared_ptr, std::shared_ptr<Factor>>
239  const Ordering &frontalKeys) {
241 
242  for (auto &f : factors) {
243  if (auto df = dynamic_pointer_cast<DiscreteFactor>(f)) {
244  dfg.push_back(df);
245  } else if (auto orphan = dynamic_pointer_cast<OrphanWrapper>(f)) {
246  // Ignore orphaned clique.
247  // TODO(dellaert): is this correct? If so explain here.
248  } else if (auto hc = dynamic_pointer_cast<HybridConditional>(f)) {
249  auto dc = hc->asDiscrete();
250  if (!dc) throwRuntimeError("discreteElimination", dc);
251  dfg.push_back(hc->asDiscrete());
252  } else {
253  throwRuntimeError("discreteElimination", f);
254  }
255  }
256 
257  // NOTE: This does sum-product. For max-product, use EliminateForMPE.
258  auto result = EliminateDiscrete(dfg, frontalKeys);
259 
260  return {std::make_shared<HybridConditional>(result.first), result.second};
261 }
262 
263 /* ************************************************************************ */
264 // If any GaussianFactorGraph in the decision tree contains a nullptr, convert
265 // that leaf to an empty GaussianFactorGraph. Needed since the DecisionTree will
266 // otherwise create a GFG with a single (null) factor,
267 // which doesn't register as null.
269  auto emptyGaussian = [](const GaussianFactorGraph &graph) {
270  bool hasNull =
272  [](const GaussianFactor::shared_ptr &ptr) { return !ptr; });
273  return hasNull ? GaussianFactorGraph() : graph;
274  };
275  return GaussianFactorGraphTree(sum, emptyGaussian);
276 }
277 
278 /* ************************************************************************ */
279 using Result = std::pair<std::shared_ptr<GaussianConditional>,
281 
282 // Integrate the probability mass in the last continuous conditional using
283 // the unnormalized probability q(μ;m) = exp(-error(μ;m)) at the mean.
284 // discrete_probability = exp(-error(μ;m)) * sqrt(det(2π Σ_m))
285 static std::shared_ptr<Factor> createDiscreteFactor(
286  const DecisionTree<Key, Result> &eliminationResults,
287  const DiscreteKeys &discreteSeparator) {
288  auto probability = [&](const Result &pair) -> double {
289  const auto &[conditional, factor] = pair;
290  static const VectorValues kEmpty;
291  // If the factor is not null, it has no keys, just contains the residual.
292  if (!factor) return 1.0; // TODO(dellaert): not loving this.
293  return exp(-factor->error(kEmpty)) / conditional->normalizationConstant();
294  };
295 
296  DecisionTree<Key, double> probabilities(eliminationResults, probability);
297 
298  return std::make_shared<DecisionTreeFactor>(discreteSeparator, probabilities);
299 }
300 
301 // Create GaussianMixtureFactor on the separator, taking care to correct
302 // for conditional constants.
303 static std::shared_ptr<Factor> createGaussianMixtureFactor(
304  const DecisionTree<Key, Result> &eliminationResults,
305  const KeyVector &continuousSeparator,
306  const DiscreteKeys &discreteSeparator) {
307  // Correct for the normalization constant used up by the conditional
308  auto correct = [&](const Result &pair) -> GaussianFactor::shared_ptr {
309  const auto &[conditional, factor] = pair;
310  if (factor) {
311  auto hf = std::dynamic_pointer_cast<HessianFactor>(factor);
312  if (!hf) throw std::runtime_error("Expected HessianFactor!");
313  hf->constantTerm() += 2.0 * conditional->logNormalizationConstant();
314  }
315  return factor;
316  };
317  DecisionTree<Key, GaussianFactor::shared_ptr> newFactors(eliminationResults,
318  correct);
319 
320  return std::make_shared<GaussianMixtureFactor>(continuousSeparator,
321  discreteSeparator, newFactors);
322 }
323 
324 static std::pair<HybridConditional::shared_ptr, std::shared_ptr<Factor>>
326  const Ordering &frontalKeys,
327  const KeyVector &continuousSeparator,
328  const std::set<DiscreteKey> &discreteSeparatorSet) {
329  // NOTE: since we use the special JunctionTree,
330  // only possibility is continuous conditioned on discrete.
331  DiscreteKeys discreteSeparator(discreteSeparatorSet.begin(),
332  discreteSeparatorSet.end());
333 
334  // Collect all the factors to create a set of Gaussian factor graphs in a
335  // decision tree indexed by all discrete keys involved.
336  GaussianFactorGraphTree factorGraphTree = factors.assembleGraphTree();
337 
338  // Convert factor graphs with a nullptr to an empty factor graph.
339  // This is done after assembly since it is non-trivial to keep track of which
340  // FG has a nullptr as we're looping over the factors.
341  factorGraphTree = removeEmpty(factorGraphTree);
342 
343  // This is the elimination method on the leaf nodes
344  auto eliminate = [&](const GaussianFactorGraph &graph) -> Result {
345  if (graph.empty()) {
346  return {nullptr, nullptr};
347  }
348 
349  auto result = EliminatePreferCholesky(graph, frontalKeys);
350 
351  return result;
352  };
353 
354  // Perform elimination!
355  DecisionTree<Key, Result> eliminationResults(factorGraphTree, eliminate);
356 
357  // If there are no more continuous parents we create a DiscreteFactor with the
358  // error for each discrete choice. Otherwise, create a GaussianMixtureFactor
359  // on the separator, taking care to correct for conditional constants.
360  auto newFactor =
361  continuousSeparator.empty()
362  ? createDiscreteFactor(eliminationResults, discreteSeparator)
363  : createGaussianMixtureFactor(eliminationResults, continuousSeparator,
364  discreteSeparator);
365 
366  // Create the GaussianMixture from the conditionals
368  eliminationResults, [](const Result &pair) { return pair.first; });
369  auto gaussianMixture = std::make_shared<GaussianMixture>(
370  frontalKeys, continuousSeparator, discreteSeparator, conditionals);
371 
372  return {std::make_shared<HybridConditional>(gaussianMixture), newFactor};
373 }
374 
375 /* ************************************************************************
376  * Function to eliminate variables **under the following assumptions**:
377  * 1. When the ordering is fully continuous, and the graph only contains
378  * continuous and hybrid factors
379  * 2. When the ordering is fully discrete, and the graph only contains discrete
380  * factors
381  *
382  * Any usage outside of this is considered incorrect.
383  *
384  * \warning This function is not meant to be used with arbitrary hybrid factor
385  * graphs. For example, if there exists continuous parents, and one tries to
386  * eliminate a discrete variable (as specified in the ordering), the result will
387  * be INCORRECT and there will be NO error raised.
388  */
389 std::pair<HybridConditional::shared_ptr, std::shared_ptr<Factor>> //
391  const Ordering &frontalKeys) {
392  // NOTE: Because we are in the Conditional Gaussian regime there are only
393  // a few cases:
394  // 1. continuous variable, make a Gaussian Mixture if there are hybrid
395  // factors;
396  // 2. continuous variable, we make a Gaussian Factor if there are no hybrid
397  // factors;
398  // 3. discrete variable, no continuous factor is allowed
399  // (escapes Conditional Gaussian regime), if discrete only we do the discrete
400  // elimination.
401 
402  // However it is not that simple. During elimination it is possible that the
403  // multifrontal needs to eliminate an ordering that contains both Gaussian and
404  // hybrid variables, for example x1, c1.
405  // In this scenario, we will have a density P(x1, c1) that is a Conditional
406  // Linear Gaussian P(x1|c1)P(c1) (see Murphy02).
407 
408  // The issue here is that, how can we know which variable is discrete if we
409  // unify Values? Obviously we can tell using the factors, but is that fast?
410 
411  // In the case of multifrontal, we will need to use a constrained ordering
412  // so that the discrete parts will be guaranteed to be eliminated last!
413  // Because of all these reasons, we carefully consider how to
414  // implement the hybrid factors so that we do not get poor performance.
415 
416  // The first thing is how to represent the GaussianMixture.
417  // A very possible scenario is that the incoming factors will have different
418  // levels of discrete keys. For example, imagine we are going to eliminate the
419  // fragment: $\phi(x1,c1,c2)$, $\phi(x1,c2,c3)$, which is perfectly valid.
420  // Now we will need to know how to retrieve the corresponding continuous
421  // densities for the assignment (c1,c2,c3) (OR (c2,c3,c1), note there is NO
422  // defined order!). We also need to consider when there is pruning. Two
423  // mixture factors could have different pruning patterns - one could have
424  // (c1=0,c2=1) pruned, and another could have (c2=0,c3=1) pruned, and this
425  // creates a big problem in how to identify the intersection of non-pruned
426  // branches.
427 
428  // Our approach is first building the collection of all discrete keys. After
429  // that we enumerate the space of all key combinations *lazily* so that the
430  // exploration branch terminates whenever an assignment yields NULL in any of
431  // the hybrid factors.
432 
433  // When the number of assignments is large we may encounter stack overflows.
434  // However this is also the case with iSAM2, so no pressure :)
435 
436  // Check the factors:
437  // 1. if all factors are discrete, then we can do discrete elimination:
438  // 2. if all factors are continuous, then we can do continuous elimination:
439  // 3. if not, we do hybrid elimination:
440 
441  bool only_discrete = true, only_continuous = true;
442  for (auto &&factor : factors) {
443  if (auto hybrid_factor = std::dynamic_pointer_cast<HybridFactor>(factor)) {
444  if (hybrid_factor->isDiscrete()) {
445  only_continuous = false;
446  } else if (hybrid_factor->isContinuous()) {
447  only_discrete = false;
448  } else if (hybrid_factor->isHybrid()) {
449  only_continuous = false;
450  only_discrete = false;
451  }
452  } else if (auto cont_factor =
453  std::dynamic_pointer_cast<GaussianFactor>(factor)) {
454  only_discrete = false;
455  } else if (auto discrete_factor =
456  std::dynamic_pointer_cast<DiscreteFactor>(factor)) {
457  only_continuous = false;
458  }
459  }
460 
461  // NOTE: We should really defer the product here because of pruning
462 
463  if (only_discrete) {
464  // Case 1: we are only dealing with discrete
465  return discreteElimination(factors, frontalKeys);
466  } else if (only_continuous) {
467  // Case 2: we are only dealing with continuous
468  return continuousElimination(factors, frontalKeys);
469  } else {
470  // Case 3: We are now in the hybrid land!
471  KeySet frontalKeysSet(frontalKeys.begin(), frontalKeys.end());
472 
473  // Find all the keys in the set of continuous keys
474  // which are not in the frontal keys. This is our continuous separator.
475  KeyVector continuousSeparator;
476  auto continuousKeySet = factors.continuousKeySet();
477  std::set_difference(
478  continuousKeySet.begin(), continuousKeySet.end(),
479  frontalKeysSet.begin(), frontalKeysSet.end(),
480  std::inserter(continuousSeparator, continuousSeparator.begin()));
481 
482  // Similarly for the discrete separator.
483  KeySet discreteSeparatorSet;
484  std::set<DiscreteKey> discreteSeparator;
485  auto discreteKeySet = factors.discreteKeySet();
486  std::set_difference(
487  discreteKeySet.begin(), discreteKeySet.end(), frontalKeysSet.begin(),
488  frontalKeysSet.end(),
489  std::inserter(discreteSeparatorSet, discreteSeparatorSet.begin()));
490  // Convert from set of keys to set of DiscreteKeys
491  auto discreteKeyMap = factors.discreteKeyMap();
492  for (auto key : discreteSeparatorSet) {
493  discreteSeparator.insert(discreteKeyMap.at(key));
494  }
495 
496  return hybridElimination(factors, frontalKeys, continuousSeparator,
497  discreteSeparator);
498  }
499 }
500 
501 /* ************************************************************************ */
503  const VectorValues &continuousValues) const {
504  AlgebraicDecisionTree<Key> error_tree(0.0);
505 
506  // Iterate over each factor.
507  for (auto &f : factors_) {
508  // TODO(dellaert): just use a virtual method defined in HybridFactor.
509  AlgebraicDecisionTree<Key> factor_error;
510 
511  if (auto gaussianMixture = dynamic_pointer_cast<GaussianMixtureFactor>(f)) {
512  // Compute factor error and add it.
513  error_tree = error_tree + gaussianMixture->errorTree(continuousValues);
514  } else if (auto gaussian = dynamic_pointer_cast<GaussianFactor>(f)) {
515  // If continuous only, get the (double) error
516  // and add it to the error_tree
517  double error = gaussian->error(continuousValues);
518  // Add the gaussian factor error to every leaf of the error tree.
519  error_tree = error_tree.apply(
520  [error](double leaf_value) { return leaf_value + error; });
521  } else if (dynamic_pointer_cast<DiscreteFactor>(f)) {
522  // If factor at `idx` is discrete-only, we skip.
523  continue;
524  } else {
525  throwRuntimeError("HybridGaussianFactorGraph::error(VV)", f);
526  }
527  }
528 
529  return error_tree;
530 }
531 
532 /* ************************************************************************ */
534  double error = this->error(values);
535  // NOTE: The 0.5 term is handled by each factor
536  return std::exp(-error);
537 }
538 
539 /* ************************************************************************ */
541  const VectorValues &continuousValues) const {
542  AlgebraicDecisionTree<Key> error_tree = this->errorTree(continuousValues);
543  AlgebraicDecisionTree<Key> prob_tree = error_tree.apply([](double error) {
544  // NOTE: The 0.5 term is handled by each factor
545  return exp(-error);
546  });
547  return prob_tree;
548 }
549 
550 } // namespace gtsam
gtsam::BayesTreeOrphanWrapper
Definition: BayesTree.h:281
HybridJunctionTree.h
gtsam::Ordering::ColamdConstrainedLast
static Ordering ColamdConstrainedLast(const FACTOR_GRAPH &graph, const KeyVector &constrainLast, bool forceOrder=false)
Definition: inference/Ordering.h:112
GaussianFactorGraph.h
Linear Factor Graph where all factors are Gaussians.
gtsam::HybridValues
Definition: HybridValues.h:38
GaussianConditional.h
Conditional Gaussian Base class.
gtsam::FactorGraph< Factor >::factors_
FastVector< sharedFactor > factors_
Definition: FactorGraph.h:92
gtsam::DiscreteFactorGraph
Definition: DiscreteFactorGraph.h:98
gtsam::HybridGaussianFactorGraph::probPrime
AlgebraicDecisionTree< Key > probPrime(const VectorValues &continuousValues) const
Compute unnormalized probability for each discrete assignment, and return as a tree.
Definition: HybridGaussianFactorGraph.cpp:540
s
RealScalar s
Definition: level1_cplx_impl.h:126
gtsam::FactorGraph< Factor >::error
double error(const HybridValues &values) const
Definition: FactorGraph-inst.h:66
DiscreteFactorGraph.h
gtsam::DecisionTree::empty
bool empty() const
Check if tree is empty.
Definition: DecisionTree.h:269
simple_graph::factors
const GaussianFactorGraph factors
Definition: testJacobianFactor.cpp:213
EliminateableFactorGraph-inst.h
HessianFactor.h
Contains the HessianFactor class, a general quadratic factor.
gtsam::Factor
Definition: Factor.h:69
gtsam::DiscreteKeys
DiscreteKeys is a set of keys that can be assembled using the & operator.
Definition: DiscreteKey.h:41
gtsam::HybridGaussianFactorGraph::assembleGraphTree
GaussianFactorGraphTree assembleGraphTree() const
Create a decision tree of factor graphs out of this hybrid factor graph.
Definition: HybridGaussianFactorGraph.cpp:177
gtsam::FastSet
Definition: FastSet.h:51
any_of
negation< all_of< negation< Ts >... > > any_of
Definition: wrap/pybind11/include/pybind11/detail/common.h:728
GaussianJunctionTree.h
exp
const EIGEN_DEVICE_FUNC ExpReturnType exp() const
Definition: ArrayCwiseUnaryOps.h:97
gtsam::KeyVector
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
Definition: Key.h:92
result
Values result
Definition: OdometryOptimize.cpp:8
utilities.h
equal_constants::conditionals
const std::vector< GaussianConditional::shared_ptr > conditionals
Definition: testGaussianMixture.cpp:51
gtsam::GaussianMixtureFactor::sharedFactor
std::shared_ptr< GaussianFactor > sharedFactor
Definition: GaussianMixtureFactor.h:53
hc
Vector3d hc
Definition: Tridiagonalization_householderCoefficients.cpp:5
name
static char name[]
Definition: rgamma.c:72
gtsam::AlgebraicDecisionTree< Key >
ss
static std::stringstream ss
Definition: testBTree.cpp:31
gtsam::EliminatePreferCholesky
std::pair< std::shared_ptr< GaussianConditional >, std::shared_ptr< GaussianFactor > > EliminatePreferCholesky(const GaussianFactorGraph &factors, const Ordering &keys)
Definition: HessianFactor.cpp:540
Key.h
gtsam::GaussianFactorGraph
Definition: GaussianFactorGraph.h:73
GaussianEliminationTree.h
HybridFactor.h
gtsam::VectorValues
Definition: VectorValues.h:74
gtsam::addGaussian
static GaussianFactorGraphTree addGaussian(const GaussianFactorGraphTree &gfgTree, const GaussianFactor::shared_ptr &factor)
Definition: HybridGaussianFactorGraph.cpp:157
gtsam::EliminateDiscrete
std::pair< DiscreteConditional::shared_ptr, DecisionTreeFactor::shared_ptr > EliminateDiscrete(const DiscreteFactorGraph &factors, const Ordering &frontalKeys)
Main elimination function for DiscreteFactorGraph.
Definition: DiscreteFactorGraph.cpp:205
gtsam::throwRuntimeError
static void throwRuntimeError(const std::string &s, const std::shared_ptr< Factor > &f)
Definition: HybridGaussianFactorGraph.cpp:62
gtsam::KeyFormatter
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
DiscreteJunctionTree.h
add
graph add(PriorFactor< Pose2 >(1, priorMean, priorNoise))
gtsam::GaussianFactor::shared_ptr
std::shared_ptr< This > shared_ptr
shared_ptr to this class
Definition: GaussianFactor.h:42
gtsam::continuousElimination
static std::pair< HybridConditional::shared_ptr, std::shared_ptr< Factor > > continuousElimination(const HybridGaussianFactorGraph &factors, const Ordering &frontalKeys)
Definition: HybridGaussianFactorGraph.cpp:214
Assignment.h
An assignment from labels to a discrete value index (size_t)
gtsam::discreteElimination
static std::pair< HybridConditional::shared_ptr, std::shared_ptr< Factor > > discreteElimination(const HybridGaussianFactorGraph &factors, const Ordering &frontalKeys)
Definition: HybridGaussianFactorGraph.cpp:238
gtsam::HybridGaussianFactorGraph
Definition: HybridGaussianFactorGraph.h:104
GaussianMixture.h
A hybrid conditional in the Conditional Linear Gaussian scheme.
gtsam::EliminateHybrid
std::pair< HybridConditional::shared_ptr, std::shared_ptr< Factor > > EliminateHybrid(const HybridGaussianFactorGraph &factors, const Ordering &frontalKeys)
Main elimination function for HybridGaussianFactorGraph.
Definition: HybridGaussianFactorGraph.cpp:390
gtsam::removeEmpty
GaussianFactorGraphTree removeEmpty(const GaussianFactorGraphTree &sum)
Definition: HybridGaussianFactorGraph.cpp:268
gtsam::DecisionTree::apply
DecisionTree apply(const Unary &op) const
Definition: DecisionTree-inl.h:921
DiscreteEliminationTree.h
gtsam::createDiscreteFactor
static std::shared_ptr< Factor > createDiscreteFactor(const DecisionTree< Key, Result > &eliminationResults, const DiscreteKeys &discreteSeparator)
Definition: HybridGaussianFactorGraph.cpp:285
gtsam::VariableIndex
Definition: VariableIndex.h:41
g
void g(const string &key, int i)
Definition: testBTree.cpp:41
str
Definition: pytypes.h:1524
key
const gtsam::Symbol key('X', 0)
JacobianFactor.h
tree::f
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
Definition: testExpression.cpp:218
gtsam::FactorGraph< Factor >::size
size_t size() const
Definition: FactorGraph.h:297
gtsam::DecisionTree
a decision tree is a function from assignments to values.
Definition: DecisionTree.h:63
gtsam::FactorGraph::empty
bool empty() const
Definition: FactorGraph.h:301
HybridEliminationTree.h
gtsam::createGaussianMixtureFactor
static std::shared_ptr< Factor > createGaussianMixtureFactor(const DecisionTree< Key, Result > &eliminationResults, const KeyVector &continuousSeparator, const DiscreteKeys &discreteSeparator)
Definition: HybridGaussianFactorGraph.cpp:303
HybridGaussianFactorGraph.h
Linearized Hybrid factor graph that uses type erasure.
gtsam
traits
Definition: chartTesting.h:28
gtsam::HybridGaussianFactorGraph::printErrors
void printErrors(const HybridValues &values, const std::string &str="HybridGaussianFactorGraph: ", const KeyFormatter &keyFormatter=DefaultKeyFormatter, const std::function< bool(const Factor *, double, size_t)> &printCondition=[](const Factor *, double, size_t) { return true;}) const
Definition: HybridGaussianFactorGraph.cpp:78
gtsam::FactorGraph::push_back
IsDerived< DERIVEDFACTOR > push_back(std::shared_ptr< DERIVEDFACTOR > factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:147
leaf::values
leaf::MyValues values
gtsam::demangle
std::string demangle(const char *name)
Pretty print Value type name.
Definition: types.cpp:37
gtsam::FactorGraph::end
const_iterator end() const
Definition: FactorGraph.h:342
gtsam::hybridElimination
static std::pair< HybridConditional::shared_ptr, std::shared_ptr< Factor > > hybridElimination(const HybridGaussianFactorGraph &factors, const Ordering &frontalKeys, const KeyVector &continuousSeparator, const std::set< DiscreteKey > &discreteSeparatorSet)
Definition: HybridGaussianFactorGraph.cpp:325
gtsam::HybridGaussianFactorGraph::errorTree
AlgebraicDecisionTree< Key > errorTree(const VectorValues &continuousValues) const
Compute error for each discrete assignment, and return as a tree.
Definition: HybridGaussianFactorGraph.cpp:502
gtsam::HybridOrdering
const Ordering HybridOrdering(const HybridGaussianFactorGraph &graph)
Return a Colamd constrained ordering where the discrete keys are eliminated after the continuous keys...
Definition: HybridGaussianFactorGraph.cpp:70
gtsam::FactorGraph::begin
const_iterator begin() const
Definition: FactorGraph.h:339
graph
NonlinearFactorGraph graph
Definition: doc/Code/OdometryExample.cpp:2
gtsam::Ordering
Definition: inference/Ordering.h:33
gtsam::GaussianFactorGraphTree
DecisionTree< Key, GaussianFactorGraph > GaussianFactorGraphTree
Alias for DecisionTree of GaussianFactorGraphs.
Definition: HybridFactor.h:35
i
int i
Definition: BiCGSTAB_step_by_step.cpp:9
GaussianMixtureFactor.h
A set of GaussianFactors, indexed by a set of discrete keys.
gtsam::Result
std::pair< std::shared_ptr< GaussianConditional >, GaussianMixtureFactor::sharedFactor > Result
Definition: HybridGaussianFactorGraph.cpp:280
HybridConditional.h


gtsam
Author(s):
autogenerated on Thu Jun 13 2024 03:02:34