| 
									
										
										
										
											2009-09-09 12:43:04 +08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * NonlinearOptimizer.h | 
					
						
							|  |  |  |  * @brief: Encapsulates nonlinear optimization state | 
					
						
							|  |  |  |  * @Author: Frank Dellaert | 
					
						
							|  |  |  |  * Created on: Sep 7, 2009 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef NONLINEAROPTIMIZER_H_
 | 
					
						
							|  |  |  | #define NONLINEAROPTIMIZER_H_
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <boost/shared_ptr.hpp>
 | 
					
						
							|  |  |  | #include "NonlinearFactorGraph.h"
 | 
					
						
							| 
									
										
										
										
											2009-10-15 04:39:59 +08:00
										 |  |  | #include "VectorConfig.h"
 | 
					
						
							| 
									
										
										
										
											2009-09-09 12:43:04 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/**
 | 
					
						
							|  |  |  | 	 * The class NonlinearOptimizer encapsulates an optimization state. | 
					
						
							|  |  |  | 	 * Typically it is instantiated with a NonlinearFactorGraph and an initial config | 
					
						
							|  |  |  | 	 * and then one of the optimization routines is called. These recursively iterate | 
					
						
							|  |  |  | 	 * until convergence. All methods are functional and return a new state. | 
					
						
							|  |  |  | 	 * | 
					
						
							| 
									
										
										
										
											2009-10-20 03:12:48 +08:00
										 |  |  | 	 * The class is parameterized by the Graph type and Config class type, the latter | 
					
						
							|  |  |  | 	 * in order to be able to optimize over non-vector configurations as well. | 
					
						
							|  |  |  | 	 * To use in code, include <gtsam/NonlinearOptimizer-inl.h> in your cpp file | 
					
						
							| 
									
										
										
										
											2009-09-09 12:43:04 +08:00
										 |  |  | 	 * (the trick in http://www.ddj.com/cpp/184403420 did not work).
 | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	template<class FactorGraph, class Config> | 
					
						
							|  |  |  | 	class NonlinearOptimizer { | 
					
						
							|  |  |  | 	public: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// For performance reasons in recursion, we store configs in a shared_ptr
 | 
					
						
							|  |  |  | 		typedef boost::shared_ptr<const Config> shared_config; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		enum verbosityLevel { | 
					
						
							|  |  |  | 			SILENT, | 
					
						
							|  |  |  | 			ERROR, | 
					
						
							|  |  |  | 			LAMBDA, | 
					
						
							|  |  |  | 			CONFIG, | 
					
						
							|  |  |  | 			DELTA, | 
					
						
							|  |  |  | 			LINEAR, | 
					
						
							|  |  |  | 			TRYLAMBDA, | 
					
						
							|  |  |  | 			TRYCONFIG, | 
					
						
							|  |  |  | 			TRYDELTA, | 
					
						
							|  |  |  | 			DAMPED | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	private: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// keep a reference to const versions of the graph and ordering
 | 
					
						
							|  |  |  | 		// These normally do not change
 | 
					
						
							|  |  |  | 		const FactorGraph* graph_; | 
					
						
							|  |  |  | 		const Ordering* ordering_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// keep a configuration and its error
 | 
					
						
							|  |  |  | 		// These typically change once per iteration (in a functional way)
 | 
					
						
							|  |  |  | 		shared_config config_; | 
					
						
							|  |  |  | 		double error_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// keep current lambda for use within LM only
 | 
					
						
							|  |  |  | 		// TODO: red flag, should we have an LM class ?
 | 
					
						
							|  |  |  | 		double lambda_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Recursively try to do tempered Gauss-Newton steps until we succeed
 | 
					
						
							| 
									
										
										
										
											2009-11-13 00:16:32 +08:00
										 |  |  | 		NonlinearOptimizer try_lambda(const GaussianFactorGraph& linear, | 
					
						
							| 
									
										
										
										
											2009-09-09 12:43:04 +08:00
										 |  |  | 				verbosityLevel verbosity, double factor) const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/**
 | 
					
						
							|  |  |  | 		 * Constructor | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		NonlinearOptimizer(const FactorGraph& graph, const Ordering& ordering, | 
					
						
							|  |  |  | 				shared_config config, double lambda = 1e-5); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/**
 | 
					
						
							|  |  |  | 		 * Return current error | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		double error() const { | 
					
						
							|  |  |  | 			return error_; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/**
 | 
					
						
							|  |  |  | 		 * Return current lambda | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		double lambda() const { | 
					
						
							|  |  |  | 			return lambda_; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-11 06:08:47 +08:00
										 |  |  | 		/**
 | 
					
						
							|  |  |  | 		 * Return the config | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2009-09-12 02:33:05 +08:00
										 |  |  | 		shared_config config() const{ | 
					
						
							| 
									
										
										
										
											2009-09-11 06:08:47 +08:00
										 |  |  | 			return config_; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-09 12:43:04 +08:00
										 |  |  | 		/**
 | 
					
						
							|  |  |  | 		 *  linearize and optimize | 
					
						
							| 
									
										
										
										
											2009-10-20 03:12:48 +08:00
										 |  |  | 		 *  This returns an VectorConfig, i.e., vectors in tangent space of Config | 
					
						
							| 
									
										
										
										
											2009-09-09 12:43:04 +08:00
										 |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2009-10-20 03:12:48 +08:00
										 |  |  | 		VectorConfig linearizeAndOptimizeForDelta() const; | 
					
						
							| 
									
										
										
										
											2009-09-09 12:43:04 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/**
 | 
					
						
							|  |  |  | 		 * Do one Gauss-Newton iteration and return next state | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		NonlinearOptimizer iterate(verbosityLevel verbosity = SILENT) const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/**
 | 
					
						
							|  |  |  | 		 * Optimize a solution for a non linear factor graph | 
					
						
							|  |  |  | 		 * @param relativeTreshold | 
					
						
							|  |  |  | 		 * @param absoluteTreshold | 
					
						
							|  |  |  | 		 * @param verbosity Integer specifying how much output to provide | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		NonlinearOptimizer | 
					
						
							|  |  |  | 		gaussNewton(double relativeThreshold, double absoluteThreshold, | 
					
						
							|  |  |  | 				verbosityLevel verbosity = SILENT, int maxIterations = 100) const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/**
 | 
					
						
							|  |  |  | 		 * One iteration of Levenberg Marquardt | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		NonlinearOptimizer iterateLM(verbosityLevel verbosity = SILENT, | 
					
						
							|  |  |  | 				double lambdaFactor = 10) const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/**
 | 
					
						
							|  |  |  | 		 * Optimize using Levenberg-Marquardt. Really Levenberg's | 
					
						
							|  |  |  | 		 * algorithm at this moment, as we just add I*\lambda to Hessian | 
					
						
							|  |  |  | 		 * H'H. The probabilistic explanation is very simple: every | 
					
						
							|  |  |  | 		 * variable gets an extra Gaussian prior that biases staying at | 
					
						
							|  |  |  | 		 * current value, with variance 1/lambda. This is done very easily | 
					
						
							|  |  |  | 		 * (but perhaps wastefully) by adding a prior factor for each of | 
					
						
							|  |  |  | 		 * the variables, after linearization. | 
					
						
							|  |  |  | 		 * | 
					
						
							|  |  |  | 		 * @param relativeThreshold | 
					
						
							|  |  |  | 		 * @param absoluteThreshold | 
					
						
							|  |  |  | 		 * @param verbosity    Integer specifying how much output to provide | 
					
						
							|  |  |  | 		 * @param lambdaFactor Factor by which to decrease/increase lambda | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		NonlinearOptimizer | 
					
						
							|  |  |  | 		levenbergMarquardt(double relativeThreshold, double absoluteThreshold, | 
					
						
							|  |  |  | 				verbosityLevel verbosity = SILENT, int maxIterations = 100, | 
					
						
							|  |  |  | 				double lambdaFactor = 10) const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-07 02:25:04 +08:00
										 |  |  | 	/**
 | 
					
						
							|  |  |  | 	 * Check convergence | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	bool check_convergence (double relativeErrorTreshold, | 
					
						
							|  |  |  | 			double absoluteErrorTreshold, | 
					
						
							|  |  |  | 			double currentError, double newError, | 
					
						
							|  |  |  | 			int verbosity); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // gtsam
 | 
					
						
							| 
									
										
										
										
											2009-09-09 12:43:04 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #endif /* NONLINEAROPTIMIZER_H_ */
 |