From b572ad8131289a3a8f82019cf47620f694cd7e1a Mon Sep 17 00:00:00 2001 From: Richard Roberts Date: Thu, 8 Aug 2013 16:30:10 +0000 Subject: [PATCH] Use functor structs instead of pointer-to-template-function --- gtsam/base/treeTraversal-inst.h | 22 +++++---- gtsam/inference/JunctionTree-inst.h | 77 +++++++++++++++-------------- gtsam/inference/inference-inst.h | 26 ++++++---- 3 files changed, 69 insertions(+), 56 deletions(-) diff --git a/gtsam/base/treeTraversal-inst.h b/gtsam/base/treeTraversal-inst.h index b4aaca072..a90121738 100644 --- a/gtsam/base/treeTraversal-inst.h +++ b/gtsam/base/treeTraversal-inst.h @@ -312,15 +312,18 @@ namespace gtsam { /* ************************************************************************* */ /** Traversal function for PrintForest */ namespace { - template - std::string - PrintForestVisitorPre(const boost::shared_ptr& node, const std::string& parentString, const KeyFormatter& formatter) + struct PrintForestVisitorPre { - // Print the current node - node->print(parentString + "-", formatter); - // Increment the indentation - return parentString + "| "; - } + const KeyFormatter& formatter; + PrintForestVisitorPre(const KeyFormatter& formatter) : formatter(formatter) {} + template std::string operator()(const boost::shared_ptr& node, const std::string& parentString) + { + // Print the current node + node->print(parentString + "-", formatter); + // Increment the indentation + return parentString + "| "; + } + }; } /** Print a tree, prefixing each line with \c str, and formatting keys using \c keyFormatter. @@ -328,7 +331,8 @@ namespace gtsam { template void PrintForest(const FOREST& forest, std::string str, const KeyFormatter& keyFormatter) { typedef typename FOREST::Node Node; - DepthFirstForest(forest, str, boost::bind(PrintForestVisitorPre, _1, _2, keyFormatter)); + PrintForestVisitorPre visitor(keyFormatter); + DepthFirstForest(forest, str, visitor); } } diff --git a/gtsam/inference/JunctionTree-inst.h b/gtsam/inference/JunctionTree-inst.h index e4e3e6630..7a2895c99 100644 --- a/gtsam/inference/JunctionTree-inst.h +++ b/gtsam/inference/JunctionTree-inst.h @@ -161,47 +161,49 @@ namespace gtsam { /* ************************************************************************* */ // Elimination post-order visitor - combine the child factors with our own factors, add the - // resulting conditional to the BayesTree, and add the remaining factor to the parent. The - // extra argument 'eliminationFunction' is passed from JunctionTree::eliminate using - // boost::bind. + // resulting conditional to the BayesTree, and add the remaining factor to the parent. template - void eliminationPostOrderVisitor(const typename JUNCTIONTREE::sharedNode& node, EliminationData& myData, - const typename JUNCTIONTREE::Eliminate& eliminationFunction) + struct EliminationPostOrderVisitor { - // Typedefs - typedef typename JUNCTIONTREE::sharedFactor sharedFactor; - typedef typename JUNCTIONTREE::FactorType FactorType; - typedef typename JUNCTIONTREE::FactorGraphType FactorGraphType; - typedef typename JUNCTIONTREE::ConditionalType ConditionalType; - typedef typename JUNCTIONTREE::BayesTreeType::Node BTNode; - - // Gather factors - FactorGraphType gatheredFactors; - gatheredFactors.reserve(node->factors.size() + node->children.size()); - gatheredFactors += node->factors; - gatheredFactors += myData.childFactors; - - // Check for Bayes tree orphan subtrees, and add them to our children - BOOST_FOREACH(const sharedFactor& f, node->factors) + const typename JUNCTIONTREE::Eliminate& eliminationFunction; + EliminationPostOrderVisitor(const typename JUNCTIONTREE::Eliminate& eliminationFunction) : eliminationFunction(eliminationFunction) {} + void operator()(const typename JUNCTIONTREE::sharedNode& node, EliminationData& myData) { - if(const BayesTreeOrphanWrapper* asSubtree = dynamic_cast*>(f.get())) + // Typedefs + typedef typename JUNCTIONTREE::sharedFactor sharedFactor; + typedef typename JUNCTIONTREE::FactorType FactorType; + typedef typename JUNCTIONTREE::FactorGraphType FactorGraphType; + typedef typename JUNCTIONTREE::ConditionalType ConditionalType; + typedef typename JUNCTIONTREE::BayesTreeType::Node BTNode; + + // Gather factors + FactorGraphType gatheredFactors; + gatheredFactors.reserve(node->factors.size() + node->children.size()); + gatheredFactors += node->factors; + gatheredFactors += myData.childFactors; + + // Check for Bayes tree orphan subtrees, and add them to our children + BOOST_FOREACH(const sharedFactor& f, node->factors) { - myData.bayesTreeNode->children.push_back(asSubtree->clique); - asSubtree->clique->parent_ = myData.bayesTreeNode; + if(const BayesTreeOrphanWrapper* asSubtree = dynamic_cast*>(f.get())) + { + myData.bayesTreeNode->children.push_back(asSubtree->clique); + asSubtree->clique->parent_ = myData.bayesTreeNode; + } } + + // Do dense elimination step + std::pair, boost::shared_ptr > eliminationResult = + eliminationFunction(gatheredFactors, Ordering(node->keys)); + + // Store conditional in BayesTree clique + myData.bayesTreeNode->conditional_ = eliminationResult.first; + + // Store remaining factor in parent's gathered factors + if(!eliminationResult.second->empty()) + myData.parentData->childFactors[myData.myIndexInParent] = eliminationResult.second; } - - // Do dense elimination step - std::pair, boost::shared_ptr > eliminationResult = - eliminationFunction(gatheredFactors, Ordering(node->keys)); - - // Store conditional in BayesTree clique - myData.bayesTreeNode->conditional_ = eliminationResult.first; - - // Store remaining factor in parent's gathered factors - if(!eliminationResult.second->empty()) - myData.parentData->childFactors[myData.myIndexInParent] = eliminationResult.second; - } + }; } /* ************************************************************************* */ @@ -278,9 +280,10 @@ namespace gtsam { // that contains all of the roots as its children. rootsContainer also stores the remaining // uneliminated factors passed up from the roots. EliminationData rootsContainer(0, roots_.size()); + EliminationPostOrderVisitor visitorPost(function); //tbb::task_scheduler_init init(1); - treeTraversal::DepthFirstForest/*Parallel*/(*this, rootsContainer, eliminationPreOrderVisitor, - boost::bind(eliminationPostOrderVisitor, _1, _2, function)/*, 10*/); + treeTraversal::DepthFirstForest/*Parallel*/(*this, rootsContainer, + eliminationPreOrderVisitor, visitorPost/*, 10*/); // Create BayesTree from roots stored in the dummy BayesTree node. boost::shared_ptr result = boost::make_shared(); diff --git a/gtsam/inference/inference-inst.h b/gtsam/inference/inference-inst.h index eb6ef9de7..1d4e7c0dc 100644 --- a/gtsam/inference/inference-inst.h +++ b/gtsam/inference/inference-inst.h @@ -50,14 +50,20 @@ namespace gtsam { /* ************************************************************************* */ template - void eliminationPostOrderVisitor(const typename TREE::sharedNode& node, EliminationData& myData, - RESULT& result, const typename TREE::Eliminate& eliminationFunction) + struct EliminationPostOrderVisitor { - // Call eliminate on the node and add the result to the parent's gathered factors - typename TREE::sharedFactor childFactor = node->eliminate(result, eliminationFunction, myData.childFactors); - if(!childFactor->empty()) - myData.parentData->childFactors.push_back(childFactor); - } + RESULT& result; + const typename TREE::Eliminate& eliminationFunction; + EliminationPostOrderVisitor(RESULT& result, const typename TREE::Eliminate& eliminationFunction) : + result(result), eliminationFunction(eliminationFunction) {} + void operator()(const typename TREE::sharedNode& node, EliminationData& myData) + { + // Call eliminate on the node and add the result to the parent's gathered factors + typename TREE::sharedFactor childFactor = node->eliminate(result, eliminationFunction, myData.childFactors); + if(!childFactor->empty()) + myData.parentData->childFactors.push_back(childFactor); + } + }; } /* ************************************************************************* */ @@ -79,12 +85,12 @@ namespace gtsam { // elimination (using the gathered child factors) and store the result in the parent's // gathered factors. EliminationData rootData(0, tree.roots().size()); - treeTraversal::DepthFirstForest(tree, rootData, eliminationPreOrderVisitor, - boost::bind(eliminationPostOrderVisitor, _1, _2, result, function)); + EliminationPostOrderVisitor visitorPost(result, function); + treeTraversal::DepthFirstForest(tree, rootData, eliminationPreOrderVisitor, visitorPost); // Return remaining factors return rootData.childFactors; } } -} \ No newline at end of file +}