| 
									
										
										
										
											2014-12-09 19:13:57 +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 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * -------------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-25 11:15:41 +08:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2015-02-25 22:09:33 +08:00
										 |  |  |  * @file    LinearInequality.h | 
					
						
							|  |  |  |  * @brief   LinearInequality derived from Base with constrained noise model | 
					
						
							|  |  |  |  * @date    Nov 27, 2014 | 
					
						
							|  |  |  |  * @author  Duy-Nguyen Ta | 
					
						
							| 
									
										
										
										
											2016-06-18 12:28:49 +08:00
										 |  |  |  * @author  Ivan Dario Jimenez | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <gtsam/linear/JacobianFactor.h>
 | 
					
						
							| 
									
										
										
										
											2016-01-30 01:07:14 +08:00
										 |  |  | #include <gtsam/linear/VectorValues.h>
 | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-13 01:51:19 +08:00
										 |  |  | typedef Eigen::RowVectorXd RowVector; | 
					
						
							| 
									
										
										
										
											2014-12-13 01:43:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2016-06-18 12:28:49 +08:00
										 |  |  |  * This class defines a linear inequality constraint Ax-b <= 0, | 
					
						
							| 
									
										
										
										
											2015-02-25 11:15:41 +08:00
										 |  |  |  * inheriting JacobianFactor with the special Constrained noise model | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | class LinearInequality: public JacobianFactor { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |   typedef LinearInequality This; ///< Typedef to this class
 | 
					
						
							|  |  |  |   typedef JacobianFactor Base; ///< Typedef to base class
 | 
					
						
							| 
									
										
										
										
											2023-01-18 06:05:12 +08:00
										 |  |  |   typedef std::shared_ptr<This> shared_ptr; ///< shared_ptr to this class
 | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |   Key dualKey_; | 
					
						
							| 
									
										
										
										
											2014-12-13 01:01:16 +08:00
										 |  |  |   bool active_; | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |   /** default constructor for I/O */ | 
					
						
							|  |  |  |   LinearInequality() : | 
					
						
							| 
									
										
										
										
											2014-12-16 00:47:04 +08:00
										 |  |  |       Base(), active_(true) { | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-23 03:41:22 +08:00
										 |  |  |   /** Conversion from HessianFactor */ | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  |   explicit LinearInequality(const HessianFactor& hf) { | 
					
						
							|  |  |  |     throw std::runtime_error( | 
					
						
							|  |  |  |         "Cannot convert HessianFactor to LinearInequality"); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-23 03:41:22 +08:00
										 |  |  |   /** Conversion from JacobianFactor */ | 
					
						
							| 
									
										
										
										
											2016-06-14 10:58:36 +08:00
										 |  |  |   explicit LinearInequality(const JacobianFactor& jf, Key dualKey) : | 
					
						
							|  |  |  |       Base(jf), dualKey_(dualKey), active_(true) { | 
					
						
							| 
									
										
										
										
											2014-12-23 03:41:22 +08:00
										 |  |  |     if (!jf.isConstrained()) { | 
					
						
							| 
									
										
										
										
											2016-06-14 10:58:36 +08:00
										 |  |  |       throw std::runtime_error( | 
					
						
							|  |  |  |           "Cannot convert an unconstrained JacobianFactor to LinearInequality"); | 
					
						
							| 
									
										
										
										
											2014-12-23 03:41:22 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (jf.get_model()->dim() != 1) { | 
					
						
							|  |  |  |       throw std::runtime_error("Only support single-valued inequality factor!"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  |   /** Construct unary factor */ | 
					
						
							| 
									
										
										
										
											2014-12-13 01:43:07 +08:00
										 |  |  |   LinearInequality(Key i1, const RowVector& A1, double b, Key dualKey) : | 
					
						
							| 
									
										
										
										
											2016-06-14 10:58:36 +08:00
										 |  |  |       Base(i1, A1, (Vector(1) << b).finished(), | 
					
						
							|  |  |  |           noiseModel::Constrained::All(1)), dualKey_(dualKey), active_(true) { | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** Construct binary factor */ | 
					
						
							| 
									
										
										
										
											2016-06-14 10:58:36 +08:00
										 |  |  |   LinearInequality(Key i1, const RowVector& A1, Key i2, const RowVector& A2, | 
					
						
							|  |  |  |       double b, Key dualKey) : | 
					
						
							|  |  |  |       Base(i1, A1, i2, A2, (Vector(1) << b).finished(), | 
					
						
							|  |  |  |           noiseModel::Constrained::All(1)), dualKey_(dualKey), active_(true) { | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** Construct ternary factor */ | 
					
						
							| 
									
										
										
										
											2016-06-14 10:58:36 +08:00
										 |  |  |   LinearInequality(Key i1, const RowVector& A1, Key i2, const RowVector& A2, | 
					
						
							|  |  |  |       Key i3, const RowVector& A3, double b, Key dualKey) : | 
					
						
							| 
									
										
										
										
											2014-12-13 06:23:31 +08:00
										 |  |  |       Base(i1, A1, i2, A2, i3, A3, (Vector(1) << b).finished(), | 
					
						
							| 
									
										
										
										
											2014-12-16 00:47:04 +08:00
										 |  |  |           noiseModel::Constrained::All(1)), dualKey_(dualKey), active_(true) { | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** Construct an n-ary factor
 | 
					
						
							|  |  |  |    * @tparam TERMS A container whose value type is std::pair<Key, Matrix>, specifying the | 
					
						
							| 
									
										
										
										
											2015-05-15 20:44:58 +08:00
										 |  |  |    *         collection of keys and matrices making up the factor. | 
					
						
							|  |  |  |    *         In this inequality factor, each matrix must have only one row!! */ | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  |   template<typename TERMS> | 
					
						
							| 
									
										
										
										
											2014-12-13 01:01:16 +08:00
										 |  |  |   LinearInequality(const TERMS& terms, double b, Key dualKey) : | 
					
						
							| 
									
										
										
										
											2014-12-13 06:23:31 +08:00
										 |  |  |       Base(terms, (Vector(1) << b).finished(), noiseModel::Constrained::All(1)), dualKey_( | 
					
						
							| 
									
										
										
										
											2014-12-16 00:47:04 +08:00
										 |  |  |           dualKey), active_(true) { | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** Virtual destructor */ | 
					
						
							| 
									
										
										
										
											2021-01-29 12:02:13 +08:00
										 |  |  |   ~LinearInequality() override { | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** equals */ | 
					
						
							| 
									
										
										
										
											2020-07-26 15:57:54 +08:00
										 |  |  |   bool equals(const GaussianFactor& lf, double tol = 1e-9) const override { | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  |     return Base::equals(lf, tol); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** print */ | 
					
						
							| 
									
										
										
										
											2020-07-26 15:57:54 +08:00
										 |  |  |   void print(const std::string& s = "", const KeyFormatter& formatter = | 
					
						
							|  |  |  |       DefaultKeyFormatter) const override { | 
					
						
							| 
									
										
										
										
											2014-12-13 14:04:46 +08:00
										 |  |  |     if (active()) | 
					
						
							|  |  |  |       Base::print(s + "  Active", formatter); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       Base::print(s + "  Inactive", formatter); | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** Clone this LinearInequality */ | 
					
						
							| 
									
										
										
										
											2020-07-26 15:57:54 +08:00
										 |  |  |   GaussianFactor::shared_ptr clone() const override { | 
					
						
							| 
									
										
										
										
											2023-01-18 06:39:55 +08:00
										 |  |  |     return std::static_pointer_cast < GaussianFactor | 
					
						
							| 
									
										
										
										
											2023-01-18 06:05:12 +08:00
										 |  |  |         > (std::make_shared < LinearInequality > (*this)); | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// dual key
 | 
					
						
							| 
									
										
										
										
											2016-06-14 10:58:36 +08:00
										 |  |  |   Key dualKey() const { | 
					
						
							|  |  |  |     return dualKey_; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-13 01:01:16 +08:00
										 |  |  |   /// return true if this constraint is active
 | 
					
						
							| 
									
										
										
										
											2016-06-14 10:58:36 +08:00
										 |  |  |   bool active() const { | 
					
						
							|  |  |  |     return active_; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-12-13 01:01:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /// Make this inequality constraint active
 | 
					
						
							| 
									
										
										
										
											2016-06-14 10:58:36 +08:00
										 |  |  |   void activate() { | 
					
						
							|  |  |  |     active_ = true; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-12-13 01:01:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /// Make this inequality constraint inactive
 | 
					
						
							| 
									
										
										
										
											2016-06-14 10:58:36 +08:00
										 |  |  |   void inactivate() { | 
					
						
							|  |  |  |     active_ = false; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-12-13 01:01:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  |   /** Special error_vector for constraints (A*x-b) */ | 
					
						
							|  |  |  |   Vector error_vector(const VectorValues& c) const { | 
					
						
							|  |  |  |     return unweighted_error(c); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-13 01:01:16 +08:00
										 |  |  |   /** Special error for single-valued inequality constraints. */ | 
					
						
							| 
									
										
										
										
											2020-07-26 15:57:54 +08:00
										 |  |  |   double error(const VectorValues& c) const override { | 
					
						
							| 
									
										
										
										
											2014-12-13 01:01:16 +08:00
										 |  |  |     return error_vector(c)[0]; | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** dot product of row s with the corresponding vector in p */ | 
					
						
							| 
									
										
										
										
											2014-12-13 01:01:16 +08:00
										 |  |  |   double dotProductRow(const VectorValues& p) const { | 
					
						
							|  |  |  |     double aTp = 0.0; | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  |     for (const_iterator xj = begin(); xj != end(); ++xj) { | 
					
						
							|  |  |  |       Vector pj = p.at(*xj); | 
					
						
							| 
									
										
										
										
											2014-12-13 01:01:16 +08:00
										 |  |  |       Vector aj = getA(xj).transpose(); | 
					
						
							|  |  |  |       aTp += aj.dot(pj); | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-12-13 01:01:16 +08:00
										 |  |  |     return aTp; | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-14 10:58:36 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | // \ LinearInequality
 | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-22 05:02:06 +08:00
										 |  |  | /// traits
 | 
					
						
							| 
									
										
										
										
											2016-06-14 10:58:36 +08:00
										 |  |  | template<> struct traits<LinearInequality> : public Testable<LinearInequality> { | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2014-12-22 05:02:06 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | } // \ namespace gtsam
 | 
					
						
							| 
									
										
										
										
											2014-12-09 19:13:57 +08:00
										 |  |  | 
 |