| 
									
										
										
										
											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 */ | 
					
						
							| 
									
										
										
										
											2009-11-21 14:07:46 +08:00
										 |  |  | 			void print(const std::string& s = "") const; | 
					
						
							| 
									
										
										
										
											2009-11-08 12:41:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-23 02:06:28 +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-11-23 00:46:29 +08:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-23 00:46:29 +08:00
										 |  |  | 		// typedef for shared pointers to cliques
 | 
					
						
							| 
									
										
										
										
											2009-11-08 01:24:05 +08:00
										 |  |  | 		typedef boost::shared_ptr<Clique> sharedClique; | 
					
						
							| 
									
										
										
										
											2009-11-07 23:58:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-23 00:46:29 +08:00
										 |  |  | 		// A convenience class for a list of shared cliques
 | 
					
						
							|  |  |  | 		struct Cliques : public std::list<sharedClique>, public Testable<Cliques> { | 
					
						
							| 
									
										
										
										
											2009-11-23 01:40:24 +08:00
										 |  |  | 			void print(const std::string& s = "Cliques") const; | 
					
						
							|  |  |  | 			bool equals(const Cliques& other, double tol = 1e-9) const; | 
					
						
							| 
									
										
										
										
											2009-11-23 00:46:29 +08:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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, | 
					
						
							| 
									
										
										
										
											2009-11-21 14:07:46 +08:00
										 |  |  | 				sharedClique parent_clique = sharedClique()); | 
					
						
							| 
									
										
										
										
											2009-11-04 11:22:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-21 11:38:13 +08:00
										 |  |  | 		/** remove a clique: warning, can result in a forest */ | 
					
						
							| 
									
										
										
										
											2009-11-21 14:07:46 +08:00
										 |  |  | 		void removeClique(sharedClique clique); | 
					
						
							| 
									
										
										
										
											2009-11-21 11:38:13 +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-23 00:04:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-23 01:34:59 +08:00
										 |  |  | 		/**
 | 
					
						
							|  |  |  | 		 * Remove path from clique to root and return that path as factors | 
					
						
							|  |  |  | 		 * plus a list of orphaned subtree roots. Used in removeTop below. | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2009-11-21 11:38:13 +08:00
										 |  |  | 		template<class Factor> | 
					
						
							| 
									
										
										
										
											2009-11-23 00:46:29 +08:00
										 |  |  | 		std::pair<FactorGraph<Factor>, Cliques> removePath(sharedClique clique); | 
					
						
							| 
									
										
										
										
											2009-11-23 00:04:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-23 01:34:59 +08:00
										 |  |  | 		/**
 | 
					
						
							|  |  |  | 		 * Given a set of factors, turn "contaminated" part of the tree back into a factor graph | 
					
						
							|  |  |  | 		 * and return it along with the new factors plus a list of orphaned subtree roots. | 
					
						
							|  |  |  | 		 * This is used for incrementally updating a BayesTree given new measurements (factors). | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		template<class Factor> | 
					
						
							|  |  |  | 		std::pair<FactorGraph<Factor>, Cliques> removeTop(const boost::shared_ptr<Factor>& newFactor); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-31 13:12:39 +08:00
										 |  |  | 	}; // BayesTree
 | 
					
						
							| 
									
										
										
										
											2009-10-28 04:23:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | } /// namespace gtsam
 |