| 
									
										
										
										
											2014-12-23 08:49:32 +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 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * -------------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2015-02-25 12:40:53 +08:00
										 |  |  |  * @file    LinearConstraintSQP.h | 
					
						
							| 
									
										
										
										
											2014-12-23 08:49:32 +08:00
										 |  |  |  * @author  Duy-Nguyen Ta | 
					
						
							|  |  |  |  * @author  Krunal Chande | 
					
						
							|  |  |  |  * @author  Luca Carlone | 
					
						
							|  |  |  |  * @date    Dec 15, 2014 | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | #include <gtsam/nonlinear/NonlinearFactorGraph.h>
 | 
					
						
							| 
									
										
										
										
											2015-02-25 21:07:40 +08:00
										 |  |  | #include <gtsam/nonlinear/NonlinearOptimizerParams.h>
 | 
					
						
							| 
									
										
										
										
											2015-02-25 12:40:53 +08:00
										 |  |  | #include <gtsam_unstable/nonlinear/LinearEqualityFactorGraph.h>
 | 
					
						
							|  |  |  | #include <gtsam_unstable/nonlinear/LinearInequalityFactorGraph.h>
 | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-24 04:12:53 +08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Nonlinear Programming problem with | 
					
						
							|  |  |  |  * only linear constraints, encoded in factor graphs | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-02-25 12:40:53 +08:00
										 |  |  | struct LinearConstraintNLP { | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  |   NonlinearFactorGraph cost; | 
					
						
							| 
									
										
										
										
											2015-02-25 12:40:53 +08:00
										 |  |  |   LinearEqualityFactorGraph linearEqualities; | 
					
						
							|  |  |  |   LinearInequalityFactorGraph linearInequalities; | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-24 04:12:53 +08:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2015-02-25 12:40:53 +08:00
										 |  |  |  * State of LinearConstraintSQP before/after each iteration | 
					
						
							| 
									
										
										
										
											2014-12-24 04:12:53 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-02-25 12:40:53 +08:00
										 |  |  | struct LinearConstraintNLPState { | 
					
						
							|  |  |  |   Values values;        //!< current solution
 | 
					
						
							|  |  |  |   VectorValues duals;   //!< current guess of the dual variables
 | 
					
						
							|  |  |  |   bool converged;       //!< convergence flag
 | 
					
						
							|  |  |  |   size_t iterations;    //!< number of iterations
 | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /// Default constructor
 | 
					
						
							| 
									
										
										
										
											2015-02-25 12:40:53 +08:00
										 |  |  |   LinearConstraintNLPState() : values(), duals(), converged(false), iterations(0) {} | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /// Constructor with an initialValues
 | 
					
						
							| 
									
										
										
										
											2015-02-25 12:40:53 +08:00
										 |  |  |   LinearConstraintNLPState(const Values& initialValues) : | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  |       values(initialValues), duals(VectorValues()), converged(false), iterations(0) { | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-12-24 07:15:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /// print
 | 
					
						
							|  |  |  |   void print(const std::string& s = "") const { | 
					
						
							|  |  |  |     std::cout << s << std::endl; | 
					
						
							|  |  |  |     values.print("Values: "); | 
					
						
							|  |  |  |     duals.print("Duals: "); | 
					
						
							|  |  |  |     if (converged) std::cout << "Converged!" << std::endl; | 
					
						
							|  |  |  |     else std::cout << "Not converged" << std::endl; | 
					
						
							|  |  |  |     std::cout << "Iterations: " << iterations << std::endl; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-25 21:07:40 +08:00
										 |  |  | /** Parameters for Gauss-Newton optimization, inherits from
 | 
					
						
							|  |  |  |  * NonlinearOptimizationParams. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class GTSAM_EXPORT LinearConstraintSQPParams : public NonlinearOptimizerParams { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |   bool warmStart; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   LinearConstraintSQPParams() : NonlinearOptimizerParams(), warmStart(false) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void setWarmStart(bool _warmStart) { | 
					
						
							|  |  |  |     _warmStart = warmStart; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2014-12-24 04:12:53 +08:00
										 |  |  |  * Simple SQP optimizer to solve nonlinear constrained problems | 
					
						
							|  |  |  |  * ONLY linear constraints are supported. | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-02-25 12:40:53 +08:00
										 |  |  | class LinearConstraintSQP { | 
					
						
							|  |  |  |   LinearConstraintNLP lcnlp_; | 
					
						
							| 
									
										
										
										
											2015-02-25 21:07:40 +08:00
										 |  |  |   LinearConstraintSQPParams params_; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2015-02-25 21:07:40 +08:00
										 |  |  |   LinearConstraintSQP(const LinearConstraintNLP& lcnlp, | 
					
						
							|  |  |  |       const LinearConstraintSQPParams& params = LinearConstraintSQPParams()) : | 
					
						
							|  |  |  |         lcnlp_(lcnlp), params_(params) { | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Check if \nabla f(x) - \lambda * \nabla c(x) == 0
 | 
					
						
							| 
									
										
										
										
											2014-12-23 08:49:32 +08:00
										 |  |  |   bool isStationary(const VectorValues& delta) const; | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /// Check if c_E(x) == 0
 | 
					
						
							| 
									
										
										
										
											2015-02-25 12:40:53 +08:00
										 |  |  |   bool isPrimalFeasible(const LinearConstraintNLPState& state) const; | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Dual variables of inequality constraints need to be >=0 | 
					
						
							|  |  |  |    * For active inequalities, the dual needs to be > 0 | 
					
						
							|  |  |  |    * For inactive inequalities, they need to be == 0. However, we don't compute | 
					
						
							|  |  |  |    * dual variables for inactive constraints in the qp subproblem, so we don't care. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2014-12-23 08:49:32 +08:00
										 |  |  |   bool isDualFeasible(const VectorValues& duals) const; | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Check complimentary slackness condition: | 
					
						
							|  |  |  |    * For all inequality constraints, | 
					
						
							|  |  |  |    *        dual * constraintError(primals) == 0. | 
					
						
							|  |  |  |    * If the constraint is active, we need to check constraintError(primals) == 0, and ignore the dual | 
					
						
							|  |  |  |    * If it is inactive, the dual should be 0, regardless of the error. However, we don't compute | 
					
						
							|  |  |  |    * dual variables for inactive constraints in the QP subproblem, so we don't care. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2015-02-25 12:40:53 +08:00
										 |  |  |   bool isComplementary(const LinearConstraintNLPState& state) const; | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /// Check convergence
 | 
					
						
							| 
									
										
										
										
											2015-02-25 12:40:53 +08:00
										 |  |  |   bool checkConvergence(const LinearConstraintNLPState& state, const VectorValues& delta) const; | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Single iteration of SQP | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2015-02-25 21:07:40 +08:00
										 |  |  |   LinearConstraintNLPState iterate(const LinearConstraintNLPState& state) const; | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-25 12:40:53 +08:00
										 |  |  |   /// Intialize all dual variables to zeros
 | 
					
						
							| 
									
										
										
										
											2014-12-23 08:49:32 +08:00
										 |  |  |   VectorValues initializeDuals() const; | 
					
						
							| 
									
										
										
										
											2015-02-19 21:51:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  |   /**
 | 
					
						
							| 
									
										
										
										
											2014-12-25 13:00:22 +08:00
										 |  |  |    * Main optimization function. new | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2015-02-25 21:07:40 +08:00
										 |  |  |   std::pair<Values, VectorValues> optimize(const Values& initialValues) const; | 
					
						
							| 
									
										
										
										
											2014-12-23 07:56:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | } |