/* * JunctionTree-inl.h * Created on: Feb 4, 2010 * @Author: Kai Ni * @Author: Frank Dellaert * @brief: The junction tree, template bodies */ #pragma once #include #include "SymbolicFactorGraph.h" #include "BayesTree-inl.h" #include "JunctionTree.h" namespace gtsam { using namespace std; /* ************************************************************************* */ template JunctionTree::JunctionTree(FG& fg, const Ordering& ordering) { // Symbolic factorization: GaussianFactorGraph -> SymbolicFactorGraph // -> SymbolicBayesNet -> SymbolicBayesTree SymbolicFactorGraph sfg(fg); SymbolicBayesNet sbn = sfg.eliminate(ordering); BayesTree sbt(sbn); // distribtue factors this->root_ = distributeFactors(fg, sbt.root()); } /* ************************************************************************* */ template typename JunctionTree::sharedClique JunctionTree::distributeFactors( FG& fg, const BayesTree::sharedClique bayesClique) { // create a new clique in the junction tree sharedClique clique(new Clique()); clique->frontal_ = bayesClique->ordering(); clique->separator_.insert(bayesClique->separator_.begin(), bayesClique->separator_.end()); // recursively call the children BOOST_FOREACH(const BayesTree::sharedClique bayesChild, bayesClique->children()) { sharedClique child = distributeFactors(fg, bayesChild); clique->children_.push_back(child); child->parent_ = clique; } // collect the factors typedef vector Factors; BOOST_FOREACH(const Symbol& frontal, clique->frontal_) { Factors factors = fg.template findAndRemoveFactors(frontal); BOOST_FOREACH(const typename FG::sharedFactor& factor_, factors) clique->push_back(factor_); } return clique; } /* ************************************************************************* */ template template pair > JunctionTree::eliminateOneClique(sharedClique current) { // current->frontal_.print("current clique:"); typedef typename BayesTree::sharedClique sharedBtreeClique; FG fg; // factor graph will be assembled from local factors and marginalized children list > children; fg.push_back(*current); // add the local factor graph // BOOST_FOREACH(const typename FG::sharedFactor& factor_, fg) // Ordering(factor_->keys()).print("local factor:"); BOOST_FOREACH(sharedClique& child, current->children_) { // receive the factors from the child and its clique point FG fgChild; BayesTree childTree; boost::tie(fgChild, childTree) = eliminateOneClique(child); // BOOST_FOREACH(const typename FG::sharedFactor& factor_, fgChild) // Ordering(factor_->keys()).print("factor from child:"); fg.push_back(fgChild); children.push_back(childTree); } // eliminate the combined factors // warning: fg is being eliminated in-place and will contain marginal afterwards BayesNet bn = fg.eliminateFrontals(current->frontal_); // create a new clique corresponding the combined factors BayesTree bayesTree(bn, children); return make_pair(fg, bayesTree); } /* ************************************************************************* */ template template BayesTree JunctionTree::eliminate() { pair > ret = this->eliminateOneClique(this->root()); if (ret.first.nrFactors() != 0) throw runtime_error("JuntionTree::eliminate: elimination failed because of factors left over!"); return ret.second; } } //namespace gtsam