gtsam  3.2.1
gtsam
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
JunctionTree-inst.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 
21 #pragma once
22 
25 #include <gtsam/symbolic/SymbolicConditional.h>
26 #include <gtsam/symbolic/SymbolicFactor-inst.h>
27 
28 namespace gtsam {
29 
30  namespace {
31  /* ************************************************************************* */
32  template<class BAYESTREE, class GRAPH>
33  struct ConstructorTraversalData {
34  ConstructorTraversalData* const parentData;
35  typename JunctionTree<BAYESTREE,GRAPH>::sharedNode myJTNode;
36  FastVector<SymbolicConditional::shared_ptr> childSymbolicConditionals;
37  FastVector<SymbolicFactor::shared_ptr> childSymbolicFactors;
38  ConstructorTraversalData(ConstructorTraversalData* _parentData) : parentData(_parentData) {}
39  };
40 
41  /* ************************************************************************* */
42  // Pre-order visitor function
43  template<class BAYESTREE, class GRAPH, class ETREE_NODE>
44  ConstructorTraversalData<BAYESTREE,GRAPH> ConstructorTraversalVisitorPre(
45  const boost::shared_ptr<ETREE_NODE>& node,
46  ConstructorTraversalData<BAYESTREE,GRAPH>& parentData)
47  {
48  // On the pre-order pass, before children have been visited, we just set up a traversal data
49  // structure with its own JT node, and create a child pointer in its parent.
50  ConstructorTraversalData<BAYESTREE,GRAPH> myData = ConstructorTraversalData<BAYESTREE,GRAPH>(&parentData);
51  myData.myJTNode = boost::make_shared<typename JunctionTree<BAYESTREE,GRAPH>::Node>();
52  myData.myJTNode->keys.push_back(node->key);
53  myData.myJTNode->factors.insert(myData.myJTNode->factors.begin(), node->factors.begin(), node->factors.end());
54  parentData.myJTNode->children.push_back(myData.myJTNode);
55  return myData;
56  }
57 
58  /* ************************************************************************* */
59  // Post-order visitor function
60  template<class BAYESTREE, class GRAPH, class ETREE_NODE>
61  void ConstructorTraversalVisitorPostAlg2(
62  const boost::shared_ptr<ETREE_NODE>& ETreeNode,
63  const ConstructorTraversalData<BAYESTREE, GRAPH>& myData)
64  {
65  // In this post-order visitor, we combine the symbolic elimination results from the
66  // elimination tree children and symbolically eliminate the current elimination tree node. We
67  // then check whether each of our elimination tree child nodes should be merged with us. The
68  // check for this is that our number of symbolic elimination parents is exactly 1 less than
69  // our child's symbolic elimination parents - this condition indicates that eliminating the
70  // current node did not introduce any parents beyond those already in the child.
71 
72  // Do symbolic elimination for this node
73  class : public FactorGraph<Factor> {} symbolicFactors;
74  symbolicFactors.reserve(ETreeNode->factors.size() + myData.childSymbolicFactors.size());
75  // Add ETree node factors
76  symbolicFactors += ETreeNode->factors;
77  // Add symbolic factors passed up from children
78  symbolicFactors += myData.childSymbolicFactors;
79 
80  Ordering keyAsOrdering; keyAsOrdering.push_back(ETreeNode->key);
81  std::pair<SymbolicConditional::shared_ptr, SymbolicFactor::shared_ptr> symbolicElimResult =
82  internal::EliminateSymbolic(symbolicFactors, keyAsOrdering);
83 
84  // Store symbolic elimination results in the parent
85  myData.parentData->childSymbolicConditionals.push_back(symbolicElimResult.first);
86  myData.parentData->childSymbolicFactors.push_back(symbolicElimResult.second);
87 
88  // Merge our children if they are in our clique - if our conditional has exactly one fewer
89  // parent than our child's conditional.
90  size_t myNrFrontals = 1;
91  const size_t myNrParents = symbolicElimResult.first->nrParents();
92  size_t nrMergedChildren = 0;
93  assert(myData.myJTNode->children.size() == myData.childSymbolicConditionals.size());
94  // Loop over children
95  int combinedProblemSize = (int) (symbolicElimResult.first->size() * symbolicFactors.size());
96  for(size_t child = 0; child < myData.childSymbolicConditionals.size(); ++child) {
97  // Check if we should merge the child
98  if(myNrParents + myNrFrontals == myData.childSymbolicConditionals[child]->nrParents()) {
99  // Get a reference to the child, adjusting the index to account for children previously
100  // merged and removed from the child list.
101  const typename JunctionTree<BAYESTREE, GRAPH>::Node& childToMerge =
102  *myData.myJTNode->children[child - nrMergedChildren];
103  // Merge keys, factors, and children.
104  myData.myJTNode->keys.insert(myData.myJTNode->keys.begin(), childToMerge.keys.begin(), childToMerge.keys.end());
105  myData.myJTNode->factors.insert(myData.myJTNode->factors.end(), childToMerge.factors.begin(), childToMerge.factors.end());
106  myData.myJTNode->children.insert(myData.myJTNode->children.end(), childToMerge.children.begin(), childToMerge.children.end());
107  // Increment problem size
108  combinedProblemSize = std::max(combinedProblemSize, childToMerge.problemSize_);
109  // Increment number of frontal variables
110  myNrFrontals += childToMerge.keys.size();
111  // Remove child from list.
112  myData.myJTNode->children.erase(myData.myJTNode->children.begin() + (child - nrMergedChildren));
113  // Increment number of merged children
114  ++ nrMergedChildren;
115  }
116  }
117  myData.myJTNode->problemSize_ = combinedProblemSize;
118  }
119  }
120 
121  /* ************************************************************************* */
122  template<class BAYESTREE, class GRAPH>
123  template<class ETREE_BAYESNET, class ETREE_GRAPH>
125  {
126  gttic(JunctionTree_FromEliminationTree);
127  // Here we rely on the BayesNet having been produced by this elimination tree, such that the
128  // conditionals are arranged in DFS post-order. We traverse the elimination tree, and inspect
129  // the symbolic conditional corresponding to each node. The elimination tree node is added to
130  // the same clique with its parent if it has exactly one more Bayes net conditional parent than
131  // does its elimination tree parent.
132 
133  // Traverse the elimination tree, doing symbolic elimination and merging nodes as we go. Gather
134  // the created junction tree roots in a dummy Node.
135  typedef typename EliminationTree<ETREE_BAYESNET, ETREE_GRAPH>::Node ETreeNode;
136  ConstructorTraversalData<BAYESTREE, GRAPH> rootData(0);
137  rootData.myJTNode = boost::make_shared<typename Base::Node>(); // Make a dummy node to gather the junction tree roots
138  treeTraversal::DepthFirstForest(eliminationTree, rootData,
139  ConstructorTraversalVisitorPre<BAYESTREE,GRAPH,ETreeNode>, ConstructorTraversalVisitorPostAlg2<BAYESTREE,GRAPH,ETreeNode>);
140 
141  // Assign roots from the dummy node
142  Base::roots_ = rootData.myJTNode->children;
143 
144  // Transfer remaining factors from elimination tree
145  Base::remainingFactors_ = eliminationTree.remainingFactors();
146  }
147 
148 } //namespace gtsam
The junction tree.
Definition: JunctionTree.h:52
Collects factorgraph fragments defined on variable clusters, arranged in a tree.
Definition: EliminationTree.h:66
void DepthFirstForest(FOREST &forest, DATA &rootData, VISITOR_PRE &visitorPre, VISITOR_POST &visitorPost)
Traverse a forest depth-first with pre-order and post-order visits.
Definition: treeTraversal-inst.h:75
double max(const Vector &a)
Return the max element of a vector.
Definition: Vector.cpp:238
const FastVector< sharedFactor > & remainingFactors() const
Return the remaining factors that are not pulled into elimination.
Definition: EliminationTree.h:154
An elimination tree is a data structure used intermediately during elimination.
Definition: EliminationTree.h:51