From 06db4ac770a79a3fa90904e59dbfc396a3a8e633 Mon Sep 17 00:00:00 2001 From: Richard Roberts Date: Mon, 7 Feb 2011 16:39:37 +0000 Subject: [PATCH] Optimized version of symbolic elimination --- gtsam/inference/EliminationTree-inl.h | 62 ++++++++++++++++++++++++++- gtsam/inference/EliminationTree.h | 7 +++ 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/gtsam/inference/EliminationTree-inl.h b/gtsam/inference/EliminationTree-inl.h index db2d61d86..9f12a69f4 100644 --- a/gtsam/inference/EliminationTree-inl.h +++ b/gtsam/inference/EliminationTree-inl.h @@ -11,9 +11,12 @@ #include #include #include +#include +#include #include #include +#include #include #include #include @@ -31,8 +34,6 @@ EliminationTree::eliminate_(Conditionals& conditionals) const { if(debug) cout << "ETree: eliminating " << this->key_ << endl; - FastSet separator; - // Create the list of factors to be eliminated, initially empty, and reserve space FactorGraph factors; factors.reserve(this->factors_.size() + this->subTrees_.size()); @@ -56,6 +57,39 @@ EliminationTree::eliminate_(Conditionals& conditionals) const { return eliminated.second; } +/* ************************************************************************* */ +// This is the explicit specialization for symbolic factors, i.e. IndexFactor +template<> inline FastSet EliminationTree::eliminateSymbolic_(Conditionals& conditionals) const { + + static const bool debug = false; + + if(debug) cout << "ETree: eliminating " << this->key_ << endl; + + FastSet variables; + BOOST_FOREACH(const sharedFactor& factor, factors_) { + variables.insert(factor->begin(), factor->end()); + } + BOOST_FOREACH(const shared_ptr& child, subTrees_) { + sharedFactor factor(child->eliminate_(conditionals)); + variables.insert(factor->begin(), factor->end()); + } + conditionals[this->key_] = IndexConditional::FromRange(variables.begin(), variables.end(), 1); + variables.erase(variables.begin()); + + if(debug) cout << "Eliminated " << this->key_ << " to get:\n"; + if(debug) conditionals[this->key_]->print("Conditional: "); + + return variables; +} + +/* ************************************************************************* */ +// This non-specialized version cannot be called. +template FastSet +EliminationTree::eliminateSymbolic_(Conditionals& conditionals) const { + throw invalid_argument("symbolic eliminate should never be called from a non-IndexFactor EliminationTree"); + return FastSet(); +} + /* ************************************************************************* */ template vector EliminationTree::ComputeParents(const VariableIndex& structure) { @@ -204,4 +238,28 @@ EliminationTree::eliminate() const { return bayesNet; } +/* ************************************************************************* */ +// Specialization for symbolic elimination that calls the optimized eliminateSymbolic_ +template<> +inline typename EliminationTree::BayesNet::shared_ptr +EliminationTree::eliminate() const { + + // call recursive routine + tic(1, "ET recursive eliminate"); + Conditionals conditionals(this->key_ + 1); + (void)eliminateSymbolic_(conditionals); + toc(1, "ET recursive eliminate"); + + // Add conditionals to BayesNet + tic(2, "assemble BayesNet"); + typename BayesNet::shared_ptr bayesNet(new BayesNet); + BOOST_FOREACH(const typename BayesNet::sharedConditional& conditional, conditionals) { + if(conditional) + bayesNet->push_back(conditional); + } + toc(2, "assemble BayesNet"); + + return bayesNet; +} + } diff --git a/gtsam/inference/EliminationTree.h b/gtsam/inference/EliminationTree.h index fdc071447..d2aa7df90 100644 --- a/gtsam/inference/EliminationTree.h +++ b/gtsam/inference/EliminationTree.h @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -62,6 +63,12 @@ private: */ sharedFactor eliminate_(Conditionals& conditionals) const; + /** + * Special optimized eliminate for symbolic factors. Will not compile if + * called in a non-IndexFactor EliminationTree. + */ + FastSet eliminateSymbolic_(Conditionals& conditionals) const; + // Allow access to constructor and add methods for testing purposes friend class ::EliminationTreeTester;