/** * @file BayesTree * @brief Bayes Tree is a tree of cliques of a Bayes Chain * @author Frank Dellaert */ // \callgraph #pragma once #include #include #include #include #include #include #include "Testable.h" #include "FactorGraph.h" #include "BayesNet.h" #include "Key.h" #include "IndexTable.h" namespace gtsam { /** * Bayes tree * Templated on the Conditional class, the type of node in the underlying Bayes chain. * This could be a ConditionalProbabilityTable, a GaussianConditional, or a SymbolicConditional */ template class BayesTree: public Testable > { public: typedef boost::shared_ptr sharedConditional; typedef boost::shared_ptr > sharedBayesNet; /** A Clique in the tree is an incomplete Bayes net: the variables * in the Bayes net are the frontal nodes, and the variables conditioned * on is the separator. We also have pointers up and down the tree. */ struct Clique: public BayesNet { typedef typename boost::shared_ptr shared_ptr; shared_ptr parent_; std::list children_; std::list separator_; /** separator keys */ //* Constructor */ Clique(const sharedConditional& conditional); /** return keys in frontal:separator order */ Ordering keys() const; /** print this node */ void print(const std::string& s = "") const; /** The size *includes* the separator */ size_t size() const { return this->conditionals_.size() + separator_.size(); } /** is this the root of a Bayes tree ? */ inline bool isRoot() const { return parent_==NULL;} /** The size of subtree rooted at this clique, i.e., nr of Cliques */ size_t treeSize() const; /** print this node and entire subtree below it */ void printTree(const std::string& indent="") const; /** return the conditional P(S|Root) on the separator given the root */ // TODO: create a cached version template BayesNet shortcut(shared_ptr root); /** return the marginal P(C) of the clique */ template FactorGraph marginal(shared_ptr root); /** return the joint P(C1,C2), where C1==this. TODO: not a method? */ template FactorGraph joint(shared_ptr C2, shared_ptr root); }; // typedef for shared pointers to cliques typedef boost::shared_ptr sharedClique; // A convenience class for a list of shared cliques struct Cliques : public std::list, public Testable { void print(const std::string& s = "Cliques") const; bool equals(const Cliques& other, double tol = 1e-9) const; }; private: /** Map from keys to Clique */ typedef std::map Nodes; Nodes nodes_; /** Root clique */ sharedClique root_; /** add a clique */ sharedClique addClique(const sharedConditional& conditional, sharedClique parent_clique = sharedClique()); protected: /** remove a clique: warning, can result in a forest */ void removeClique(sharedClique clique); public: /** Create an empty Bayes Tree */ BayesTree(); /** Create a Bayes Tree from a Bayes Net */ BayesTree(const BayesNet& bayesNet); /** Destructor */ virtual ~BayesTree() { } /** print */ void print(const std::string& s = "") const; /** check equality */ bool equals(const BayesTree& other, double tol = 1e-9) const; /** * Find parent clique of a conditional, given an IndexTable constructed from an ordering. * It will look at all parents and return the one with the lowest index in the ordering. */ Symbol findParentClique(const std::list& parents, const IndexTable& index) const; /** insert a new conditional */ void insert(const sharedConditional& conditional, const IndexTable& index); /** number of cliques */ inline size_t size() const { if(root_) return root_->treeSize(); else return 0; } /** return root clique */ sharedClique root() const { return root_; } /** find the clique to which key belongs */ sharedClique operator[](const Symbol& key) const { typename Nodes::const_iterator it = nodes_.find(key); if (it == nodes_.end()) throw(std::invalid_argument( "BayesTree::operator['" + (std::string)key + "']: key not found")); sharedClique clique = it->second; return clique; } /** return marginal on any variable */ template FactorGraph marginal(const Symbol& key) const; /** return marginal on any variable, as a Bayes Net */ template BayesNet marginalBayesNet(const Symbol& key) const; /** return joint on two variables */ template FactorGraph joint(const Symbol& key1, const Symbol& key2) const; /** return joint on two variables as a BayesNet */ template BayesNet jointBayesNet(const Symbol& key1, const Symbol& key2) const; /** * Remove all nodes */ void clear(); /** * Remove path from clique to root and return that path as factors * plus a list of orphaned subtree roots. Used in removeTop below. */ void removePath(sharedClique clique, BayesNet& bn, Cliques& orphans); /** * Given a list of keys, turn "contaminated" part of the tree back into a factor graph. * Factors and orphans are added to the in/out arguments. */ void removeTop(const std::list& keys, BayesNet& bn, Cliques& orphans); }; // BayesTree } /// namespace gtsam