HybridSmoother.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 
20 
21 #include <algorithm>
22 #include <unordered_set>
23 
24 namespace gtsam {
25 
26 /* ************************************************************************* */
28  const HybridGaussianFactorGraph &newFactors) {
30  factors.push_back(newFactors);
31 
32  // Get all the discrete keys from the factors
33  KeySet allDiscrete = factors.discreteKeySet();
34 
35  // Create KeyVector with continuous keys followed by discrete keys.
36  KeyVector newKeysDiscreteLast;
37  const KeySet newFactorKeys = newFactors.keys();
38  // Insert continuous keys first.
39  for (auto &k : newFactorKeys) {
40  if (!allDiscrete.exists(k)) {
41  newKeysDiscreteLast.push_back(k);
42  }
43  }
44 
45  // Insert discrete keys at the end
46  std::copy(allDiscrete.begin(), allDiscrete.end(),
47  std::back_inserter(newKeysDiscreteLast));
48 
49  const VariableIndex index(factors);
50 
51  // Get an ordering where the new keys are eliminated last
53  index, KeyVector(newKeysDiscreteLast.begin(), newKeysDiscreteLast.end()),
54  true);
55  return ordering;
56 }
57 
58 /* ************************************************************************* */
60  std::optional<size_t> maxNrLeaves,
61  const std::optional<Ordering> given_ordering) {
63  // If no ordering provided, then we compute one
64  if (!given_ordering.has_value()) {
65  ordering = this->getOrdering(graph);
66  } else {
67  ordering = *given_ordering;
68  }
69 
70  // Add the necessary conditionals from the previous timestep(s).
71  std::tie(graph, hybridBayesNet_) =
72  addConditionals(graph, hybridBayesNet_, ordering);
73 
74  // Eliminate.
75  auto bayesNetFragment = graph.eliminateSequential(ordering);
76 
78  if (maxNrLeaves) {
79  // `pruneBayesNet` sets the leaves with 0 in discreteFactor to nullptr in
80  // all the conditionals with the same keys in bayesNetFragment.
81  HybridBayesNet prunedBayesNetFragment =
82  bayesNetFragment->prune(*maxNrLeaves);
83  // Set the bayes net fragment to the pruned version
84  bayesNetFragment = std::make_shared<HybridBayesNet>(prunedBayesNetFragment);
85  }
86 
87  // Add the partial bayes net to the posterior bayes net.
88  hybridBayesNet_.add(*bayesNetFragment);
89 }
90 
91 /* ************************************************************************* */
92 std::pair<HybridGaussianFactorGraph, HybridBayesNet>
94  const HybridBayesNet &originalHybridBayesNet,
95  const Ordering &ordering) const {
96  HybridGaussianFactorGraph graph(originalGraph);
97  HybridBayesNet hybridBayesNet(originalHybridBayesNet);
98 
99  // If we are not at the first iteration, means we have conditionals to add.
100  if (!hybridBayesNet.empty()) {
101  // We add all relevant conditional mixtures on the last continuous variable
102  // in the previous `hybridBayesNet` to the graph
103 
104  // Conditionals to remove from the bayes net
105  // since the conditional will be updated.
106  std::vector<HybridConditional::shared_ptr> conditionals_to_erase;
107 
108  // New conditionals to add to the graph
109  gtsam::HybridBayesNet newConditionals;
110 
111  // NOTE(Varun) Using a for-range loop doesn't work since some of the
112  // conditionals are invalid pointers
113  for (size_t i = 0; i < hybridBayesNet.size(); i++) {
114  auto conditional = hybridBayesNet.at(i);
115 
116  for (auto &key : conditional->frontals()) {
117  if (std::find(ordering.begin(), ordering.end(), key) !=
118  ordering.end()) {
119  newConditionals.push_back(conditional);
120  conditionals_to_erase.push_back(conditional);
121 
122  break;
123  }
124  }
125  }
126  // Remove conditionals at the end so we don't affect the order in the
127  // original bayes net.
128  for (auto &&conditional : conditionals_to_erase) {
129  auto it = find(hybridBayesNet.begin(), hybridBayesNet.end(), conditional);
130  hybridBayesNet.erase(it);
131  }
132 
133  graph.push_back(newConditionals);
134  }
135  return {graph, hybridBayesNet};
136 }
137 
138 /* ************************************************************************* */
140  size_t index) const {
141  return hybridBayesNet_.at(index)->asMixture();
142 }
143 
144 /* ************************************************************************* */
146  return hybridBayesNet_;
147 }
148 
149 } // namespace gtsam
const gtsam::Symbol key('X', 0)
KeySet discreteKeySet() const
Get all the discrete keys in the factor graph, as a set.
An incremental smoother for hybrid factor graphs.
KeySet keys() const
std::pair< HybridGaussianFactorGraph, HybridBayesNet > addConditionals(const HybridGaussianFactorGraph &graph, const HybridBayesNet &hybridBayesNet, const Ordering &ordering) const
Add conditionals from previous timestep as part of liquefication.
IsDerived< DERIVEDFACTOR > push_back(std::shared_ptr< DERIVEDFACTOR > factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:190
bool exists(const VALUE &e) const
Definition: FastSet.h:98
const GaussianFactorGraph factors
GaussianMixture::shared_ptr gaussianMixture(size_t index) const
Get the Gaussian Mixture from the Bayes Net posterior at index.
const HybridBayesNet & hybridBayesNet() const
Return the Bayes Net posterior.
NonlinearFactorGraph graph
static enum @1107 ordering
IsDerived< DERIVEDFACTOR > add(std::shared_ptr< DERIVEDFACTOR > factor)
add is a synonym for push_back.
Definition: FactorGraph.h:214
size_t size() const
Definition: FactorGraph.h:334
const_iterator begin() const
Definition: FactorGraph.h:361
bool empty() const
Definition: FactorGraph.h:338
HybridBayesNet hybridBayesNet_
HybridBayesNet prune(size_t maxNrLeaves)
Prune the Hybrid Bayes Net such that we have at most maxNrLeaves leaves.
std::shared_ptr< BayesNetType > eliminateSequential(OptionalOrderingType orderingType={}, const Eliminate &function=EliminationTraitsType::DefaultEliminate, OptionalVariableIndex variableIndex={}) const
void push_back(std::shared_ptr< HybridConditional > conditional)
Add a hybrid conditional using a shared_ptr.
const_iterator end() const
Definition: FactorGraph.h:364
traits
Definition: chartTesting.h:28
const sharedFactor at(size_t i) const
Definition: FactorGraph.h:343
std::shared_ptr< GaussianMixture > shared_ptr
Ordering getOrdering(const HybridGaussianFactorGraph &newFactors)
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
Definition: Key.h:86
void update(HybridGaussianFactorGraph graph, std::optional< size_t > maxNrLeaves={}, const std::optional< Ordering > given_ordering={})
static Ordering ColamdConstrainedLast(const FACTOR_GRAPH &graph, const KeyVector &constrainLast, bool forceOrder=false)
iterator erase(iterator item)
Definition: FactorGraph.h:399


gtsam
Author(s):
autogenerated on Tue Jul 4 2023 02:34:21