Use functor structs instead of pointer-to-template-function
parent
2925995d25
commit
b572ad8131
|
|
@ -312,15 +312,18 @@ namespace gtsam {
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
/** Traversal function for PrintForest */
|
/** Traversal function for PrintForest */
|
||||||
namespace {
|
namespace {
|
||||||
template<typename NODE>
|
struct PrintForestVisitorPre
|
||||||
std::string
|
|
||||||
PrintForestVisitorPre(const boost::shared_ptr<NODE>& node, const std::string& parentString, const KeyFormatter& formatter)
|
|
||||||
{
|
{
|
||||||
// Print the current node
|
const KeyFormatter& formatter;
|
||||||
node->print(parentString + "-", formatter);
|
PrintForestVisitorPre(const KeyFormatter& formatter) : formatter(formatter) {}
|
||||||
// Increment the indentation
|
template<typename NODE> std::string operator()(const boost::shared_ptr<NODE>& node, const std::string& parentString)
|
||||||
return 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.
|
/** Print a tree, prefixing each line with \c str, and formatting keys using \c keyFormatter.
|
||||||
|
|
@ -328,7 +331,8 @@ namespace gtsam {
|
||||||
template<class FOREST>
|
template<class FOREST>
|
||||||
void PrintForest(const FOREST& forest, std::string str, const KeyFormatter& keyFormatter) {
|
void PrintForest(const FOREST& forest, std::string str, const KeyFormatter& keyFormatter) {
|
||||||
typedef typename FOREST::Node Node;
|
typedef typename FOREST::Node Node;
|
||||||
DepthFirstForest(forest, str, boost::bind(PrintForestVisitorPre<Node>, _1, _2, keyFormatter));
|
PrintForestVisitorPre visitor(keyFormatter);
|
||||||
|
DepthFirstForest(forest, str, visitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -161,47 +161,49 @@ namespace gtsam {
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
// Elimination post-order visitor - combine the child factors with our own factors, add the
|
// 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
|
// resulting conditional to the BayesTree, and add the remaining factor to the parent.
|
||||||
// extra argument 'eliminationFunction' is passed from JunctionTree::eliminate using
|
|
||||||
// boost::bind.
|
|
||||||
template<class JUNCTIONTREE>
|
template<class JUNCTIONTREE>
|
||||||
void eliminationPostOrderVisitor(const typename JUNCTIONTREE::sharedNode& node, EliminationData<JUNCTIONTREE>& myData,
|
struct EliminationPostOrderVisitor
|
||||||
const typename JUNCTIONTREE::Eliminate& eliminationFunction)
|
|
||||||
{
|
{
|
||||||
// Typedefs
|
const typename JUNCTIONTREE::Eliminate& eliminationFunction;
|
||||||
typedef typename JUNCTIONTREE::sharedFactor sharedFactor;
|
EliminationPostOrderVisitor(const typename JUNCTIONTREE::Eliminate& eliminationFunction) : eliminationFunction(eliminationFunction) {}
|
||||||
typedef typename JUNCTIONTREE::FactorType FactorType;
|
void operator()(const typename JUNCTIONTREE::sharedNode& node, EliminationData<JUNCTIONTREE>& myData)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
if(const BayesTreeOrphanWrapper<BTNode>* asSubtree = dynamic_cast<const BayesTreeOrphanWrapper<BTNode>*>(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);
|
if(const BayesTreeOrphanWrapper<BTNode>* asSubtree = dynamic_cast<const BayesTreeOrphanWrapper<BTNode>*>(f.get()))
|
||||||
asSubtree->clique->parent_ = myData.bayesTreeNode;
|
{
|
||||||
|
myData.bayesTreeNode->children.push_back(asSubtree->clique);
|
||||||
|
asSubtree->clique->parent_ = myData.bayesTreeNode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do dense elimination step
|
||||||
|
std::pair<boost::shared_ptr<ConditionalType>, boost::shared_ptr<FactorType> > 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<ConditionalType>, boost::shared_ptr<FactorType> > 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
|
// that contains all of the roots as its children. rootsContainer also stores the remaining
|
||||||
// uneliminated factors passed up from the roots.
|
// uneliminated factors passed up from the roots.
|
||||||
EliminationData<This> rootsContainer(0, roots_.size());
|
EliminationData<This> rootsContainer(0, roots_.size());
|
||||||
|
EliminationPostOrderVisitor<This> visitorPost(function);
|
||||||
//tbb::task_scheduler_init init(1);
|
//tbb::task_scheduler_init init(1);
|
||||||
treeTraversal::DepthFirstForest/*Parallel*/(*this, rootsContainer, eliminationPreOrderVisitor<This>,
|
treeTraversal::DepthFirstForest/*Parallel*/(*this, rootsContainer,
|
||||||
boost::bind(eliminationPostOrderVisitor<This>, _1, _2, function)/*, 10*/);
|
eliminationPreOrderVisitor<This>, visitorPost/*, 10*/);
|
||||||
|
|
||||||
// Create BayesTree from roots stored in the dummy BayesTree node.
|
// Create BayesTree from roots stored in the dummy BayesTree node.
|
||||||
boost::shared_ptr<BayesTreeType> result = boost::make_shared<BayesTreeType>();
|
boost::shared_ptr<BayesTreeType> result = boost::make_shared<BayesTreeType>();
|
||||||
|
|
|
||||||
|
|
@ -50,14 +50,20 @@ namespace gtsam {
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
template<class TREE, class RESULT>
|
template<class TREE, class RESULT>
|
||||||
void eliminationPostOrderVisitor(const typename TREE::sharedNode& node, EliminationData<TREE>& myData,
|
struct EliminationPostOrderVisitor
|
||||||
RESULT& result, const typename TREE::Eliminate& eliminationFunction)
|
|
||||||
{
|
{
|
||||||
// Call eliminate on the node and add the result to the parent's gathered factors
|
RESULT& result;
|
||||||
typename TREE::sharedFactor childFactor = node->eliminate(result, eliminationFunction, myData.childFactors);
|
const typename TREE::Eliminate& eliminationFunction;
|
||||||
if(!childFactor->empty())
|
EliminationPostOrderVisitor(RESULT& result, const typename TREE::Eliminate& eliminationFunction) :
|
||||||
myData.parentData->childFactors.push_back(childFactor);
|
result(result), eliminationFunction(eliminationFunction) {}
|
||||||
}
|
void operator()(const typename TREE::sharedNode& node, EliminationData<TREE>& 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
|
// elimination (using the gathered child factors) and store the result in the parent's
|
||||||
// gathered factors.
|
// gathered factors.
|
||||||
EliminationData<TREE> rootData(0, tree.roots().size());
|
EliminationData<TREE> rootData(0, tree.roots().size());
|
||||||
treeTraversal::DepthFirstForest(tree, rootData, eliminationPreOrderVisitor<TREE>,
|
EliminationPostOrderVisitor<TREE,RESULT> visitorPost(result, function);
|
||||||
boost::bind(eliminationPostOrderVisitor<TREE,RESULT>, _1, _2, result, function));
|
treeTraversal::DepthFirstForest(tree, rootData, eliminationPreOrderVisitor<TREE>, visitorPost);
|
||||||
|
|
||||||
// Return remaining factors
|
// Return remaining factors
|
||||||
return rootData.childFactors;
|
return rootData.childFactors;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue