| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2009-11-13 00:16:32 +08:00
										 |  |  |  * @file    GaussianFactorGraph.h | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |  * @brief   Linear Factor Graph where all factors are Gaussians | 
					
						
							|  |  |  |  * @author  Kai Ni | 
					
						
							|  |  |  |  * @author  Christian Potthast | 
					
						
							|  |  |  |  * @author  Alireza Fathi | 
					
						
							|  |  |  |  */  | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-13 00:16:32 +08:00
										 |  |  | // $Id: GaussianFactorGraph.h,v 1.24 2009/08/14 20:48:51 acunning Exp $
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // \callgraph
 | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <boost/shared_ptr.hpp>
 | 
					
						
							|  |  |  | #include "FactorGraph.h"
 | 
					
						
							| 
									
										
										
										
											2009-12-27 20:13:31 +08:00
										 |  |  | #include "Errors.h"
 | 
					
						
							| 
									
										
										
										
											2009-11-13 00:16:32 +08:00
										 |  |  | #include "GaussianFactor.h"
 | 
					
						
							| 
									
										
										
										
											2009-11-05 11:51:08 +08:00
										 |  |  | #include "GaussianBayesNet.h" // needed for MATLAB toolbox !!
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 11:50:30 +08:00
										 |  |  | 	class Ordering; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-07 02:25:04 +08:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * A Linear Factor Graph is a factor graph where all factors are Gaussian, i.e. | 
					
						
							| 
									
										
										
										
											2009-11-13 00:16:32 +08:00
										 |  |  |    *   Factor == GaussianFactor | 
					
						
							| 
									
										
										
										
											2009-10-15 04:39:59 +08:00
										 |  |  |    *   VectorConfig = A configuration of vectors | 
					
						
							| 
									
										
										
										
											2009-10-07 02:25:04 +08:00
										 |  |  |    * Most of the time, linear factor graphs arise by linearizing a non-linear factor graph. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2009-11-13 00:16:32 +08:00
										 |  |  |   class GaussianFactorGraph : public FactorGraph<GaussianFactor> { | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |   public: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /**
 | 
					
						
							|  |  |  |      * Default constructor  | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2009-11-13 00:16:32 +08:00
										 |  |  |     GaussianFactorGraph() {} | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /**
 | 
					
						
							| 
									
										
										
										
											2009-11-13 00:16:32 +08:00
										 |  |  |      * Constructor that receives a Chordal Bayes Net and returns a GaussianFactorGraph | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2009-11-13 00:16:32 +08:00
										 |  |  |     GaussianFactorGraph(const GaussianBayesNet& CBN); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-10 23:33:52 +08:00
										 |  |  |   	/** Add a null factor */ | 
					
						
							|  |  |  |     inline void add(const Vector& b) { | 
					
						
							|  |  |  |     	push_back(sharedFactor(new GaussianFactor(b))); | 
					
						
							|  |  |  |   	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   	/** Add a unary factor */ | 
					
						
							| 
									
										
										
										
											2010-01-18 03:34:57 +08:00
										 |  |  |     inline void add(const Symbol& key1, const Matrix& A1, | 
					
						
							| 
									
										
										
										
											2009-12-10 23:33:52 +08:00
										 |  |  |   			const Vector& b, double sigma) { | 
					
						
							|  |  |  |     	push_back(sharedFactor(new GaussianFactor(key1,A1,b,sigma))); | 
					
						
							|  |  |  |   	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   	/** Add a binary factor */ | 
					
						
							| 
									
										
										
										
											2010-01-18 03:34:57 +08:00
										 |  |  |     inline void add(const Symbol& key1, const Matrix& A1, | 
					
						
							|  |  |  |   			const Symbol& key2, const Matrix& A2, | 
					
						
							| 
									
										
										
										
											2009-12-10 23:33:52 +08:00
										 |  |  |   			const Vector& b, double sigma) { | 
					
						
							|  |  |  |     	push_back(sharedFactor(new GaussianFactor(key1,A1,key2,A2,b,sigma))); | 
					
						
							|  |  |  |   	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   	/** Add a ternary factor */ | 
					
						
							| 
									
										
										
										
											2010-01-18 03:34:57 +08:00
										 |  |  |     inline void add(const Symbol& key1, const Matrix& A1, | 
					
						
							|  |  |  |   			const Symbol& key2, const Matrix& A2, | 
					
						
							|  |  |  |   			const Symbol& key3, const Matrix& A3, | 
					
						
							| 
									
										
										
										
											2009-12-10 23:33:52 +08:00
										 |  |  |   			const Vector& b, double sigma) { | 
					
						
							|  |  |  |     	push_back(sharedFactor(new GaussianFactor(key1,A1,key2,A2,key3,A3,b,sigma))); | 
					
						
							|  |  |  |   	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   	/** Add an n-ary factor */ | 
					
						
							| 
									
										
										
										
											2010-01-18 03:34:57 +08:00
										 |  |  |     inline void add(const std::vector<std::pair<Symbol, Matrix> > &terms, | 
					
						
							| 
									
										
										
										
											2009-12-10 23:33:52 +08:00
										 |  |  |   	    const Vector &b, double sigma) { | 
					
						
							|  |  |  |     	push_back(sharedFactor(new GaussianFactor(terms,b,sigma))); | 
					
						
							|  |  |  |   	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-27 20:13:31 +08:00
										 |  |  | 		/** return A*x-b */ | 
					
						
							|  |  |  | 		Errors errors(const VectorConfig& x) const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-19 18:46:12 +08:00
										 |  |  | 		/** shared pointer version */ | 
					
						
							|  |  |  | 		boost::shared_ptr<Errors> errors_(const VectorConfig& x) const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-27 20:13:31 +08:00
										 |  |  | 			/** unnormalized error */ | 
					
						
							| 
									
										
										
										
											2009-12-27 06:48:41 +08:00
										 |  |  | 		double error(const VectorConfig& x) const; | 
					
						
							| 
									
										
										
										
											2009-10-29 12:11:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-27 06:48:41 +08:00
										 |  |  | 		/** return A*x */ | 
					
						
							|  |  |  | 		Errors operator*(const VectorConfig& x) const; | 
					
						
							| 
									
										
										
										
											2009-10-29 12:11:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-27 20:13:31 +08:00
										 |  |  | 		/** return A^x */ | 
					
						
							|  |  |  | 		VectorConfig operator^(const Errors& e) const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   	/**
 | 
					
						
							|  |  |  |   	 * Calculate Gradient of A^(A*x-b) for a given config | 
					
						
							|  |  |  |   	 * @param x: VectorConfig specifying where to calculate gradient | 
					
						
							|  |  |  |   	 * @return gradient, as a VectorConfig as well | 
					
						
							|  |  |  |   	 */ | 
					
						
							|  |  |  |   	VectorConfig gradient(const VectorConfig& x) const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-29 12:11:23 +08:00
										 |  |  | 		/** Unnormalized probability. O(n) */ | 
					
						
							|  |  |  | 		double probPrime(const VectorConfig& c) const { | 
					
						
							|  |  |  | 			return exp(-0.5 * error(c)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * find the separator, i.e. all the nodes that have at least one | 
					
						
							|  |  |  |      * common factor with the given node. FD: not used AFAIK. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2010-01-18 03:34:57 +08:00
										 |  |  |     std::set<Symbol> find_separator(const Symbol& key) const; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-08 05:03:30 +08:00
										 |  |  |   	/**
 | 
					
						
							|  |  |  |      * Eliminate a single node yielding a conditional Gaussian | 
					
						
							|  |  |  |      * Eliminates the factors from the factor graph through findAndRemoveFactors | 
					
						
							|  |  |  |      * and adds a new factor on the separator to the factor graph | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2010-01-18 03:34:57 +08:00
										 |  |  |     GaussianConditional::shared_ptr eliminateOne(const Symbol& key); | 
					
						
							| 
									
										
										
										
											2009-11-08 05:03:30 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * eliminate factor graph in place(!) in the given order, yielding | 
					
						
							| 
									
										
										
										
											2009-11-05 12:56:59 +08:00
										 |  |  |      * a chordal Bayes net. Allows for passing an incomplete ordering | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |      * that does not completely eliminate the graph | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2009-11-09 15:04:26 +08:00
										 |  |  |     GaussianBayesNet eliminate(const Ordering& ordering); | 
					
						
							| 
									
										
										
										
											2010-01-19 18:46:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * optimize a linear factor graph | 
					
						
							|  |  |  |      * @param ordering fg in order | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2009-10-15 04:39:59 +08:00
										 |  |  |     VectorConfig optimize(const Ordering& ordering); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-11 15:14:13 +08:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * shared pointer versions for MATLAB | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     boost::shared_ptr<GaussianBayesNet> eliminate_(const Ordering&); | 
					
						
							|  |  |  |     boost::shared_ptr<VectorConfig> optimize_(const Ordering&); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     /**
 | 
					
						
							| 
									
										
										
										
											2009-08-25 10:36:30 +08:00
										 |  |  |      * static function that combines two factor graphs | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |      * @param const &lfg1 Linear factor graph | 
					
						
							|  |  |  |      * @param const &lfg2 Linear factor graph | 
					
						
							|  |  |  |      * @return a new combined factor graph | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2009-11-13 00:16:32 +08:00
										 |  |  |     static GaussianFactorGraph combine2(const GaussianFactorGraph& lfg1, | 
					
						
							|  |  |  | 				const GaussianFactorGraph& lfg2); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 		 | 
					
						
							|  |  |  |     /**
 | 
					
						
							|  |  |  |      * combine two factor graphs | 
					
						
							|  |  |  |      * @param *lfg Linear factor graph | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2009-11-13 00:16:32 +08:00
										 |  |  |     void combine(const GaussianFactorGraph &lfg); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /**
 | 
					
						
							|  |  |  |      * Find all variables and their dimensions | 
					
						
							|  |  |  |      * @return The set of all variable/dimension pairs | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2009-11-06 13:43:03 +08:00
										 |  |  |     Dimensions dimensions() const; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /**
 | 
					
						
							|  |  |  |      * Add zero-mean i.i.d. Gaussian prior terms to each variable | 
					
						
							|  |  |  |      * @param sigma Standard deviation of Gaussian | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2009-11-13 00:16:32 +08:00
										 |  |  |     GaussianFactorGraph add_priors(double sigma) const; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-29 02:46:01 +08:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Return RHS (b./sigmas) as Errors class | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     Errors rhs() const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Return (dense) matrix associated with factor graph | 
					
						
							|  |  |  |      * @param ordering of variables needed for matrix column order | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     std::pair<Matrix,Vector> matrix (const Ordering& ordering) const; | 
					
						
							| 
									
										
										
										
											2009-11-06 13:43:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-12 14:18:29 +08:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * get the starting column indices for all variables | 
					
						
							|  |  |  |      * @param ordering of variables needed for matrix column order | 
					
						
							|  |  |  |      * @return The set of all variable/index pairs | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     Dimensions columnIndices(const Ordering& ordering) const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-06 13:43:03 +08:00
										 |  |  |   	/**
 | 
					
						
							|  |  |  |   	 * Return 3*nzmax matrix where the rows correspond to the vectors i, j, and s | 
					
						
							|  |  |  |   	 * to generate an m-by-n sparse matrix, which can be given to MATLAB's sparse function. | 
					
						
							|  |  |  |   	 * The standard deviations are baked into A and b | 
					
						
							|  |  |  |   	 * @param ordering of variables needed for matrix column order | 
					
						
							|  |  |  |   	 */ | 
					
						
							|  |  |  |   	Matrix sparse(const Ordering& ordering) const; | 
					
						
							| 
									
										
										
										
											2009-12-11 04:19:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-11 12:59:05 +08:00
										 |  |  |   	/**
 | 
					
						
							|  |  |  |   	 * Take an optimal step in direction d by calculating optimal step-size | 
					
						
							|  |  |  |   	 * @param x: starting point for search | 
					
						
							|  |  |  |   	 * @param d: search direction | 
					
						
							|  |  |  |   	 */ | 
					
						
							|  |  |  |   	VectorConfig optimalUpdate(const VectorConfig& x0, const VectorConfig& d) const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   	/**
 | 
					
						
							| 
									
										
										
										
											2009-12-28 18:48:48 +08:00
										 |  |  | 		 * Find solution using gradient descent | 
					
						
							|  |  |  | 		 * @param x0: VectorConfig specifying initial estimate | 
					
						
							|  |  |  | 		 * @return solution | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2009-12-29 00:15:26 +08:00
										 |  |  | 		VectorConfig steepestDescent(const VectorConfig& x0, bool verbose = false, | 
					
						
							|  |  |  | 				double epsilon = 1e-3, size_t maxIterations = 0) const; | 
					
						
							| 
									
										
										
										
											2009-12-28 18:48:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/**
 | 
					
						
							|  |  |  | 		 * shared pointer versions for MATLAB | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		boost::shared_ptr<VectorConfig> | 
					
						
							| 
									
										
										
										
											2009-12-29 00:15:26 +08:00
										 |  |  | 		steepestDescent_(const VectorConfig& x0, bool verbose = false, | 
					
						
							|  |  |  | 				double epsilon = 1e-3, size_t maxIterations = 0) const; | 
					
						
							| 
									
										
										
										
											2009-12-28 18:48:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/**
 | 
					
						
							|  |  |  | 		 * Find solution using conjugate gradient descent | 
					
						
							|  |  |  | 		 * @param x0: VectorConfig specifying initial estimate | 
					
						
							|  |  |  | 		 * @return solution | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2009-12-29 00:15:26 +08:00
										 |  |  | 		VectorConfig conjugateGradientDescent(const VectorConfig& x0, bool verbose = | 
					
						
							|  |  |  | 				false, double epsilon = 1e-3, size_t maxIterations = 0) const; | 
					
						
							| 
									
										
										
										
											2009-12-28 18:48:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/**
 | 
					
						
							|  |  |  | 		 * shared pointer versions for MATLAB | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		boost::shared_ptr<VectorConfig> conjugateGradientDescent_( | 
					
						
							| 
									
										
										
										
											2009-12-29 00:15:26 +08:00
										 |  |  | 				const VectorConfig& x0, bool verbose = false, double epsilon = 1e-3, | 
					
						
							|  |  |  | 				size_t maxIterations = 0) const; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-18 13:51:19 +08:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * A linear system solver using factorization | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   template <class NonlinearGraph, class Config> | 
					
						
							|  |  |  |   class Factorization { | 
					
						
							|  |  |  |   public: | 
					
						
							|  |  |  |   	Factorization() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   	Factorization(const NonlinearGraph& g, const Config& config) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   	/**
 | 
					
						
							|  |  |  |   	 * solve for the optimal displacement in the tangent space, and then solve | 
					
						
							|  |  |  |   	 * the resulted linear system | 
					
						
							|  |  |  |   	 */ | 
					
						
							|  |  |  |   	VectorConfig optimize(GaussianFactorGraph& fg, const Ordering& ordering) const { | 
					
						
							|  |  |  |   		return fg.optimize(ordering); | 
					
						
							|  |  |  |   	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/**
 | 
					
						
							| 
									
										
										
										
											2010-01-19 18:46:12 +08:00
										 |  |  | 		 * linearize the non-linear graph around the current config | 
					
						
							| 
									
										
										
										
											2010-01-18 13:51:19 +08:00
										 |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2010-01-19 18:46:12 +08:00
										 |  |  |   	GaussianFactorGraph linearize(const NonlinearGraph& g, const Config& config) const { | 
					
						
							|  |  |  |   		return g.linearize(config); | 
					
						
							| 
									
										
										
										
											2010-01-18 13:51:19 +08:00
										 |  |  |   	} | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | } |