gtsam 4.1.1
gtsam
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>
24#include <gtsam/inference/Key.h>
25#include <gtsam/config.h> // for GTSAM_USE_TBB
26
27#include <stack>
28#include <vector>
29#include <string>
30#include <boost/shared_ptr.hpp>
31#include <boost/make_shared.hpp>
32
33namespace gtsam {
34
36namespace treeTraversal {
37
38/* ************************************************************************* */
39namespace {
40// Internal node used in DFS preorder stack
41template<typename NODE, typename DATA>
42struct TraversalNode {
43 bool expanded;
44 const boost::shared_ptr<NODE>& treeNode;
45 DATA& parentData;
46 typename FastList<DATA>::iterator dataPointer;
47 TraversalNode(const boost::shared_ptr<NODE>& _treeNode, DATA& _parentData) :
48 expanded(false), treeNode(_treeNode), parentData(_parentData) {
49 }
50};
51
52// Do nothing - default argument for post-visitor for tree traversal
53struct no_op {
54 template<typename NODE, typename DATA>
55 void operator()(const boost::shared_ptr<NODE>& node, const DATA& data) {
56 }
57};
58
59}
60
75template<class FOREST, typename DATA, typename VISITOR_PRE,
76 typename VISITOR_POST>
77void DepthFirstForest(FOREST& forest, DATA& rootData, VISITOR_PRE& visitorPre,
78 VISITOR_POST& visitorPost) {
79 // Typedefs
80 typedef typename FOREST::Node Node;
81 typedef boost::shared_ptr<Node> sharedNode;
82
83 // Depth first traversal stack
84 typedef TraversalNode<typename FOREST::Node, DATA> TraversalNode;
85 typedef FastList<TraversalNode> Stack;
86 Stack stack;
87 FastList<DATA> dataList; // List to store node data as it is returned from the pre-order visitor
88
89 // Add roots to stack (insert such that they are visited and processed in order
90 {
91 typename Stack::iterator insertLocation = stack.begin();
92 for(const sharedNode& root: forest.roots())
93 stack.insert(insertLocation, TraversalNode(root, rootData));
94 }
95
96 // Traverse
97 while (!stack.empty()) {
98 // Get next node
99 TraversalNode& node = stack.front();
100
101 if (node.expanded) {
102 // If already expanded, then the data stored in the node is no longer needed, so visit
103 // then delete it.
104 (void) visitorPost(node.treeNode, *node.dataPointer);
105 dataList.erase(node.dataPointer);
106 stack.pop_front();
107 } else {
108 // If not already visited, visit the node and add its children (use reverse iterators so
109 // children are processed in the order they appear)
110 node.dataPointer = dataList.insert(dataList.end(),
111 visitorPre(node.treeNode, node.parentData));
112 typename Stack::iterator insertLocation = stack.begin();
113 for(const sharedNode& child: node.treeNode->children)
114 stack.insert(insertLocation, TraversalNode(child, *node.dataPointer));
115 node.expanded = true;
116 }
117 }
118 assert(dataList.empty());
119}
120
132template<class FOREST, typename DATA, typename VISITOR_PRE>
133void DepthFirstForest(FOREST& forest, DATA& rootData, VISITOR_PRE& visitorPre) {
134 no_op visitorPost;
135 DepthFirstForest(forest, rootData, visitorPre, visitorPost);
136}
137
152template<class FOREST, typename DATA, typename VISITOR_PRE,
153 typename VISITOR_POST>
154void DepthFirstForestParallel(FOREST& forest, DATA& rootData,
155 VISITOR_PRE& visitorPre, VISITOR_POST& visitorPost,
156 int problemSizeThreshold = 10) {
157#ifdef GTSAM_USE_TBB
158 // Typedefs
159 typedef typename FOREST::Node Node;
160
161 internal::CreateRootTask<Node>(forest.roots(), rootData, visitorPre,
162 visitorPost, problemSizeThreshold);
163#else
164 DepthFirstForest(forest, rootData, visitorPre, visitorPost);
165#endif
166}
167
168/* ************************************************************************* */
170namespace {
171template<typename NODE>
172boost::shared_ptr<NODE> CloneForestVisitorPre(
173 const boost::shared_ptr<NODE>& node,
174 const boost::shared_ptr<NODE>& parentPointer) {
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
188template<class FOREST>
189FastVector<boost::shared_ptr<typename FOREST::Node> > CloneForest(
190 const FOREST& forest) {
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(),
195 rootContainer->children.end());
196}
197
198/* ************************************************************************* */
200namespace {
201struct PrintForestVisitorPre {
202 const KeyFormatter& formatter;
203 PrintForestVisitorPre(const KeyFormatter& formatter) :
204 formatter(formatter) {
205 }
206 template<typename NODE> std::string operator()(
207 const boost::shared_ptr<NODE>& node, const std::string& parentString) {
208 // Print the current node
209 node->print(parentString + "-", formatter);
210 // Increment the indentation
211 return parentString + "| ";
212 }
213};
214}
215
218template<class FOREST>
219void PrintForest(const FOREST& forest, std::string str,
220 const KeyFormatter& keyFormatter) {
221 PrintForestVisitorPre visitor(keyFormatter);
222 DepthFirstForest(forest, str, visitor);
223}
224}
225
226}
A thin wrapper around std::vector that uses a custom allocator.
A thin wrapper around std::list that uses boost's fast_pool_allocator.
Global functions in a separate testing namespace.
Definition: chartTesting.h:28
Matrix stack(size_t nrMatrices,...)
create a matrix by stacking other matrices Given a set of matrices: A1, A2, A3...
Definition: Matrix.cpp:396
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
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:77
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 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:219
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:154
Definition: FastList.h:40