| 
									
										
										
										
											2012-07-11 02:15:51 +08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * @file LinearContainerFactor.h | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @brief Wrap Jacobian and Hessian linear factors to allow simple injection into a nonlinear graph | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * @date Jul 6, 2012 | 
					
						
							|  |  |  |  * @author Alex Cunningham | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <gtsam/linear/HessianFactor.h>
 | 
					
						
							| 
									
										
										
										
											2012-08-22 02:48:04 +08:00
										 |  |  | #include <gtsam/nonlinear/NonlinearFactorGraph.h>
 | 
					
						
							| 
									
										
										
										
											2012-07-11 02:15:51 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Dummy version of a generic linear factor to be injected into a nonlinear factor graph | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class LinearContainerFactor : public NonlinearFactor { | 
					
						
							|  |  |  | protected: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	GaussianFactor::shared_ptr factor_; | 
					
						
							| 
									
										
										
										
											2012-08-27 09:11:37 +08:00
										 |  |  | 	boost::optional<Values> linearizationPoint_; | 
					
						
							| 
									
										
										
										
											2012-07-11 02:15:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-03 11:06:08 +08:00
										 |  |  | 	/** direct copy constructor */ | 
					
						
							|  |  |  | 	LinearContainerFactor(const GaussianFactor::shared_ptr& factor, | 
					
						
							|  |  |  | 			const boost::optional<Values>& linearizationPoint) | 
					
						
							|  |  |  | 	: factor_(factor), linearizationPoint_(linearizationPoint) {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-11 02:15:51 +08:00
										 |  |  | public: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** Primary constructor: store a linear factor and decode the ordering */ | 
					
						
							| 
									
										
										
										
											2012-08-27 09:11:37 +08:00
										 |  |  | 	LinearContainerFactor(const JacobianFactor& factor, const Ordering& ordering, | 
					
						
							|  |  |  | 			const Values& linearizationPoint = Values()); | 
					
						
							| 
									
										
										
										
											2012-07-11 02:15:51 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/** Primary constructor: store a linear factor and decode the ordering */ | 
					
						
							| 
									
										
										
										
											2012-08-27 09:11:37 +08:00
										 |  |  | 	LinearContainerFactor(const HessianFactor& factor, const Ordering& ordering, | 
					
						
							|  |  |  | 			const Values& linearizationPoint = Values()); | 
					
						
							| 
									
										
										
										
											2012-07-11 02:15:51 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/** Constructor from shared_ptr */ | 
					
						
							| 
									
										
										
										
											2012-08-27 09:11:37 +08:00
										 |  |  | 	LinearContainerFactor(const GaussianFactor::shared_ptr& factor, const Ordering& ordering, | 
					
						
							|  |  |  | 			const Values& linearizationPoint = Values()); | 
					
						
							| 
									
										
										
										
											2012-07-11 02:15:51 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/** Constructor from re-keyed factor: all indices assumed replaced with Key */ | 
					
						
							| 
									
										
										
										
											2012-08-27 09:11:37 +08:00
										 |  |  | 	LinearContainerFactor(const GaussianFactor::shared_ptr& factor, | 
					
						
							|  |  |  | 			const Values& linearizationPoint = Values()); | 
					
						
							| 
									
										
										
										
											2012-07-11 02:15:51 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/** Alternate constructor: store a linear factor and decode keys with inverted ordering*/ | 
					
						
							|  |  |  | 	LinearContainerFactor(const JacobianFactor& factor, | 
					
						
							| 
									
										
										
										
											2012-08-27 09:11:37 +08:00
										 |  |  | 			const Ordering::InvertedMap& inverted_ordering, | 
					
						
							|  |  |  | 			const Values& linearizationPoint = Values()); | 
					
						
							| 
									
										
										
										
											2012-07-11 02:15:51 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/** Alternate constructor: store a linear factor and decode keys with inverted ordering*/ | 
					
						
							|  |  |  | 	LinearContainerFactor(const HessianFactor& factor, | 
					
						
							| 
									
										
										
										
											2012-08-27 09:11:37 +08:00
										 |  |  | 			const Ordering::InvertedMap& inverted_ordering, | 
					
						
							|  |  |  | 			const Values& linearizationPoint = Values()); | 
					
						
							| 
									
										
										
										
											2012-07-11 02:15:51 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/** Constructor from shared_ptr with inverted ordering*/ | 
					
						
							|  |  |  | 	LinearContainerFactor(const GaussianFactor::shared_ptr& factor, | 
					
						
							| 
									
										
										
										
											2012-08-27 09:11:37 +08:00
										 |  |  | 			const Ordering::InvertedMap& ordering, | 
					
						
							|  |  |  | 			const Values& linearizationPoint = Values()); | 
					
						
							| 
									
										
										
										
											2012-07-11 02:15:51 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Access
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const GaussianFactor::shared_ptr& factor() const { return factor_; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Testable
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** print */ | 
					
						
							|  |  |  |   void print(const std::string& s = "", const KeyFormatter& keyFormatter = gtsam::DefaultKeyFormatter) const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** Check if two factors are equal */ | 
					
						
							|  |  |  |   bool equals(const NonlinearFactor& f, double tol = 1e-9) const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// NonlinearFactor
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Calculate the error of the factor: uses the underlying linear factor to compute ordering | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   double error(const Values& c) const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** get the dimension of the factor: rows of linear factor */ | 
					
						
							|  |  |  |   size_t dim() const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-27 09:11:37 +08:00
										 |  |  |   /** Extract the linearization point used in recalculating error */ | 
					
						
							|  |  |  | 	const boost::optional<Values>& linearizationPoint() const { return linearizationPoint_; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-22 02:48:04 +08:00
										 |  |  |   /** Apply the ordering to a graph - same as linearize(), but without needing a linearization point */ | 
					
						
							|  |  |  |   GaussianFactor::shared_ptr order(const Ordering& ordering) const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-11 02:15:51 +08:00
										 |  |  |   /** linearize to a GaussianFactor: values has no effect, just clones/rekeys underlying factor */ | 
					
						
							| 
									
										
										
										
											2012-08-22 02:48:04 +08:00
										 |  |  |   GaussianFactor::shared_ptr linearize(const Values& c, const Ordering& ordering) const; | 
					
						
							| 
									
										
										
										
											2012-07-11 02:15:51 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Creates an anti-factor directly and performs rekeying due to ordering | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   GaussianFactor::shared_ptr negate(const Ordering& ordering) const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-21 02:28:19 +08:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Creates the equivalent anti-factor as another LinearContainerFactor, | 
					
						
							|  |  |  |    * so it remains independent of ordering. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   NonlinearFactor::shared_ptr negate() const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-11 02:15:51 +08:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Creates a shared_ptr clone of the factor - needs to be specialized to allow | 
					
						
							|  |  |  |    * for subclasses | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * Clones the underlying linear factor | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   NonlinearFactor::shared_ptr clone() const { | 
					
						
							| 
									
										
										
										
											2012-09-03 11:06:08 +08:00
										 |  |  |   	return NonlinearFactor::shared_ptr(new LinearContainerFactor(factor_,linearizationPoint_)); | 
					
						
							| 
									
										
										
										
											2012-07-11 02:15:51 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // casting syntactic sugar
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Simple check whether this is a Jacobian or Hessian factor | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   bool isJacobian() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** Casts to JacobianFactor */ | 
					
						
							|  |  |  |   JacobianFactor::shared_ptr toJacobian() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** Casts to HessianFactor */ | 
					
						
							|  |  |  |   HessianFactor::shared_ptr toHessian() const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-22 02:48:04 +08:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Utility function for converting linear graphs to nonlinear graphs | 
					
						
							|  |  |  |    * consisting of LinearContainerFactors.  Two versions are available, using | 
					
						
							|  |  |  |    * either the ordering the linear graph was linearized around, or the inverse ordering. | 
					
						
							|  |  |  |    * If the inverse ordering is present, it will be faster. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   static NonlinearFactorGraph convertLinearGraph(const GaussianFactorGraph& linear_graph, | 
					
						
							|  |  |  |   		const Ordering& ordering); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   static NonlinearFactorGraph convertLinearGraph(const GaussianFactorGraph& linear_graph, | 
					
						
							|  |  |  |   		const InvertedOrdering& invOrdering); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-11 02:15:51 +08:00
										 |  |  | protected: | 
					
						
							|  |  |  |   void rekeyFactor(const Ordering& ordering); | 
					
						
							|  |  |  |   void rekeyFactor(const Ordering::InvertedMap& invOrdering); | 
					
						
							| 
									
										
										
										
											2012-08-27 09:11:37 +08:00
										 |  |  |   void initializeLinearizationPoint(const Values& linearizationPoint); | 
					
						
							| 
									
										
										
										
											2012-07-11 02:15:51 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | }; // \class LinearContainerFactor
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // \namespace gtsam
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 |