| 
									
										
										
										
											2010-10-14 12:54:38 +08:00
										 |  |  | /* ----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * GTSAM Copyright 2010, Georgia Tech Research Corporation,  | 
					
						
							|  |  |  |  * Atlanta, Georgia 30332-0415 | 
					
						
							|  |  |  |  * All Rights Reserved | 
					
						
							|  |  |  |  * Authors: Frank Dellaert, et al. (see THANKS for the full author list) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * See LICENSE for the license information | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * -------------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-13 00:41:18 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * @file NonlinearEquality.h | 
					
						
							|  |  |  |  * @brief Factor to handle enforced equality between factors | 
					
						
							|  |  |  |  * @author Alex Cunningham | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-13 14:15:48 +08:00
										 |  |  | #include <limits>
 | 
					
						
							| 
									
										
										
										
											2009-11-13 10:06:52 +08:00
										 |  |  | #include <iostream>
 | 
					
						
							| 
									
										
											  
											
												Large gtsam refactoring
To support faster development *and* better performance Richard and I pushed through a large refactoring of NonlinearFactors.
The following are the biggest changes:
1) NonLinearFactor1 and NonLinearFactor2 are now templated on Config, Key type, and X type, where X is the argument to the measurement function.
2) The measurement itself is no longer kept in the nonlinear factor. Instead, a derived class (see testVSLAMFactor, testNonlinearEquality, testPose3Factor etc...) has to implement a function to compute the errors, "evaluateErrors". Instead of (h(x)-z), it needs to return (z-h(x)), so Ax-b is an approximation of the error. IMPORTANT: evaluateErrors needs - if asked - *combine* the calculation of the function value h(x) and the derivatives dh(x)/dx. This was a major performance issue. To do this, boost::optional<Matrix&> arguments are provided, and tin EvaluateErrors you just  says something like
	if (H) *H = Matrix_(3,6,....);
3) We are no longer using int or strings for nonlinear factors. Instead, the preferred key type is now Symbol, defined in Key.h. This is both fast and cool: you can construct it from an int, and cast it to a strong. It also does type checking: a Symbol<Pose3,'x'> will not match a Symbol<Pose2,'x'>
4) minor: take a look at LieConfig.h: it help you avoid writing a lot of code bu automatically creating configs for a certain type. See e.g. Pose3Config.h. A "double" LieConfig is on the way - Thanks Richard and Manohar !
											
										 
											2010-01-14 06:25:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | #include <gtsam/nonlinear/Key.h>
 | 
					
						
							| 
									
										
										
										
											2010-08-20 01:23:19 +08:00
										 |  |  | #include <gtsam/nonlinear/NonlinearFactor.h>
 | 
					
						
							| 
									
										
										
										
											2009-11-13 00:41:18 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-11 03:25:19 +08:00
										 |  |  | 	/**
 | 
					
						
							| 
									
										
											  
											
												Large gtsam refactoring
To support faster development *and* better performance Richard and I pushed through a large refactoring of NonlinearFactors.
The following are the biggest changes:
1) NonLinearFactor1 and NonLinearFactor2 are now templated on Config, Key type, and X type, where X is the argument to the measurement function.
2) The measurement itself is no longer kept in the nonlinear factor. Instead, a derived class (see testVSLAMFactor, testNonlinearEquality, testPose3Factor etc...) has to implement a function to compute the errors, "evaluateErrors". Instead of (h(x)-z), it needs to return (z-h(x)), so Ax-b is an approximation of the error. IMPORTANT: evaluateErrors needs - if asked - *combine* the calculation of the function value h(x) and the derivatives dh(x)/dx. This was a major performance issue. To do this, boost::optional<Matrix&> arguments are provided, and tin EvaluateErrors you just  says something like
	if (H) *H = Matrix_(3,6,....);
3) We are no longer using int or strings for nonlinear factors. Instead, the preferred key type is now Symbol, defined in Key.h. This is both fast and cool: you can construct it from an int, and cast it to a strong. It also does type checking: a Symbol<Pose3,'x'> will not match a Symbol<Pose2,'x'>
4) minor: take a look at LieConfig.h: it help you avoid writing a lot of code bu automatically creating configs for a certain type. See e.g. Pose3Config.h. A "double" LieConfig is on the way - Thanks Richard and Manohar !
											
										 
											2010-01-14 06:25:03 +08:00
										 |  |  | 	 * Template default compare function that assumes a testable T | 
					
						
							| 
									
										
										
										
											2010-01-11 03:25:19 +08:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
											  
											
												Large gtsam refactoring
To support faster development *and* better performance Richard and I pushed through a large refactoring of NonlinearFactors.
The following are the biggest changes:
1) NonLinearFactor1 and NonLinearFactor2 are now templated on Config, Key type, and X type, where X is the argument to the measurement function.
2) The measurement itself is no longer kept in the nonlinear factor. Instead, a derived class (see testVSLAMFactor, testNonlinearEquality, testPose3Factor etc...) has to implement a function to compute the errors, "evaluateErrors". Instead of (h(x)-z), it needs to return (z-h(x)), so Ax-b is an approximation of the error. IMPORTANT: evaluateErrors needs - if asked - *combine* the calculation of the function value h(x) and the derivatives dh(x)/dx. This was a major performance issue. To do this, boost::optional<Matrix&> arguments are provided, and tin EvaluateErrors you just  says something like
	if (H) *H = Matrix_(3,6,....);
3) We are no longer using int or strings for nonlinear factors. Instead, the preferred key type is now Symbol, defined in Key.h. This is both fast and cool: you can construct it from an int, and cast it to a strong. It also does type checking: a Symbol<Pose3,'x'> will not match a Symbol<Pose2,'x'>
4) minor: take a look at LieConfig.h: it help you avoid writing a lot of code bu automatically creating configs for a certain type. See e.g. Pose3Config.h. A "double" LieConfig is on the way - Thanks Richard and Manohar !
											
										 
											2010-01-14 06:25:03 +08:00
										 |  |  | 	template<class T> | 
					
						
							| 
									
										
										
										
											2010-07-09 05:30:19 +08:00
										 |  |  | 	bool compare(const T& a, const T& b) { return a.equals(b); } | 
					
						
							| 
									
										
										
										
											2009-11-13 10:06:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/**
 | 
					
						
							| 
									
										
										
										
											2010-01-11 03:25:19 +08:00
										 |  |  | 	 * An equality factor that forces either one variable to a constant, | 
					
						
							|  |  |  | 	 * or a set of variables to be equal to each other. | 
					
						
							| 
									
										
										
										
											2010-07-09 05:30:19 +08:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * Depending on flag, throws an error at linearization if the constraints are not met. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * Switchable implementation: | 
					
						
							|  |  |  | 	 *   - ALLLOW_ERROR : if we allow that there can be nonzero error, does not throw, and uses gain | 
					
						
							|  |  |  | 	 *   - ONLY_EXACT   : throws error at linearization if not at exact feasible point, and infinite error | 
					
						
							| 
									
										
										
										
											2009-11-13 10:06:52 +08:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2010-10-21 00:37:47 +08:00
										 |  |  | 	template<class VALUES, class KEY> | 
					
						
							|  |  |  | 	class NonlinearEquality: public NonlinearFactor1<VALUES, KEY> { | 
					
						
							| 
									
										
										
										
											2010-08-24 03:44:17 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	public: | 
					
						
							| 
									
										
										
										
											2010-10-21 00:37:47 +08:00
										 |  |  | 		typedef typename KEY::Value T; | 
					
						
							| 
									
										
										
										
											2010-08-24 03:44:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-11 03:25:19 +08:00
										 |  |  | 	private: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Large gtsam refactoring
To support faster development *and* better performance Richard and I pushed through a large refactoring of NonlinearFactors.
The following are the biggest changes:
1) NonLinearFactor1 and NonLinearFactor2 are now templated on Config, Key type, and X type, where X is the argument to the measurement function.
2) The measurement itself is no longer kept in the nonlinear factor. Instead, a derived class (see testVSLAMFactor, testNonlinearEquality, testPose3Factor etc...) has to implement a function to compute the errors, "evaluateErrors". Instead of (h(x)-z), it needs to return (z-h(x)), so Ax-b is an approximation of the error. IMPORTANT: evaluateErrors needs - if asked - *combine* the calculation of the function value h(x) and the derivatives dh(x)/dx. This was a major performance issue. To do this, boost::optional<Matrix&> arguments are provided, and tin EvaluateErrors you just  says something like
	if (H) *H = Matrix_(3,6,....);
3) We are no longer using int or strings for nonlinear factors. Instead, the preferred key type is now Symbol, defined in Key.h. This is both fast and cool: you can construct it from an int, and cast it to a strong. It also does type checking: a Symbol<Pose3,'x'> will not match a Symbol<Pose2,'x'>
4) minor: take a look at LieConfig.h: it help you avoid writing a lot of code bu automatically creating configs for a certain type. See e.g. Pose3Config.h. A "double" LieConfig is on the way - Thanks Richard and Manohar !
											
										 
											2010-01-14 06:25:03 +08:00
										 |  |  | 		// feasible value
 | 
					
						
							|  |  |  | 		T feasible_; | 
					
						
							| 
									
										
										
										
											2010-01-11 03:25:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-09 05:30:19 +08:00
										 |  |  | 		// error handling flag
 | 
					
						
							|  |  |  | 		bool allow_error_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// error gain in allow error case
 | 
					
						
							|  |  |  | 		double error_gain_; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-11 03:25:19 +08:00
										 |  |  | 	public: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/**
 | 
					
						
							| 
									
										
											  
											
												Large gtsam refactoring
To support faster development *and* better performance Richard and I pushed through a large refactoring of NonlinearFactors.
The following are the biggest changes:
1) NonLinearFactor1 and NonLinearFactor2 are now templated on Config, Key type, and X type, where X is the argument to the measurement function.
2) The measurement itself is no longer kept in the nonlinear factor. Instead, a derived class (see testVSLAMFactor, testNonlinearEquality, testPose3Factor etc...) has to implement a function to compute the errors, "evaluateErrors". Instead of (h(x)-z), it needs to return (z-h(x)), so Ax-b is an approximation of the error. IMPORTANT: evaluateErrors needs - if asked - *combine* the calculation of the function value h(x) and the derivatives dh(x)/dx. This was a major performance issue. To do this, boost::optional<Matrix&> arguments are provided, and tin EvaluateErrors you just  says something like
	if (H) *H = Matrix_(3,6,....);
3) We are no longer using int or strings for nonlinear factors. Instead, the preferred key type is now Symbol, defined in Key.h. This is both fast and cool: you can construct it from an int, and cast it to a strong. It also does type checking: a Symbol<Pose3,'x'> will not match a Symbol<Pose2,'x'>
4) minor: take a look at LieConfig.h: it help you avoid writing a lot of code bu automatically creating configs for a certain type. See e.g. Pose3Config.h. A "double" LieConfig is on the way - Thanks Richard and Manohar !
											
										 
											2010-01-14 06:25:03 +08:00
										 |  |  | 		 * Function that compares two values | 
					
						
							| 
									
										
										
										
											2010-01-11 03:25:19 +08:00
										 |  |  | 		 */ | 
					
						
							| 
									
										
											  
											
												Large gtsam refactoring
