| 
									
										
										
										
											2009-10-28 04:23:19 +08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * @file    BayesTree | 
					
						
							|  |  |  |  * @brief   Bayes Tree is a tree of cliques of a Bayes Chain | 
					
						
							|  |  |  |  * @author  Frank Dellaert | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // \callgraph
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 |  |  | #include <map>
 | 
					
						
							| 
									
										
										
										
											2009-10-28 04:23:19 +08:00
										 |  |  | #include <list>
 | 
					
						
							| 
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 |  |  | #include <vector>
 | 
					
						
							| 
									
										
										
										
											2009-10-28 04:23:19 +08:00
										 |  |  | #include <boost/serialization/map.hpp>
 | 
					
						
							|  |  |  | #include <boost/serialization/list.hpp>
 | 
					
						
							| 
									
										
										
										
											2009-11-02 13:17:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-28 04:23:19 +08:00
										 |  |  | #include "Testable.h"
 | 
					
						
							| 
									
										
										
										
											2009-11-12 12:56:30 +08:00
										 |  |  | #include "FactorGraph.h"
 | 
					
						
							| 
									
										
										
										
											2009-11-01 03:53:20 +08:00
										 |  |  | #include "BayesNet.h"
 | 
					
						
							| 
									
										
										
										
											2009-10-28 04:23:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 |  |  | 	/**
 | 
					
						
							|  |  |  | 	 * Bayes tree | 
					
						
							|  |  |  | 	 * Templated on the Conditional class, the type of node in the underlying Bayes chain. | 
					
						
							| 
									
										
										
										
											2009-11-13 00:41:18 +08:00
										 |  |  | 	 * This could be a ConditionalProbabilityTable, a GaussianConditional, or a SymbolicConditional | 
					
						
							| 
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 |  |  | 	 */ | 
					
						
							|  |  |  | 	template<class Conditional> | 
					
						
							|  |  |  | 	class BayesTree: public Testable<BayesTree<Conditional> > { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-08 01:24:05 +08:00
										 |  |  | 		typedef boost::shared_ptr<Conditional> sharedConditional; | 
					
						
							|  |  |  | 		typedef boost::shared_ptr<BayesNet<Conditional> > sharedBayesNet; | 
					
						
							| 
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-08 01:24:05 +08:00
										 |  |  | 		/** A Clique in the tree is an incomplete Bayes net: the variables
 | 
					
						
							| 
									
										
										
										
											2009-11-02 13:17:44 +08:00
										 |  |  | 		 * 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. | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2009-11-08 01:24:05 +08:00
										 |  |  | 		struct Clique: public BayesNet<Conditional> { | 
					
						
							| 
									
										
										
										
											2009-11-07 23:58:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-08 12:41:01 +08:00
										 |  |  | 			typedef typename boost::shared_ptr<Clique> shared_ptr; | 
					
						
							| 
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 |  |  | 			shared_ptr parent_; | 
					
						
							|  |  |  | 			std::list<shared_ptr> children_; | 
					
						
							| 
									
										
										
										
											2009-11-08 01:24:05 +08:00
										 |  |  | 			std::list<std::string> separator_; /** separator keys */ | 
					
						
							| 
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 13:17:44 +08:00
										 |  |  | 			//* Constructor */
 | 
					
						
							| 
									
										
										
										
											2009-11-08 01:24:05 +08:00
										 |  |  | 			Clique(const sharedConditional& conditional); | 
					
						
							| 
									
										
										
										
											2009-11-02 13:17:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 06:51:12 +08:00
										 |  |  | 			/** return keys in frontal:separator order */ | 
					
						
							|  |  |  | 			Ordering keys() const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-08 12:41:01 +08:00
										 |  |  | 			/** print this node */ | 
					
						
							|  |  |  | 			void print(const std::string& s = "Bayes tree node") const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 13:17:44 +08:00
										 |  |  | 			/** The size *includes* the separator */ | 
					
						
							| 
									
										
										
										
											2009-11-07 23:58:45 +08:00
										 |  |  | 			size_t size() const { | 
					
						
							|  |  |  | 				return this->conditionals_.size() + separator_.size(); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-11-02 13:17:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-08 12:41:01 +08:00
										 |  |  | 			/** is this the root of a Bayes tree ? */ | 
					
						
							|  |  |  | 			inline bool isRoot() const { return parent_==NULL;} | 
					
						
							| 
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-19 02:05:12 +08:00
										 |  |  | 			/** The size of subtree rooted at this clique, i.e., nr of Cliques */ | 
					
						
							|  |  |  | 			size_t treeSize() const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-08 01:24:05 +08:00
										 |  |  | 			/** print this node and entire subtree below it */ | 
					
						
							| 
									
										
										
										
											2009-11-02 13:17:44 +08:00
										 |  |  | 			void printTree(const std::string& indent) const; | 
					
						
							| 
									
										
										
										
											2009-11-08 01:24:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/** return the conditional P(S|Root) on the separator given the root */ | 
					
						
							| 
									
										
										
										
											2009-11-09 15:04:26 +08:00
										 |  |  | 			// TODO: create a cached version
 | 
					
						
							| 
									
										
										
										
											2009-11-08 12:41:01 +08:00
										 |  |  | 			template<class Factor> | 
					
						
							| 
									
										
										
										
											2009-11-09 15:04:26 +08:00
										 |  |  | 			BayesNet<Conditional> shortcut(shared_ptr root); | 
					
						
							| 
									
										
										
										
											2009-11-09 06:51:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/** return the marginal P(C) of the clique */ | 
					
						
							|  |  |  | 			template<class Factor> | 
					
						
							| 
									
										
										
										
											2009-11-12 12:56:30 +08:00
										 |  |  | 			FactorGraph<Factor> marginal(shared_ptr root); | 
					
						
							| 
									
										
										
										
											2009-11-09 08:13:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/** return the joint P(C1,C2), where C1==this. TODO: not a method? */ | 
					
						
							|  |  |  | 			template<class Factor> | 
					
						
							| 
									
										
										
										
											2009-11-12 12:56:30 +08:00
										 |  |  | 			FactorGraph<Factor> joint(shared_ptr C2, shared_ptr root); | 
					
						
							| 
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-08 01:24:05 +08:00
										 |  |  | 		typedef boost::shared_ptr<Clique> sharedClique; | 
					
						
							| 
									
										
										
										
											2009-11-07 23:58:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	private: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-08 01:24:05 +08:00
										 |  |  | 		/** Map from keys to Clique */ | 
					
						
							|  |  |  | 		typedef std::map<std::string, sharedClique> Nodes; | 
					
						
							| 
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 |  |  | 		Nodes nodes_; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 08:13:44 +08:00
										 |  |  | 		/** Root clique */ | 
					
						
							| 
									
										
										
										
											2009-11-08 01:24:05 +08:00
										 |  |  | 		sharedClique root_; | 
					
						
							| 
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 11:22:29 +08:00
										 |  |  | 		/** add a clique */ | 
					
						
							| 
									
										
										
										
											2009-11-08 01:24:05 +08:00
										 |  |  | 		sharedClique addClique(const sharedConditional& conditional, | 
					
						
							|  |  |  | 				sharedClique parent_clique = sharedClique()) { | 
					
						
							|  |  |  | 			sharedClique new_clique(new Clique(conditional)); | 
					
						
							|  |  |  | 			nodes_.insert(make_pair(conditional->key(), new_clique)); | 
					
						
							|  |  |  | 			if (parent_clique != NULL) { | 
					
						
							|  |  |  | 				new_clique->parent_ = parent_clique; | 
					
						
							|  |  |  | 				parent_clique->children_.push_back(new_clique); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return new_clique; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-11-04 11:22:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 |  |  | 	public: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/** Create an empty Bayes Tree */ | 
					
						
							|  |  |  | 		BayesTree(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 11:50:30 +08:00
										 |  |  | 		/** Create a Bayes Tree from a Bayes Net */ | 
					
						
							| 
									
										
										
										
											2009-11-04 11:22:29 +08:00
										 |  |  | 		BayesTree(const BayesNet<Conditional>& bayesNet); | 
					
						
							| 
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/** Destructor */ | 
					
						
							| 
									
										
										
										
											2009-11-07 23:58:45 +08:00
										 |  |  | 		virtual ~BayesTree() { | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-10-28 04:23:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 |  |  | 		/** print */ | 
					
						
							|  |  |  | 		void print(const std::string& s = "") const; | 
					
						
							| 
									
										
										
										
											2009-10-28 04:23:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 |  |  | 		/** check equality */ | 
					
						
							|  |  |  | 		bool equals(const BayesTree<Conditional>& other, double tol = 1e-9) const; | 
					
						
							| 
									
										
										
										
											2009-10-28 04:23:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 |  |  | 		/** insert a new conditional */ | 
					
						
							| 
									
										
										
										
											2009-11-08 01:24:05 +08:00
										 |  |  | 		void insert(const sharedConditional& conditional); | 
					
						
							| 
									
										
										
										
											2009-10-28 04:23:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-07 23:58:45 +08:00
										 |  |  | 		/** number of cliques */ | 
					
						
							|  |  |  | 		inline size_t size() const { | 
					
						
							| 
									
										
										
										
											2009-11-19 02:05:12 +08:00
										 |  |  | 			return root_->treeSize(); | 
					
						
							| 
									
										
										
										
											2009-11-07 23:58:45 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-10-31 22:12:41 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 |  |  | 		/** return root clique */ | 
					
						
							| 
									
										
										
										
											2009-11-08 01:24:05 +08:00
										 |  |  | 		sharedClique root() const { | 
					
						
							| 
									
										
										
										
											2009-11-07 23:58:45 +08:00
										 |  |  | 			return root_; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-10-28 04:23:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-06 13:55:29 +08:00
										 |  |  | 		/** find the clique to which key belongs */ | 
					
						
							| 
									
										
										
										
											2009-11-08 01:24:05 +08:00
										 |  |  | 		sharedClique operator[](const std::string& key) const { | 
					
						
							| 
									
										
										
										
											2009-11-06 13:55:29 +08:00
										 |  |  | 			typename Nodes::const_iterator it = nodes_.find(key); | 
					
						
							| 
									
										
										
										
											2009-11-07 23:58:45 +08:00
										 |  |  | 			if (it == nodes_.end()) throw(std::invalid_argument( | 
					
						
							| 
									
										
										
										
											2009-11-08 12:41:01 +08:00
										 |  |  | 					"BayesTree::operator['" + key + "']: key not found")); | 
					
						
							| 
									
										
										
										
											2009-11-08 01:24:05 +08:00
										 |  |  | 			sharedClique clique = it->second; | 
					
						
							| 
									
										
										
										
											2009-11-06 13:55:29 +08:00
										 |  |  | 			return clique; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 11:22:29 +08:00
										 |  |  | 		/** return marginal on any variable */ | 
					
						
							| 
									
										
										
										
											2009-11-05 14:30:50 +08:00
										 |  |  | 		template<class Factor> | 
					
						
							| 
									
										
										
										
											2009-11-12 12:56:30 +08:00
										 |  |  | 		FactorGraph<Factor> marginal(const std::string& key) const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/** return marginal on any variable, as a Bayes Net */ | 
					
						
							|  |  |  | 		template<class Factor> | 
					
						
							|  |  |  | 		BayesNet<Conditional> marginalBayesNet(const std::string& key) const; | 
					
						
							| 
									
										
										
										
											2009-11-09 08:13:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/** return joint on two variables */ | 
					
						
							|  |  |  | 		template<class Factor> | 
					
						
							| 
									
										
										
										
											2009-11-12 12:56:30 +08:00
										 |  |  | 		FactorGraph<Factor> joint(const std::string& key1, const std::string& key2) const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/** return joint on two variables as a BayesNet */ | 
					
						
							|  |  |  | 		template<class Factor> | 
					
						
							|  |  |  | 		BayesNet<Conditional> jointBayesNet(const std::string& key1, const std::string& key2) const; | 
					
						
							| 
									
										
										
										
											2009-11-09 08:13:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 |  |  | 	}; // BayesTree
 | 
					
						
							| 
									
										
										
										
											2009-10-28 04:23:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | } /// namespace gtsam
 |