HybridJunctionTree.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 
22 #include <gtsam/inference/Key.h>
23 
24 #include <unordered_map>
25 #include <cassert>
26 
27 namespace gtsam {
28 
29 // Instantiate base classes
30 template class EliminatableClusterTree<HybridBayesTree,
31  HybridGaussianFactorGraph>;
32 template class JunctionTree<HybridBayesTree, HybridGaussianFactorGraph>;
33 
36  typedef
39 
45 
46  // Small inner class to store symbolic factors
47  class SymbolicFactors : public FactorGraph<Factor> {};
48 
50  : parentData(_parentData) {}
51 
52  // Pre-order visitor function
54  const std::shared_ptr<HybridEliminationTree::Node>& node,
56  // On the pre-order pass, before children have been visited, we just set up
57  // a traversal data structure with its own JT node, and create a child
58  // pointer in its parent.
61  data.junctionTreeNode = std::make_shared<Node>(node->key, node->factors);
62  parentData.junctionTreeNode->addChild(data.junctionTreeNode);
63 
64  // Add all the discrete keys in the hybrid factors to the current data
65  for (const auto& f : node->factors) {
66  if (auto hf = std::dynamic_pointer_cast<HybridFactor>(f)) {
67  for (auto& k : hf->discreteKeys()) {
68  data.discreteKeys.insert(k.first);
69  }
70  } else if (auto hf = std::dynamic_pointer_cast<DiscreteFactor>(f)) {
71  for (auto& k : hf->discreteKeys()) {
72  data.discreteKeys.insert(k.first);
73  }
74  }
75  }
76 
77  return data;
78  }
79 
80  // Post-order visitor function
82  const std::shared_ptr<HybridEliminationTree::Node>& node,
84  // In this post-order visitor, we combine the symbolic elimination results
85  // from the elimination tree children and symbolically eliminate the current
86  // elimination tree node. We then check whether each of our elimination
87  // tree child nodes should be merged with us. The check for this is that
88  // our number of symbolic elimination parents is exactly 1 less than
89  // our child's symbolic elimination parents - this condition indicates that
90  // eliminating the current node did not introduce any parents beyond those
91  // already in the child->
92 
93  // Do symbolic elimination for this node
94  SymbolicFactors symbolicFactors;
95  symbolicFactors.reserve(node->factors.size() +
96  data.childSymbolicFactors.size());
97  // Add ETree node factors
98  symbolicFactors.push_back(node->factors);
99  // Add symbolic factors passed up from children
100  symbolicFactors.push_back(data.childSymbolicFactors);
101 
102  Ordering keyAsOrdering;
103  keyAsOrdering.push_back(node->key);
104  const auto [conditional, separatorFactor] =
105  internal::EliminateSymbolic(symbolicFactors, keyAsOrdering);
106 
107  // Store symbolic elimination results in the parent
108  data.parentData->childSymbolicConditionals.push_back(conditional);
109  data.parentData->childSymbolicFactors.push_back(separatorFactor);
110  data.parentData->discreteKeys.merge(data.discreteKeys);
111 
112  sharedNode jt_node = data.junctionTreeNode;
113  const FastVector<SymbolicConditional::shared_ptr>& childConditionals =
114  data.childSymbolicConditionals;
115  jt_node->problemSize_ = (int)(conditional->size() * symbolicFactors.size());
116 
117  // Merge our children if they are in our clique - if our conditional has
118  // exactly one fewer parent than our child's conditional.
119  const size_t nrParents = conditional->nrParents();
120  const size_t nrChildren = jt_node->nrChildren();
121  assert(childConditionals.size() == nrChildren);
122 
123  // decide which children to merge, as index into children
124  std::vector<size_t> nrChildrenFrontals = jt_node->nrFrontalsOfChildren();
125  std::vector<bool> merge(nrChildren, false);
126  size_t nrFrontals = 1;
127  for (size_t i = 0; i < nrChildren; i++) {
128  // Check if we should merge the i^th child
129  if (nrParents + nrFrontals == childConditionals[i]->nrParents()) {
130  const bool myType =
131  data.discreteKeys.exists(conditional->frontals().front());
132  const bool theirType =
133  data.discreteKeys.exists(childConditionals[i]->frontals().front());
134 
135  if (myType == theirType) {
136  // Increment number of frontal variables
137  nrFrontals += nrChildrenFrontals[i];
138  merge[i] = true;
139  }
140  }
141  }
142 
143  // now really merge
144  jt_node->mergeChildren(merge);
145  }
146 };
147 
148 /* ************************************************************************* */
150  const HybridEliminationTree& eliminationTree) {
151  gttic(JunctionTree_FromEliminationTree);
152  // Here we rely on the BayesNet having been produced by this elimination tree,
153  // such that the conditionals are arranged in DFS post-order. We traverse the
154  // elimination tree, and inspect the symbolic conditional corresponding to
155  // each node. The elimination tree node is added to the same clique with its
156  // parent if it has exactly one more Bayes net conditional parent than
157  // does its elimination tree parent.
158 
159  // Traverse the elimination tree, doing symbolic elimination and merging nodes
160  // as we go. Gather the created junction tree roots in a dummy Node.
161  typedef HybridConstructorTraversalData Data;
162  Data rootData(0);
163  rootData.junctionTreeNode =
164  std::make_shared<typename Base::Node>(); // Make a dummy node to gather
165  // the junction tree roots
166  treeTraversal::DepthFirstForest(eliminationTree, rootData,
167  Data::ConstructorTraversalVisitorPre,
168  Data::ConstructorTraversalVisitorPost);
169 
170  // Assign roots from the dummy node
171  this->addChildrenAsRoots(rootData.junctionTreeNode);
172 
173  // Transfer remaining factors from elimination tree
174  Base::remainingFactors_ = eliminationTree.remainingFactors();
175 }
176 
177 } // namespace gtsam
gtsam::HybridConstructorTraversalData::childSymbolicConditionals
FastVector< SymbolicConditional::shared_ptr > childSymbolicConditionals
Definition: HybridJunctionTree.cpp:42
gtsam.examples.DogLegOptimizerExample.int
int
Definition: DogLegOptimizerExample.py:111
HybridJunctionTree.h
gtsam::HybridConstructorTraversalData::Node
HybridJunctionTree::Node Node
Definition: HybridJunctionTree.cpp:35
gtsam::FastVector
std::vector< T, typename internal::FastDefaultVectorAllocator< T >::type > FastVector
Definition: FastVector.h:34
gtsam::HybridConstructorTraversalData::SymbolicFactors
Definition: HybridJunctionTree.cpp:47
gtsam::HybridConstructorTraversalData::junctionTreeNode
sharedNode junctionTreeNode
Definition: HybridJunctionTree.cpp:41
gtsam::HybridConstructorTraversalData::HybridConstructorTraversalData
HybridConstructorTraversalData(HybridConstructorTraversalData *_parentData)
Definition: HybridJunctionTree.cpp:49
gtsam::HybridBayesTree
Definition: HybridBayesTree.h:62
gtsam::HybridConstructorTraversalData::sharedNode
JunctionTree< HybridBayesTree, HybridGaussianFactorGraph >::sharedNode sharedNode
Definition: HybridJunctionTree.cpp:38
gtsam::HybridConstructorTraversalData::ConstructorTraversalVisitorPre
static HybridConstructorTraversalData ConstructorTraversalVisitorPre(const std::shared_ptr< HybridEliminationTree::Node > &node, HybridConstructorTraversalData &parentData)
Definition: HybridJunctionTree.cpp:53
gtsam::FastSet< Key >
gtsam::HybridConstructorTraversalData
Definition: HybridJunctionTree.cpp:34
gtsam::HybridConstructorTraversalData::childSymbolicFactors
FastVector< SymbolicFactor::shared_ptr > childSymbolicFactors
Definition: HybridJunctionTree.cpp:43
gtsam::FactorGraph
Definition: BayesTree.h:34
Key.h
gtsam::internal::EliminateSymbolic
std::pair< std::shared_ptr< SymbolicConditional >, std::shared_ptr< SymbolicFactor > > EliminateSymbolic(const FactorGraph< FACTOR > &factors, const Ordering &keys)
Definition: SymbolicFactor-inst.h:38
data
int data[]
Definition: Map_placement_new.cpp:1
parentData
DATA & parentData
Definition: treeTraversal-inst.h:45
gtsam::HybridConstructorTraversalData::discreteKeys
KeySet discreteKeys
Definition: HybridJunctionTree.cpp:44
gtsam::treeTraversal::DepthFirstForest
void DepthFirstForest(FOREST &forest, DATA &rootData, VISITOR_PRE &visitorPre, VISITOR_POST &visitorPost)
Definition: treeTraversal-inst.h:77
gtsam::HybridGaussianFactorGraph
Definition: HybridGaussianFactorGraph.h:106
gtsam::HybridEliminationTree
Definition: HybridEliminationTree.h:31
tree::f
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
Definition: testExpression.cpp:218
gtsam::FactorGraph::size
size_t size() const
Definition: FactorGraph.h:297
HybridEliminationTree.h
gtsam::HybridConstructorTraversalData::ConstructorTraversalVisitorPost
static void ConstructorTraversalVisitorPost(const std::shared_ptr< HybridEliminationTree::Node > &node, const HybridConstructorTraversalData &data)
Definition: HybridJunctionTree.cpp:81
HybridGaussianFactorGraph.h
Linearized Hybrid factor graph that uses type erasure.
gtsam
traits
Definition: SFMdata.h:40
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
gtsam::JunctionTree
Definition: JunctionTree.h:50
gtsam::EliminatableClusterTree< HybridBayesTree, HybridGaussianFactorGraph >::remainingFactors_
FastVector< sharedFactor > remainingFactors_
Definition: ClusterTree.h:202
gtsam::HybridConstructorTraversalData::parentData
HybridConstructorTraversalData *const parentData
Definition: HybridJunctionTree.cpp:40
gtsam::FactorGraph::reserve
void reserve(size_t size)
Definition: FactorGraph.h:143
JunctionTree-inst.h
The junction tree, template bodies.
Node
static sharedNode Node(Key key, const SymbolicFactorGraph &factors, const ChildNodes::Result &children)
Definition: testSymbolicEliminationTree.cpp:86
gtsam::Ordering
Definition: inference/Ordering.h:33
i
int i
Definition: BiCGSTAB_step_by_step.cpp:9
gttic
#define gttic(label)
Definition: timing.h:295
gtsam::HybridJunctionTree::HybridJunctionTree
HybridJunctionTree(const HybridEliminationTree &eliminationTree)
Definition: HybridJunctionTree.cpp:149
gtsam::EliminationTree::remainingFactors
const FastVector< sharedFactor > & remainingFactors() const
Definition: EliminationTree.h:155


gtsam
Author(s):
autogenerated on Wed Jan 1 2025 04:01:39