To support faster development *and* better performance Richard and I pushed through a large refactoring of NonlinearFactors.
The following are the biggest changes:
1) NonLinearFactor1 and NonLinearFactor2 are now templated on Config, Key type, and X type, where X is the argument to the measurement function.
2) The measurement itself is no longer kept in the nonlinear factor. Instead, a derived class (see testVSLAMFactor, testNonlinearEquality, testPose3Factor etc...) has to implement a function to compute the errors, "evaluateErrors". Instead of (h(x)-z), it needs to return (z-h(x)), so Ax-b is an approximation of the error. IMPORTANT: evaluateErrors needs - if asked - *combine* the calculation of the function value h(x) and the derivatives dh(x)/dx. This was a major performance issue. To do this, boost::optional<Matrix&> arguments are provided, and tin EvaluateErrors you just  says something like
	if (H) *H = Matrix_(3,6,....);
3) We are no longer using int or strings for nonlinear factors. Instead, the preferred key type is now Symbol, defined in Key.h. This is both fast and cool: you can construct it from an int, and cast it to a strong. It also does type checking: a Symbol<Pose3,'x'> will not match a Symbol<Pose2,'x'>
4) minor: take a look at LieConfig.h: it help you avoid writing a lot of code bu automatically creating configs for a certain type. See e.g. Pose3Config.h. A "double" LieConfig is on the way - Thanks Richard and Manohar !
											
										 
											2010-01-14 06:25:03 +08:00
										 |  |  | 		bool (*compare_)(const T& a, const T& b); | 
					
						
							| 
									
										
										
										
											2010-01-11 03:25:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-21 00:37:47 +08:00
										 |  |  | 		typedef NonlinearFactor1<VALUES, KEY> Base; | 
					
						
							| 
									
										
										
										
											2009-11-13 10:06:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-11 03:25:19 +08:00
										 |  |  | 		/**
 | 
					
						
							| 
									
										
										
										
											2010-07-09 05:30:19 +08:00
										 |  |  | 		 * Constructor - forces exact evaluation | 
					
						
							| 
									
										
										
										
											2010-01-11 03:25:19 +08:00
										 |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2010-10-21 00:37:47 +08:00
										 |  |  | 		NonlinearEquality(const KEY& j, const T& feasible, bool (*compare)(const T&, const T&) = compare<T>) : | 
					
						
							| 
									
										
										
										
											2010-08-27 03:55:40 +08:00
										 |  |  | 			Base(noiseModel::Constrained::All(feasible.dim()), j), feasible_(feasible), | 
					
						
							| 
									
										
										
										
											2010-07-09 05:30:19 +08:00
										 |  |  | 			allow_error_(false), error_gain_(std::numeric_limits<double>::infinity()), | 
					
						
							|  |  |  | 			compare_(compare) { | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/**
 | 
					
						
							|  |  |  | 		 * Constructor - allows inexact evaluation | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2010-10-21 00:37:47 +08:00
										 |  |  | 		NonlinearEquality(const KEY& j, const T& feasible, double error_gain, bool (*compare)(const T&, const T&) = compare<T>) : | 
					
						
							| 
									
										
										
										
											2010-08-27 03:55:40 +08:00
										 |  |  | 			Base(noiseModel::Constrained::All(feasible.dim()), j), feasible_(feasible), | 
					
						
							| 
									
										
										
										
											2010-07-09 05:30:19 +08:00
										 |  |  | 			allow_error_(true), error_gain_(error_gain), | 
					
						
							|  |  |  | 			compare_(compare) { | 
					
						
							| 
									
										
										
										
											2010-01-11 03:25:19 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-11-13 10:06:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-11 03:25:19 +08:00
										 |  |  | 		void print(const std::string& s = "") const { | 
					
						
							| 
									
										
											  
											
												Large gtsam refactoring
To support faster development *and* better performance Richard and I pushed through a large refactoring of NonlinearFactors.
The following are the biggest changes:
1) NonLinearFactor1 and NonLinearFactor2 are now templated on Config, Key type, and X type, where X is the argument to the measurement function.
2) The measurement itself is no longer kept in the nonlinear factor. Instead, a derived class (see testVSLAMFactor, testNonlinearEquality, testPose3Factor etc...) has to implement a function to compute the errors, "evaluateErrors". Instead of (h(x)-z), it needs to return (z-h(x)), so Ax-b is an approximation of the error. IMPORTANT: evaluateErrors needs - if asked - *combine* the calculation of the function value h(x) and the derivatives dh(x)/dx. This was a major performance issue. To do this, boost::optional<Matrix&> arguments are provided, and tin EvaluateErrors you just  says something like
	if (H) *H = Matrix_(3,6,....);
3) We are no longer using int or strings for nonlinear factors. Instead, the preferred key type is now Symbol, defined in Key.h. This is both fast and cool: you can construct it from an int, and cast it to a strong. It also does type checking: a Symbol<Pose3,'x'> will not match a Symbol<Pose2,'x'>
4) minor: take a look at LieConfig.h: it help you avoid writing a lot of code bu automatically creating configs for a certain type. See e.g. Pose3Config.h. A "double" LieConfig is on the way - Thanks Richard and Manohar !
											
										 
											2010-01-14 06:25:03 +08:00
										 |  |  | 			std::cout << "Constraint: " << s << " on [" << (std::string)(this->key_) << "]\n"; | 
					
						
							|  |  |  | 			gtsam::print(feasible_,"Feasible Point"); | 
					
						
							| 
									
										
										
										
											2010-08-27 03:55:40 +08:00
										 |  |  | 			std::cout << "Variable Dimension: " << feasible_.dim() << std::endl; | 
					
						
							| 
									
										
										
										
											2010-01-11 03:25:19 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-11-13 10:06:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-11 03:25:19 +08:00
										 |  |  | 		/** Check if two factors are equal */ | 
					
						
							| 
									
										
										
										
											2010-10-21 00:37:47 +08:00
										 |  |  | 		bool equals(const NonlinearEquality<VALUES,KEY>& f, double tol = 1e-9) const { | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 			if (!Base::equals(f)) return false; | 
					
						
							|  |  |  | 			return compare_(feasible_, f.feasible_); | 
					
						
							| 
									
										
										
										
											2010-01-11 03:25:19 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-11-13 10:06:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-09 05:30:19 +08:00
										 |  |  | 		/** actual error function calculation */ | 
					
						
							| 
									
										
										
										
											2010-10-21 00:37:47 +08:00
										 |  |  | 		virtual double error(const VALUES& c) const { | 
					
						
							| 
									
										
										
										
											2010-07-09 05:30:19 +08:00
										 |  |  | 			const T& xj = c[this->key_]; | 
					
						
							|  |  |  | 			Vector e = this->unwhitenedError(c); | 
					
						
							|  |  |  | 			if (allow_error_ || !compare_(xj, feasible_)) { | 
					
						
							|  |  |  | 				return error_gain_ * inner_prod(e,e); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				return 0.0; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-11 03:25:19 +08:00
										 |  |  | 		/** error function */ | 
					
						
							| 
									
										
										
										
											2010-07-09 05:30:19 +08:00
										 |  |  | 		inline Vector evaluateError(const T& xj, boost::optional<Matrix&> H = boost::none) const { | 
					
						
							| 
									
										
										
										
											2010-08-27 03:55:40 +08:00
										 |  |  | 			size_t nj = feasible_.dim(); | 
					
						
							| 
									
										
										
										
											2010-07-09 05:30:19 +08:00
										 |  |  | 			if (allow_error_) { | 
					
						
							|  |  |  | 				if (H) *H = eye(nj); // FIXME: this is not the right linearization for nonlinear compare
 | 
					
						
							| 
									
										
										
										
											2010-08-27 03:55:40 +08:00
										 |  |  | 				return xj.logmap(feasible_); | 
					
						
							| 
									
										
										
										
											2010-07-09 05:30:19 +08:00
										 |  |  | 			} else if (compare_(feasible_,xj)) { | 
					
						
							| 
									
										
											  
											
												Large gtsam refactoring
To support faster development *and* better performance Richard and I pushed through a large refactoring of NonlinearFactors.
The following are the biggest changes:
1) NonLinearFactor1 and NonLinearFactor2 are now templated on Config, Key type, and X type, where X is the argument to the measurement function.
2) The measurement itself is no longer kept in the nonlinear factor. Instead, a derived class (see testVSLAMFactor, testNonlinearEquality, testPose3Factor etc...) has to implement a function to compute the errors, "evaluateErrors". Instead of (h(x)-z), it needs to return (z-h(x)), so Ax-b is an approximation of the error. IMPORTANT: evaluateErrors needs - if asked - *combine* the calculation of the function value h(x) and the derivatives dh(x)/dx. This was a major performance issue. To do this, boost::optional<Matrix&> arguments are provided, and tin EvaluateErrors you just  says something like
	if (H) *H = Matrix_(3,6,....);
3) We are no longer using int or strings for nonlinear factors. Instead, the preferred key type is now Symbol, defined in Key.h. This is both fast and cool: you can construct it from an int, and cast it to a strong. It also does type checking: a Symbol<Pose3,'x'> will not match a Symbol<Pose2,'x'>
4) minor: take a look at LieConfig.h: it help you avoid writing a lot of code bu automatically creating configs for a certain type. See e.g. Pose3Config.h. A "double" LieConfig is on the way - Thanks Richard and Manohar !
											
										 
											2010-01-14 06:25:03 +08:00
										 |  |  | 				if (H) *H = eye(nj); | 
					
						
							|  |  |  | 				return zero(nj); // set error to zero if equal
 | 
					
						
							| 
									
										
										
										
											2010-01-11 03:25:19 +08:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
											  
											
												Large gtsam refactoring
To support faster development *and* better performance Richard and I pushed through a large refactoring of NonlinearFactors.
The following are the biggest changes:
1) NonLinearFactor1 and NonLinearFactor2 are now templated on Config, Key type, and X type, where X is the argument to the measurement function.
2) The measurement itself is no longer kept in the nonlinear factor. Instead, a derived class (see testVSLAMFactor, testNonlinearEquality, testPose3Factor etc...) has to implement a function to compute the errors, "evaluateErrors". Instead of (h(x)-z), it needs to return (z-h(x)), so Ax-b is an approximation of the error. IMPORTANT: evaluateErrors needs - if asked - *combine* the calculation of the function value h(x) and the derivatives dh(x)/dx. This was a major performance issue. To do this, boost::optional<Matrix&> arguments are provided, and tin EvaluateErrors you just  says something like
	if (H) *H = Matrix_(3,6,....);
