gtsam  3.2.1
gtsam
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NonlinearEquality.h
1 /* ----------------------------------------------------------------------------
2 
3  * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4  * Atlanta, Georgia 30332-0415
5  * All Rights Reserved
6  * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7 
8  * See LICENSE for the license information
9 
10  * -------------------------------------------------------------------------- */
11 
12 /*
13  * @file NonlinearEquality.h
14  * @brief Factor to handle enforced equality between factors
15  * @author Alex Cunningham
16  */
17 
18 #pragma once
19 
20 #include <limits>
21 #include <iostream>
22 
24 #include <gtsam/base/Testable.h>
25 #include <gtsam/base/Manifold.h>
26 
27 namespace gtsam {
28 
32  template<class T>
33  bool compare(const T& a, const T& b) {
34  GTSAM_CONCEPT_TESTABLE_TYPE(T);
35  return a.equals(b);
36  }
37 
50  template<class VALUE>
51  class NonlinearEquality: public NoiseModelFactor1<VALUE> {
52 
53  public:
54  typedef VALUE T;
55 
56  private:
57 
58  // feasible value
59  T feasible_;
60 
61  // error handling flag
62  bool allow_error_;
63 
64  // error gain in allow error case
65  double error_gain_;
66 
67  // typedef to this class
69 
70  // typedef to base class
72 
73  public:
74 
78  bool (*compare_)(const T& a, const T& b);
79 
80 
83 
84  virtual ~NonlinearEquality() {}
85 
88 
92  NonlinearEquality(Key j, const T& feasible, bool (*_compare)(const T&, const T&) = compare<T>) :
93  Base(noiseModel::Constrained::All(feasible.dim()), j), feasible_(feasible),
94  allow_error_(false), error_gain_(0.0),
95  compare_(_compare) {
96  }
97 
101  NonlinearEquality(Key j, const T& feasible, double error_gain, bool (*_compare)(const T&, const T&) = compare<T>) :
102  Base(noiseModel::Constrained::All(feasible.dim()), j), feasible_(feasible),
103  allow_error_(true), error_gain_(error_gain),
104  compare_(_compare) {
105  }
106 
110 
111  virtual void print(const std::string& s = "", const KeyFormatter& keyFormatter = DefaultKeyFormatter) const {
112  std::cout << s << "Constraint: on [" << keyFormatter(this->key()) << "]\n";
113  gtsam::print(feasible_,"Feasible Point:\n");
114  std::cout << "Variable Dimension: " << feasible_.dim() << std::endl;
115  }
116 
118  virtual bool equals(const NonlinearFactor& f, double tol = 1e-9) const {
119  const This* e = dynamic_cast<const This*>(&f);
120  return e && Base::equals(f) && feasible_.equals(e->feasible_, tol) &&
121  fabs(error_gain_ - e->error_gain_) < tol;
122  }
123 
127 
129  virtual double error(const Values& c) const {
130  const T& xj = c.at<T>(this->key());
131  Vector e = this->unwhitenedError(c);
132  if (allow_error_ || !compare_(xj, feasible_)) {
133  return error_gain_ * dot(e,e);
134  } else {
135  return 0.0;
136  }
137  }
138 
140  Vector evaluateError(const T& xj, boost::optional<Matrix&> H = boost::none) const {
141  size_t nj = feasible_.dim();
142  if (allow_error_) {
143  if (H) *H = eye(nj); // FIXME: this is not the right linearization for nonlinear compare
144  return xj.localCoordinates(feasible_);
145  } else if (compare_(feasible_,xj)) {
146  if (H) *H = eye(nj);
147  return zero(nj); // set error to zero if equal
148  } else {
149  if (H) throw std::invalid_argument(
150  "Linearization point not feasible for " + DefaultKeyFormatter(this->key()) + "!");
151  return repeat(nj, std::numeric_limits<double>::infinity()); // set error to infinity if not equal
152  }
153  }
154 
155  // Linearize is over-written, because base linearization tries to whiten
156  virtual GaussianFactor::shared_ptr linearize(const Values& x) const {
157  const T& xj = x.at<T>(this->key());
158  Matrix A;
159  Vector b = evaluateError(xj, A);
160  SharedDiagonal model = noiseModel::Constrained::All(b.size());
161  return GaussianFactor::shared_ptr(new JacobianFactor(this->key(), A, b, model));
162  }
163 
165  virtual gtsam::NonlinearFactor::shared_ptr clone() const {
166  return boost::static_pointer_cast<gtsam::NonlinearFactor>(
167  gtsam::NonlinearFactor::shared_ptr(new This(*this))); }
168 
170 
171  private:
172 
175  template<class ARCHIVE>
176  void serialize(ARCHIVE & ar, const unsigned int version) {
177  ar & boost::serialization::make_nvp("NoiseModelFactor1",
178  boost::serialization::base_object<Base>(*this));
179  ar & BOOST_SERIALIZATION_NVP(feasible_);
180  ar & BOOST_SERIALIZATION_NVP(allow_error_);
181  ar & BOOST_SERIALIZATION_NVP(error_gain_);
182  }
183 
184  }; // \class NonlinearEquality
185 
186  /* ************************************************************************* */
190  template<class VALUE>
191  class NonlinearEquality1 : public NoiseModelFactor1<VALUE> {
192 
193  public:
194  typedef VALUE X;
195 
196  protected:
199 
202 
203  X value_;
204 
206  GTSAM_CONCEPT_TESTABLE_TYPE(X);
207 
208  public:
209 
210  typedef boost::shared_ptr<NonlinearEquality1<VALUE> > shared_ptr;
211 
213  NonlinearEquality1(const X& value, Key key1, double mu = 1000.0)
214  : Base(noiseModel::Constrained::All(value.dim(), fabs(mu)), key1), value_(value) {}
215 
216  virtual ~NonlinearEquality1() {}
217 
219  virtual gtsam::NonlinearFactor::shared_ptr clone() const {
220  return boost::static_pointer_cast<gtsam::NonlinearFactor>(
221  gtsam::NonlinearFactor::shared_ptr(new This(*this))); }
222 
224  Vector evaluateError(const X& x1, boost::optional<Matrix&> H = boost::none) const {
225  if (H) (*H) = eye(x1.dim());
226  // manifold equivalent of h(x)-z -> log(z,h(x))
227  return value_.localCoordinates(x1);
228  }
229 
231  virtual void print(const std::string& s = "", const KeyFormatter& keyFormatter = DefaultKeyFormatter) const {
232  std::cout << s << ": NonlinearEquality1("
233  << keyFormatter(this->key()) << "),"<< "\n";
234  this->noiseModel_->print();
235  value_.print("Value");
236  }
237 
238  private:
239 
242  template<class ARCHIVE>
243  void serialize(ARCHIVE & ar, const unsigned int version) {
244  ar & boost::serialization::make_nvp("NoiseModelFactor1",
245  boost::serialization::base_object<Base>(*this));
246  ar & BOOST_SERIALIZATION_NVP(value_);
247  }
248  }; // \NonlinearEquality1
249 
250  /* ************************************************************************* */
255  template<class VALUE>
256  class NonlinearEquality2 : public NoiseModelFactor2<VALUE, VALUE> {
257  public:
258  typedef VALUE X;
259 
260  protected:
263 
264  GTSAM_CONCEPT_MANIFOLD_TYPE(X);
265 
268 
269  public:
270 
271  typedef boost::shared_ptr<NonlinearEquality2<VALUE> > shared_ptr;
272 
274  NonlinearEquality2(Key key1, Key key2, double mu = 1000.0)
275  : Base(noiseModel::Constrained::All(X::Dim(), fabs(mu)), key1, key2) {}
276  virtual ~NonlinearEquality2() {}
277 
279  virtual gtsam::NonlinearFactor::shared_ptr clone() const {
280  return boost::static_pointer_cast<gtsam::NonlinearFactor>(
281  gtsam::NonlinearFactor::shared_ptr(new This(*this))); }
282 
284  Vector evaluateError(const X& x1, const X& x2,
285  boost::optional<Matrix&> H1 = boost::none,
286  boost::optional<Matrix&> H2 = boost::none) const {
287  const size_t p = X::Dim();
288  if (H1) *H1 = -eye(p);
289  if (H2) *H2 = eye(p);
290  return x1.localCoordinates(x2);
291  }
292 
293  private:
294 
297  template<class ARCHIVE>
298  void serialize(ARCHIVE & ar, const unsigned int version) {
299  ar & boost::serialization::make_nvp("NoiseModelFactor2",
300  boost::serialization::base_object<Base>(*this));
301  }
302  }; // \NonlinearEquality2
303 
304 } // namespace gtsam
305 
Non-linear factor base classes.
virtual bool equals(const NonlinearFactor &f, double tol=1e-9) const
Check if two factors are equal.
Definition: NonlinearFactor.h:239
friend class boost::serialization::access
Serialization function.
Definition: NonlinearEquality.h:174
virtual void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
Print.
Definition: NonlinearEquality.h:111
double dot(const V1 &a, const V2 &b)
Dot product.
Definition: Vector.h:259
virtual size_t dim() const
get the dimension of the factor (number of rows on linearization)
Definition: NonlinearFactor.h:247
NonlinearEquality(Key j, const T &feasible, double error_gain, bool(*_compare)(const T &, const T &)=compare< T >)
Constructor - allows inexact evaluation.
Definition: NonlinearEquality.h:101
Vector evaluateError(const X &x1, const X &x2, boost::optional< Matrix & > H1=boost::none, boost::optional< Matrix & > H2=boost::none) const
g(x) with optional derivative2
Definition: NonlinearEquality.h:284
Matrix eye(size_t m, size_t n)
Creates an identity matrix, with matlab-like syntax.
Definition: Matrix.cpp:50
NonlinearEquality(Key j, const T &feasible, bool(*_compare)(const T &, const T &)=compare< T >)
Constructor - forces exact evaluation.
Definition: NonlinearEquality.h:92
virtual gtsam::NonlinearFactor::shared_ptr clone() const
Definition: NonlinearEquality.h:219
friend class boost::serialization::access
Serialization function.
Definition: NonlinearEquality.h:296
Simple binary equality constraint - this constraint forces two factors to be the same.
Definition: NonlinearEquality.h:256
Base class and basic functions for Manifold types.
GTSAM_CONCEPT_MANIFOLD_TYPE(X)
fixed value for variable
A convenient base class for creating your own NoiseModelFactor with 2 variables.
Definition: NonlinearFactor.h:423
A Gaussian factor in the squared-error form.
Definition: JacobianFactor.h:82
This is the base class for all factor types.
Definition: Factor.h:51
static shared_ptr All(size_t dim)
Fully constrained variations.
Definition: NoiseModel.h:445
virtual Vector unwhitenedError(const Values &x, boost::optional< std::vector< Matrix > & > H=boost::none) const
Calls the 1-key specific version of evaluateError, which is pure virtual so must be implemented in th...
Definition: NonlinearFactor.h:386
virtual GaussianFactor::shared_ptr linearize(const Values &x) const
linearize to a GaussianFactor
Definition: NonlinearEquality.h:156
virtual gtsam::NonlinearFactor::shared_ptr clone() const
Definition: NonlinearEquality.h:279
A non-templated config holding any types of Manifold-group elements.
Definition: Values.h:75
bool zero(const Vector &v)
check if all zero
Definition: Vector.cpp:39
friend class boost::serialization::access
Serialization function.
Definition: NonlinearEquality.h:241
void print(const Matrix &A, const string &s, ostream &stream)
print a matrix
Definition: Matrix.cpp:183
Vector evaluateError(const T &xj, boost::optional< Matrix & > H=boost::none) const
error function
Definition: NonlinearEquality.h:140
Key key1() const
methods to retrieve both keys
Definition: NonlinearFactor.h:455
const ValueType & at(Key j) const
Retrieve a variable by key j.
Definition: Values-inl.h:219
Concept check for values that can be used in unit tests.
Simple unary equality constraint - fixes a value for a variable.
Definition: NonlinearEquality.h:191
virtual void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
Print.
Definition: NonlinearEquality.h:231
size_t Key
Integer nonlinear key type.
Definition: types.h:59
virtual bool equals(const NonlinearFactor &f, double tol=1e-9) const
Check if two factors are equal.
Definition: NonlinearEquality.h:118
NonlinearEquality()
default constructor - only for serialization
Definition: NonlinearEquality.h:82
boost::shared_ptr< This > shared_ptr
shared_ptr to this class
Definition: GaussianFactor.h:39
A convenient base class for creating your own NoiseModelFactor with 1 variable.
Definition: NonlinearFactor.h:354
virtual double error(const Values &c) const
actual error function calculation
Definition: NonlinearEquality.h:129
bool(* compare_)(const T &a, const T &b)
Function that compares two values.
Definition: NonlinearEquality.h:78
An equality factor that forces either one variable to a constant, or a set of variables to be equal t...
Definition: NonlinearEquality.h:51
bool compare(const T &a, const T &b)
Template default compare function that assumes a testable T.
Definition: NonlinearEquality.h:33
NonlinearEquality1()
default constructor to allow for serialization
Definition: NonlinearEquality.h:201
Nonlinear factor base class.
Definition: NonlinearFactor.h:54
Vector repeat(size_t n, double value)
Create vector initialized to a constant value.
Definition: Vector.cpp:48
virtual gtsam::NonlinearFactor::shared_ptr clone() const
Definition: NonlinearEquality.h:165
boost::function< std::string(Key)> KeyFormatter
Typedef for a function to format a key, i.e. to convert it to a string.
Definition: types.h:62
NonlinearEquality2()
default constructor to allow for serialization
Definition: NonlinearEquality.h:267
NonlinearEquality2(Key key1, Key key2, double mu=1000.0)
TODO: comment.
Definition: NonlinearEquality.h:274
NonlinearEquality1(const X &value, Key key1, double mu=1000.0)
TODO: comment.
Definition: NonlinearEquality.h:213
Vector evaluateError(const X &x1, boost::optional< Matrix & > H=boost::none) const
g(x) with optional derivative
Definition: NonlinearEquality.h:224