/* * JunctionTree-inl.h * Created on: Feb 4, 2010 * @Author: Kai Ni * @Author: Frank Dellaert * @brief: The junction tree, template bodies */ #pragma once #include #include #include #include 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::sharedClique> JunctionTree::eliminateOneClique(sharedClique current) { 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(sharedClique& child, current->children_) { // receive the factors from the child and its clique point FG fgChild; sharedBtreeClique childRoot; boost::tie(fgChild, childRoot) = eliminateOneClique(child); fg.push_back(fgChild); children.push_back(childRoot); } // 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); sharedBtreeClique new_clique(new typename BayesTree::Clique(bn)); new_clique->children_ = children; BOOST_FOREACH(sharedBtreeClique& childRoot, children) childRoot->parent_ = new_clique; return make_pair(fg, new_clique); } /* ************************************************************************* */ template template typename BayesTree::sharedClique JunctionTree::eliminate() { pair::sharedClique> 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