| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * @file    FactorGraph.h | 
					
						
							|  |  |  |  * @brief   Factor Graph Base Class | 
					
						
							|  |  |  |  * @author  Carlos Nieto | 
					
						
							|  |  |  |  * @author  Christian Potthast | 
					
						
							| 
									
										
										
										
											2010-07-10 02:15:54 +08:00
										 |  |  |  * @author  Michael Kaess | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // \callgraph
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <boost/shared_ptr.hpp>
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | #include <boost/foreach.hpp>
 | 
					
						
							| 
									
										
										
										
											2010-08-27 23:31:20 +08:00
										 |  |  | //#include <boost/serialization/map.hpp>
 | 
					
						
							|  |  |  | //#include <boost/serialization/list.hpp>
 | 
					
						
							|  |  |  | //#include <boost/serialization/vector.hpp>
 | 
					
						
							|  |  |  | //#include <boost/serialization/shared_ptr.hpp>
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | #include <boost/pool/pool_alloc.hpp>
 | 
					
						
							| 
									
										
										
										
											2009-08-31 10:40:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | #include <gtsam/base/types.h>
 | 
					
						
							| 
									
										
										
										
											2010-08-20 01:23:19 +08:00
										 |  |  | #include <gtsam/base/Testable.h>
 | 
					
						
							|  |  |  | #include <gtsam/inference/BayesNet.h>
 | 
					
						
							|  |  |  | #include <gtsam/inference/graph.h>
 | 
					
						
							| 
									
										
										
										
											2009-10-25 07:14:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | namespace gtsam { | 
					
						
							| 
									
										
										
										
											2009-08-31 10:40:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/**
 | 
					
						
							|  |  |  | 	 * A factor graph is a bipartite graph with factor nodes connected to variable nodes. | 
					
						
							|  |  |  | 	 * In this class, however, only factor nodes are kept around. | 
					
						
							| 
									
										
										
										
											2009-10-07 02:25:04 +08:00
										 |  |  | 	 *  | 
					
						
							| 
									
										
										
										
											2010-10-09 11:09:58 +08:00
										 |  |  | 	 * Templated on the type of factors and values structure. | 
					
						
							| 
									
										
										
										
											2009-08-31 10:40:26 +08:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 	template<class Factor> | 
					
						
							|  |  |  | 	class FactorGraph: public Testable<FactorGraph<Factor> > { | 
					
						
							| 
									
										
										
										
											2009-08-31 10:40:26 +08:00
										 |  |  | 	public: | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 	  typedef Factor factor_type; | 
					
						
							|  |  |  | 	  typedef boost::shared_ptr<FactorGraph<Factor> > shared_ptr; | 
					
						
							| 
									
										
										
										
											2009-11-08 03:31:39 +08:00
										 |  |  | 		typedef typename boost::shared_ptr<Factor> sharedFactor; | 
					
						
							|  |  |  | 		typedef typename std::vector<sharedFactor>::iterator iterator; | 
					
						
							|  |  |  | 		typedef typename std::vector<sharedFactor>::const_iterator const_iterator; | 
					
						
							| 
									
										
										
										
											2009-08-31 10:40:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	protected: | 
					
						
							| 
									
										
										
										
											2010-01-18 03:34:57 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** Collection of factors */ | 
					
						
							| 
									
										
										
										
											2009-11-08 03:31:39 +08:00
										 |  |  | 		std::vector<sharedFactor> factors_; | 
					
						
							| 
									
										
										
										
											2009-08-31 10:40:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | //		/**
 | 
					
						
							|  |  |  | //		 * Return an ordering in first argument, potentially using a set of
 | 
					
						
							|  |  |  | //		 * keys that need to appear last, and potentially restricting scope
 | 
					
						
							|  |  |  | //		 */
 | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  | //		void getOrdering(Ordering& ordering, const std::set<Index>& lastKeys,
 | 
					
						
							|  |  |  | //				boost::optional<const std::set<Index>&> scope = boost::none) const;
 | 
					
						
							| 
									
										
										
										
											2010-07-14 21:55:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-31 10:40:26 +08:00
										 |  |  | 	public: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-14 21:55:32 +08:00
										 |  |  | 		/** ------------------ Creating Factor Graphs ---------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-05 12:56:59 +08:00
										 |  |  | 		/** Default constructor */ | 
					
						
							|  |  |  | 		FactorGraph() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/** convert from Bayes net */ | 
					
						
							|  |  |  | 		template<class Conditional> | 
					
						
							|  |  |  | 		FactorGraph(const BayesNet<Conditional>& bayesNet); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 		/** convert from a derived type */ | 
					
						
							| 
									
										
										
										
											2010-10-14 04:43:58 +08:00
										 |  |  | 		template<class DerivedFactor> | 
					
						
							|  |  |  | 		FactorGraph(const FactorGraph<DerivedFactor>& factorGraph); | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-14 21:55:32 +08:00
										 |  |  | 		/** Add a factor */ | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 		template<class DerivedFactor> | 
					
						
							|  |  |  | 		void push_back(const boost::shared_ptr<DerivedFactor>& factor); | 
					
						
							| 
									
										
										
										
											2010-07-14 21:55:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/** push back many factors */ | 
					
						
							|  |  |  | 		void push_back(const FactorGraph<Factor>& factors); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/** ------------------ Querying Factor Graphs ---------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-26 06:27:18 +08:00
										 |  |  | 		/** print out graph */ | 
					
						
							|  |  |  | 		void print(const std::string& s = "FactorGraph") const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/** Check equality */ | 
					
						
							|  |  |  | 		bool equals(const FactorGraph& fg, double tol = 1e-9) const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 		/** const cast to the underlying vector of factors */ | 
					
						
							|  |  |  | 		operator const std::vector<sharedFactor>&() const { return factors_; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-23 13:27:19 +08:00
										 |  |  | 		/** STL begin and end, so we can use BOOST_FOREACH */ | 
					
						
							|  |  |  | 		inline const_iterator begin() const { return factors_.begin();} | 
					
						
							|  |  |  | 		inline const_iterator end()   const { return factors_.end();  } | 
					
						
							| 
									
										
										
										
											2009-08-31 10:40:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/** Get a specific factor by index */ | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 		inline sharedFactor operator[](size_t i) const { assert(i<factors_.size()); return factors_[i]; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** Get the first factor */ | 
					
						
							|  |  |  |     inline sharedFactor front() const { return factors_.front(); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/** Get the last factor */ | 
					
						
							|  |  |  | 		inline sharedFactor back() const { return factors_.back(); } | 
					
						
							| 
									
										
										
										
											2009-08-31 10:40:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-29 12:11:23 +08:00
										 |  |  | 		/** return the number of factors and NULLS */ | 
					
						
							| 
									
										
										
										
											2009-12-21 05:21:01 +08:00
										 |  |  | 		inline size_t size() const { return factors_.size();} | 
					
						
							| 
									
										
										
										
											2009-10-29 12:11:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/** return the number valid factors */ | 
					
						
							| 
									
										
										
										
											2009-12-21 05:21:01 +08:00
										 |  |  | 		size_t nrFactors() const; | 
					
						
							| 
									
										
										
										
											2009-08-31 10:40:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | //		/** return keys in some random order */
 | 
					
						
							|  |  |  | //		Ordering keys() const;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //		/**
 | 
					
						
							|  |  |  | //		 * Compute colamd ordering, including I/O, constrained ordering,
 | 
					
						
							|  |  |  | //		 * and shared pointer version.
 | 
					
						
							|  |  |  | //		 */
 | 
					
						
							|  |  |  | //		Ordering getOrdering() const;
 | 
					
						
							|  |  |  | //		boost::shared_ptr<Ordering> getOrdering_() const;
 | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  | //		Ordering getOrdering(const std::set<Index>& scope) const;
 | 
					
						
							|  |  |  | //		Ordering getConstrainedOrdering(const std::set<Index>& lastKeys) const;
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | //		/**
 | 
					
						
							|  |  |  | //		 * find the minimum spanning tree using boost graph library
 | 
					
						
							|  |  |  | //		 */
 | 
					
						
							|  |  |  | //		template<class Key, class Factor2> PredecessorMap<Key>
 | 
					
						
							|  |  |  | // SL-NEEDED?				findMinimumSpanningTree() const;
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //		/**
 | 
					
						
							|  |  |  | //		 * Split the graph into two parts: one corresponds to the given spanning tree,
 | 
					
						
							|  |  |  | //		 * and the other corresponds to the rest of the factors
 | 
					
						
							|  |  |  | //		 */
 | 
					
						
							|  |  |  | // SL-NEEDED?		template<class Key, class Factor2> void split(const PredecessorMap<Key>& tree,
 | 
					
						
							|  |  |  | //				FactorGraph<Factor>& Ab1, FactorGraph<Factor>& Ab2) const;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //		/**
 | 
					
						
							|  |  |  | //		 * find the minimum spanning tree using DSF
 | 
					
						
							|  |  |  | //		 */
 | 
					
						
							|  |  |  | //		std::pair<FactorGraph<Factor> , FactorGraph<Factor> >
 | 
					
						
							|  |  |  | // SL-NEEDED?				splitMinimumSpanningTree() const;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //		/**
 | 
					
						
							|  |  |  | //		 * Check consistency of the index map, useful for debugging
 | 
					
						
							|  |  |  | //		 */
 | 
					
						
							|  |  |  | //		void checkGraphConsistency() const;
 | 
					
						
							| 
									
										
										
										
											2010-02-13 09:29:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-14 21:55:32 +08:00
										 |  |  | 		/** ----------------- Modifying Factor Graphs ---------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/** STL begin and end, so we can use BOOST_FOREACH */ | 
					
						
							|  |  |  | 		inline       iterator begin()       { return factors_.begin();} | 
					
						
							|  |  |  | 		inline       iterator end()         { return factors_.end();  } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 		/**
 | 
					
						
							|  |  |  | 		 * Reserve space for the specified number of factors if you know in | 
					
						
							|  |  |  | 		 * advance how many there will be (works like std::vector::reserve). | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		void reserve(size_t size) { factors_.reserve(size); } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-14 21:55:32 +08:00
										 |  |  | 		/** delete factor without re-arranging indexes by inserting a NULL pointer */ | 
					
						
							|  |  |  | 		inline void remove(size_t i) { factors_[i].reset();} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/** replace a factor by index */ | 
					
						
							|  |  |  | 		void replace(size_t index, sharedFactor factor); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | //    /**
 | 
					
						
							|  |  |  | //     * Find all the factors that involve the given node and remove them
 | 
					
						
							|  |  |  | //     * from the factor graph
 | 
					
						
							|  |  |  | //     * @param key the key for the given node
 | 
					
						
							|  |  |  | //     */
 | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  | //    std::vector<sharedFactor> findAndRemoveFactors(Index key);
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | //
 | 
					
						
							|  |  |  | //		/** remove singleton variables and the related factors */
 | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  | //		std::pair<FactorGraph<Factor>, std::set<Index> > removeSingletons();
 | 
					
						
							| 
									
										
										
										
											2010-07-14 21:55:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-31 12:13:57 +08:00
										 |  |  | 	private: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/** Serialization function */ | 
					
						
							|  |  |  | 		friend class boost::serialization::access; | 
					
						
							|  |  |  | 		template<class Archive> | 
					
						
							|  |  |  | 		void serialize(Archive & ar, const unsigned int version) { | 
					
						
							|  |  |  | 			ar & BOOST_SERIALIZATION_NVP(factors_); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}; // FactorGraph
 | 
					
						
							| 
									
										
										
										
											2009-11-08 03:31:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/**
 | 
					
						
							| 
									
										
										
										
											2009-11-08 10:50:19 +08:00
										 |  |  |    * static function that combines two factor graphs | 
					
						
							|  |  |  |    * @param const &fg1 Linear factor graph | 
					
						
							|  |  |  |    * @param const &fg2 Linear factor graph | 
					
						
							|  |  |  |    * @return a new combined factor graph | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2010-10-10 11:10:03 +08:00
										 |  |  | 	template<class FactorGraph> | 
					
						
							|  |  |  | 	FactorGraph combine(const FactorGraph& fg1, const FactorGraph& fg2); | 
					
						
							| 
									
										
										
										
											2009-11-08 10:50:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | //  /**
 | 
					
						
							|  |  |  | //   * Extract and combine all the factors that involve a given node
 | 
					
						
							|  |  |  | //   * Put this here as not all Factors have a combine constructor
 | 
					
						
							|  |  |  | //   * @param key the key for the given node
 | 
					
						
							|  |  |  | //   * @return the combined linear factor
 | 
					
						
							|  |  |  | //   */
 | 
					
						
							|  |  |  | //	template<class Factor> boost::shared_ptr<Factor>
 | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  | //		removeAndCombineFactors(FactorGraph<Factor>& factorGraph, const Index& key);
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/**
 | 
					
						
							|  |  |  | 	 * These functions are defined here because they are templated on an | 
					
						
							|  |  |  | 	 * additional parameter.  Putting them in the -inl.h file would mean these | 
					
						
							|  |  |  | 	 * would have to be explicitly instantiated for any possible derived factor | 
					
						
							|  |  |  | 	 * type. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   template<class Factor> | 
					
						
							| 
									
										
										
										
											2010-10-14 04:43:58 +08:00
										 |  |  |   template<class DerivedFactor> | 
					
						
							|  |  |  |   FactorGraph<Factor>::FactorGraph(const FactorGraph<DerivedFactor>& factorGraph) { | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |     factors_.reserve(factorGraph.size()); | 
					
						
							| 
									
										
										
										
											2010-10-14 04:43:58 +08:00
										 |  |  |     BOOST_FOREACH(const typename DerivedFactor::shared_ptr& factor, factorGraph) { | 
					
						
							| 
									
										
										
										
											2010-10-10 11:10:03 +08:00
										 |  |  |       if(factor) | 
					
						
							|  |  |  |         this->push_back(sharedFactor(new Factor(*factor))); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         this->push_back(sharedFactor()); | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-14 04:43:58 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   template<class Factor> | 
					
						
							|  |  |  |   template<class Conditional> | 
					
						
							|  |  |  |   FactorGraph<Factor>::FactorGraph(const BayesNet<Conditional>& bayesNet) { | 
					
						
							|  |  |  |     factors_.reserve(bayesNet.size()); | 
					
						
							|  |  |  |     BOOST_FOREACH(const typename Conditional::shared_ptr& cond, bayesNet) { | 
					
						
							|  |  |  |       this->push_back(sharedFactor(new Factor(*cond))); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   template<class Factor> | 
					
						
							|  |  |  |   template<class DerivedFactor> | 
					
						
							|  |  |  |   inline void FactorGraph<Factor>::push_back(const boost::shared_ptr<DerivedFactor>& factor) { | 
					
						
							|  |  |  | #ifndef NDEBUG
 | 
					
						
							|  |  |  |     factors_.push_back(boost::dynamic_pointer_cast<Factor>(factor)); // add the actual factor
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     factors_.push_back(boost::static_pointer_cast<Factor>(factor)); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-14 21:55:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | } // namespace gtsam
 | 
					
						
							| 
									
										
										
										
											2009-10-07 02:25:04 +08:00
										 |  |  | 
 |