gtsam  3.2.1
gtsam
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
treeTraversal-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 
17 #pragma once
18 
19 #include <gtsam/base/treeTraversal/parallelTraversalTasks.h>
20 #include <gtsam/base/treeTraversal/statistics.h>
21 
22 #include <gtsam/base/FastList.h>
23 #include <gtsam/base/FastVector.h>
24 #include <gtsam/inference/Key.h>
25 
26 #include <stack>
27 #include <vector>
28 #include <string>
29 #include <boost/shared_ptr.hpp>
30 #include <boost/make_shared.hpp>
31 #include <boost/foreach.hpp>
32 #include <boost/bind.hpp>
33 
34 namespace gtsam {
35 
37  namespace treeTraversal {
38 
39  /* ************************************************************************* */
40  namespace {
41  // Internal node used in DFS preorder stack
42  template<typename NODE, typename DATA>
43  struct TraversalNode {
44  bool expanded;
45  const boost::shared_ptr<NODE>& treeNode;
46  DATA& parentData;
47  typename FastList<DATA>::iterator dataPointer;
48  TraversalNode(const boost::shared_ptr<NODE>& _treeNode, DATA& _parentData) :
49  expanded(false), treeNode(_treeNode), parentData(_parentData) {}
50  };
51 
52  // Do nothing - default argument for post-visitor for tree traversal
53  struct no_op {
54  template<typename NODE, typename DATA>
55  void operator()(const boost::shared_ptr<NODE>& node, const DATA& data) {}
56  };
57 
58  }
59 
74  template<class FOREST, typename DATA, typename VISITOR_PRE, typename VISITOR_POST>
75  void DepthFirstForest(FOREST& forest, DATA& rootData, VISITOR_PRE& visitorPre, VISITOR_POST& visitorPost)
76  {
77  // Typedefs
78  typedef typename FOREST::Node Node;
79  typedef boost::shared_ptr<Node> sharedNode;
80 
81  // Depth first traversal stack
82  typedef TraversalNode<typename FOREST::Node, DATA> TraversalNode;
83  typedef FastList<TraversalNode> Stack;
84  Stack stack;
85  FastList<DATA> dataList; // List to store node data as it is returned from the pre-order visitor
86 
87  // Add roots to stack (insert such that they are visited and processed in order
88  {
89  typename Stack::iterator insertLocation = stack.begin();
90  BOOST_FOREACH(const sharedNode& root, forest.roots())
91  stack.insert(insertLocation, TraversalNode(root, rootData));
92  }
93 
94  // Traverse
95  while(!stack.empty())
96  {
97  // Get next node
98  TraversalNode& node = stack.front();
99 
100  if(node.expanded) {
101  // If already expanded, then the data stored in the node is no longer needed, so visit
102  // then delete it.
103  (void) visitorPost(node.treeNode, *node.dataPointer);
104  dataList.erase(node.dataPointer);
105  stack.pop_front();
106  } else {
107  // If not already visited, visit the node and add its children (use reverse iterators so
108  // children are processed in the order they appear)
109  node.dataPointer = dataList.insert(dataList.end(), visitorPre(node.treeNode, node.parentData));
110  typename Stack::iterator insertLocation = stack.begin();
111  BOOST_FOREACH(const sharedNode& child, node.treeNode->children)
112  stack.insert(insertLocation, TraversalNode(child, *node.dataPointer));
113  node.expanded = true;
114  }
115  }
116  assert(dataList.empty());
117  }
118 
130  template<class FOREST, typename DATA, typename VISITOR_PRE>
131  void DepthFirstForest(FOREST& forest, DATA& rootData, VISITOR_PRE& visitorPre)
132  {
133  no_op visitorPost;
134  DepthFirstForest(forest, rootData, visitorPre, visitorPost);
135  }
136 
151  template<class FOREST, typename DATA, typename VISITOR_PRE, typename VISITOR_POST>
152  void DepthFirstForestParallel(FOREST& forest, DATA& rootData, VISITOR_PRE& visitorPre, VISITOR_POST& visitorPost,
153  int problemSizeThreshold = 10)
154  {
155 #ifdef GTSAM_USE_TBB
156  // Typedefs
157  typedef typename FOREST::Node Node;
158  typedef boost::shared_ptr<Node> sharedNode;
159 
160  tbb::task::spawn_root_and_wait(internal::CreateRootTask<Node>(
161  forest.roots(), rootData, visitorPre, visitorPost, problemSizeThreshold));
162 #else
163  DepthFirstForest(forest, rootData, visitorPre, visitorPost);
164 #endif
165  }
166 
167 
168  /* ************************************************************************* */
170  namespace {
171  template<typename NODE>
172  boost::shared_ptr<NODE>
173  CloneForestVisitorPre(const boost::shared_ptr<NODE>& node, const boost::shared_ptr<NODE>& parentPointer)
174  {
175  // Clone the current node and add it to its cloned parent
176  boost::shared_ptr<NODE> clone = boost::make_shared<NODE>(*node);
177  clone->children.clear();
178  parentPointer->children.push_back(clone);
179  return clone;
180  }
181  }
182 
188  template<class FOREST>
190  {
191  typedef typename FOREST::Node Node;
192  boost::shared_ptr<Node> rootContainer = boost::make_shared<Node>();
193  DepthFirstForest(forest, rootContainer, CloneForestVisitorPre<Node>);
194  return FastVector<boost::shared_ptr<Node> >(rootContainer->children.begin(), rootContainer->children.end());
195  }
196 
197 
198  /* ************************************************************************* */
200  namespace {
201  struct PrintForestVisitorPre
202  {
203  const KeyFormatter& formatter;
204  PrintForestVisitorPre(const KeyFormatter& formatter) : formatter(formatter) {}
205  template<typename NODE> std::string operator()(const boost::shared_ptr<NODE>& node, const std::string& parentString)
206  {
207  // Print the current node
208  node->print(parentString + "-", formatter);
209  // Increment the indentation
210  return parentString + "| ";
211  }
212  };
213  }
214 
217  template<class FOREST>
218  void PrintForest(const FOREST& forest, std::string str, const KeyFormatter& keyFormatter) {
219  PrintForestVisitorPre visitor(keyFormatter);
220  DepthFirstForest(forest, str, visitor);
221  }
222  }
223 
224 }
Matrix stack(size_t nrMatrices,...)
create a matrix by stacking other matrices Given a set of matrices: A1, A2, A3... ...
Definition: Matrix.cpp:458
A thin wrapper around std::list that uses boost's fast_pool_allocator.
FastVector< boost::shared_ptr< typename FOREST::Node > > CloneForest(const FOREST &forest)
Clone a tree, copy-constructing new nodes (calling boost::make_shared) and setting up child pointers ...
Definition: treeTraversal-inst.h:189
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
void DepthFirstForestParallel(FOREST &forest, DATA &rootData, VISITOR_PRE &visitorPre, VISITOR_POST &visitorPost, int problemSizeThreshold=10)
Traverse a forest depth-first with pre-order and post-order visits.
Definition: treeTraversal-inst.h:152
Definition: FastList.h:38
void PrintForest(const FOREST &forest, std::string str, const KeyFormatter &keyFormatter)
Print a tree, prefixing each line with str, and formatting keys using keyFormatter.
Definition: treeTraversal-inst.h:218
Definition: FastVector.h:38
A thin wrapper around std::vector that uses boost's pool_allocator.
boost::function< std::string(Key)> KeyFormatter
Typedef for a function to format a key, i.e. to convert it to a string.
Definition: types.h:62