201 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			201 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C++
		
	
	
| /**
 | |
|  * @file    FactorGraph.h
 | |
|  * @brief   Factor Graph Base Class
 | |
|  * @author  Carlos Nieto
 | |
|  * @author  Christian Potthast
 | |
|  * @author  Michael Kaess
 | |
|  */
 | |
| 
 | |
| // \callgraph
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #include <boost/shared_ptr.hpp>
 | |
| //#include <boost/serialization/map.hpp>
 | |
| //#include <boost/serialization/list.hpp>
 | |
| //#include <boost/serialization/vector.hpp>
 | |
| //#include <boost/serialization/shared_ptr.hpp>
 | |
| 
 | |
| #include <gtsam/base/Testable.h>
 | |
| #include <gtsam/inference/BayesNet.h>
 | |
| #include <gtsam/inference/graph.h>
 | |
| #include <gtsam/inference/Key.h>
 | |
| #include <gtsam/inference/SymbolMap.h>
 | |
| 
 | |
| namespace gtsam {
 | |
| 
 | |
| 	class Ordering;
 | |
| 
 | |
| 	/**
 | |
| 	 * A factor graph is a bipartite graph with factor nodes connected to variable nodes.
 | |
| 	 * In this class, however, only factor nodes are kept around.
 | |
| 	 * 
 | |
| 	 * Templated on the type of factors and configuration.
 | |
| 	 */
 | |
| 	template<class Factor> class FactorGraph: public Testable<FactorGraph<Factor> > {
 | |
| 	public:
 | |
| 		typedef typename boost::shared_ptr<Factor> sharedFactor;
 | |
| 		typedef typename std::vector<sharedFactor>::iterator iterator;
 | |
| 		typedef typename std::vector<sharedFactor>::const_iterator const_iterator;
 | |
| 
 | |
| 	protected:
 | |
| 
 | |
|     /** Collection of factors */
 | |
| 		std::vector<sharedFactor> factors_;
 | |
| 
 | |
| 		/** For each variable a list of factor indices connected to it  */
 | |
| 		typedef SymbolMap<std::list<size_t> > Indices;
 | |
| 		Indices indices_;
 | |
| 
 | |
| 		/** Associate factor index with the variables connected to the factor */
 | |
| 		void associateFactor(size_t index, const sharedFactor& factor);
 | |
| 
 | |
| 		/**
 | |
| 		 * Return an ordering in first argument, potentially using a set of
 | |
| 		 * keys that need to appear last, and potentially restricting scope
 | |
| 		 */
 | |
| 		void getOrdering(Ordering& ordering, const std::set<Symbol>& lastKeys,
 | |
| 				boost::optional<const std::set<Symbol>&> scope = boost::none) const;
 | |
| 
 | |
| 	public:
 | |
| 
 | |
| 		/** ------------------ Creating Factor Graphs ---------------------------- */
 | |
| 
 | |
| 		/** Default constructor */
 | |
| 		FactorGraph() {}
 | |
| 
 | |
| 		/** convert from Bayes net */
 | |
| 		template<class Conditional>
 | |
| 		FactorGraph(const BayesNet<Conditional>& bayesNet);
 | |
| 
 | |
| 		/** Add a factor */
 | |
| 		void push_back(sharedFactor factor);
 | |
| 
 | |
| 		/** push back many factors */
 | |
| 		void push_back(const FactorGraph<Factor>& factors);
 | |
| 
 | |
| 		/** ------------------ Querying Factor Graphs ---------------------------- */
 | |
| 
 | |
| 		/** print out graph */
 | |
| 		void print(const std::string& s = "FactorGraph") const;
 | |
| 
 | |
| 		/** Check equality */
 | |
| 		bool equals(const FactorGraph& fg, double tol = 1e-9) const;
 | |
| 
 | |
| 		/** 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();  }
 | |
| 
 | |
| 		/** Get a specific factor by index */
 | |
| 		inline sharedFactor operator[](size_t i) const {return factors_[i];}
 | |
| 
 | |
| 		/** return the number of factors and NULLS */
 | |
| 		inline size_t size() const { return factors_.size();}
 | |
| 
 | |
| 		/** return the number valid factors */
 | |
| 		size_t nrFactors() const;
 | |
| 
 | |
| 		/** return keys in some random order */
 | |
| 		Ordering keys() const;
 | |
| 
 | |
| 		/** return the number of the keys */
 | |
| 		inline size_t nrKeys() const {return indices_.size(); };
 | |
| 
 | |
| 		/** Check whether a factor with this variable exists */
 | |
| 		bool involves(const Symbol& key) const {
 | |
| 			return !(indices_.find(key)==indices_.end());
 | |
| 		}
 | |
| 
 | |
|     /**
 | |
|      * Return indices for all factors that involve the given node
 | |
|      * @param key the key for the given node
 | |
|      */
 | |
|     std::list<size_t> factors(const Symbol& key) const;
 | |
| 
 | |
| 		/**
 | |
| 		 * Compute colamd ordering, including I/O, constrained ordering,
 | |
| 		 * and shared pointer version.
 | |
| 		 */
 | |
| 		Ordering getOrdering() const;
 | |
| 		boost::shared_ptr<Ordering> getOrdering_() const;
 | |
| 		Ordering getOrdering(const std::set<Symbol>& scope) const;
 | |
| 		Ordering getConstrainedOrdering(const std::set<Symbol>& lastKeys) const;
 | |
| 
 | |
| 		/**
 | |
| 		 * find the minimum spanning tree using boost graph library
 | |
| 		 */
 | |
| 		template<class Key, class Factor2> PredecessorMap<Key>
 | |
| 				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
 | |
| 		 */
 | |
| 		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> >
 | |
| 				splitMinimumSpanningTree() const;
 | |
| 
 | |
| 		/**
 | |
| 		 * Check consistency of the index map, useful for debugging
 | |
| 		 */
 | |
| 		void checkGraphConsistency() const;
 | |
| 
 | |
| 		/** ----------------- 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();  }
 | |
| 
 | |
| 		/** 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);
 | |
| 
 | |
|     /**
 | |
|      * Find all the factors that involve the given node and remove them
 | |
|      * from the factor graph
 | |
|      * @param key the key for the given node
 | |
|      */
 | |
|     std::vector<sharedFactor> findAndRemoveFactors(const Symbol& key);
 | |
| 
 | |
| 		/** remove singleton variables and the related factors */
 | |
| 		std::pair<FactorGraph<Factor>, std::set<Symbol> > removeSingletons();
 | |
| 
 | |
| 	private:
 | |
| 
 | |
| 		/** Serialization function */
 | |
| 		friend class boost::serialization::access;
 | |
| 		template<class Archive>
 | |
| 		void serialize(Archive & ar, const unsigned int version) {
 | |
| 			ar & BOOST_SERIALIZATION_NVP(factors_);
 | |
| 			ar & BOOST_SERIALIZATION_NVP(indices_);
 | |
| 		}
 | |
| 	}; // FactorGraph
 | |
| 
 | |
| 	/**
 | |
|    * 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
 | |
|    */
 | |
| 	template<class Factor>
 | |
| 	FactorGraph<Factor> combine(const FactorGraph<Factor>& fg1, const FactorGraph<Factor>& fg2);
 | |
| 
 | |
|   /**
 | |
|    * 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>
 | |
| 		removeAndCombineFactors(FactorGraph<Factor>& factorGraph, const Symbol& key);
 | |
| 
 | |
| } // namespace gtsam
 | |
| 
 |