3) We are no longer using int or strings for nonlinear factors. Instead, the preferred key type is now Symbol, defined in Key.h. This is both fast and cool: you can construct it from an int, and cast it to a strong. It also does type checking: a Symbol<Pose3,'x'> will not match a Symbol<Pose2,'x'>
4) minor: take a look at LieConfig.h: it help you avoid writing a lot of code bu automatically creating configs for a certain type. See e.g. Pose3Config.h. A "double" LieConfig is on the way - Thanks Richard and Manohar !
											
										 
											2010-01-14 06:25:03 +08:00
										 |  |  | 				if (H) throw std::invalid_argument( | 
					
						
							|  |  |  | 						"Linearization point not feasible for " + (std::string)(this->key_) + "!"); | 
					
						
							|  |  |  | 				return repeat(nj, std::numeric_limits<double>::infinity()); // set error to infinity if not equal
 | 
					
						
							| 
									
										
										
										
											2010-01-11 03:25:19 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-11-13 10:06:52 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-01-18 13:38:53 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Linearize is over-written, because base linearization tries to whiten
 | 
					
						
							| 
									
										
										
										
											2010-10-21 00:37:47 +08:00
										 |  |  | 		virtual boost::shared_ptr<GaussianFactor> linearize(const VALUES& x, const Ordering& ordering) const { | 
					
						
							| 
									
										
										
										
											2010-01-18 13:38:53 +08:00
										 |  |  | 			const T& xj = x[this->key_]; | 
					
						
							|  |  |  | 			Matrix A; | 
					
						
							| 
									
										
										
										
											2010-07-10 01:08:35 +08:00
										 |  |  | 			Vector b = evaluateError(xj, A); | 
					
						
							| 
									
										
										
										
											2010-01-18 13:38:53 +08:00
										 |  |  | 			// TODO pass unwhitened + noise model to Gaussian factor
 | 
					
						
							| 
									
										
										
										
											2010-01-23 01:36:57 +08:00
										 |  |  | 			SharedDiagonal model = noiseModel::Constrained::All(b.size()); | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 			return	GaussianFactor::shared_ptr(new GaussianFactor(ordering[this->key_], A, b, model)); | 
					
						
							| 
									
										
										
										
											2010-01-18 13:38:53 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-11 03:25:19 +08:00
										 |  |  | 	}; // NonlinearEquality
 | 
					
						
							| 
									
										
										
										
											2009-11-13 00:41:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-11 03:25:19 +08:00
										 |  |  | } // namespace gtsam
 | 
					
						
							| 
									
										
										
										
											2009-11-13 00:41:18 +08:00
										 |  |  | 
 |