gtsam  4.0.0
gtsam
NoiseModel.h
Go to the documentation of this file.
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 
19 #pragma once
20 
21 #include <gtsam/base/Testable.h>
22 #include <gtsam/base/Matrix.h>
23 #include <gtsam/dllexport.h>
24 
25 #include <boost/serialization/nvp.hpp>
26 #include <boost/serialization/extended_type_info.hpp>
27 #include <boost/serialization/singleton.hpp>
28 #include <boost/serialization/shared_ptr.hpp>
29 #include <boost/serialization/optional.hpp>
30 
31 namespace gtsam {
32 
34  namespace noiseModel {
35 
36  // Forward declaration
37  class Gaussian;
38  class Diagonal;
39  class Constrained;
40  class Isotropic;
41  class Unit;
42 
43  //---------------------------------------------------------------------------------------
44 
51  class GTSAM_EXPORT Base {
52 
53  public:
54  typedef boost::shared_ptr<Base> shared_ptr;
55 
56  protected:
57 
58  size_t dim_;
59 
60  public:
61 
63  Base(size_t dim = 1):dim_(dim) {}
64  virtual ~Base() {}
65 
67  virtual bool isConstrained() const { return false; } // default false
68 
70  virtual bool isUnit() const { return false; } // default false
71 
73  inline size_t dim() const { return dim_;}
74 
75  virtual void print(const std::string& name = "") const = 0;
76 
77  virtual bool equals(const Base& expected, double tol=1e-9) const = 0;
78 
80  virtual Vector sigmas() const;
81 
83  virtual Vector whiten(const Vector& v) const = 0;
84 
86  virtual Matrix Whiten(const Matrix& H) const = 0;
87 
89  virtual Vector unwhiten(const Vector& v) const = 0;
90 
91  virtual double distance(const Vector& v) const = 0;
92 
93  virtual void WhitenSystem(std::vector<Matrix>& A, Vector& b) const = 0;
94  virtual void WhitenSystem(Matrix& A, Vector& b) const = 0;
95  virtual void WhitenSystem(Matrix& A1, Matrix& A2, Vector& b) const = 0;
96  virtual void WhitenSystem(Matrix& A1, Matrix& A2, Matrix& A3, Vector& b) const = 0;
97 
99  virtual void whitenInPlace(Vector& v) const {
100  v = whiten(v);
101  }
102 
104  virtual void unwhitenInPlace(Vector& v) const {
105  v = unwhiten(v);
106  }
107 
109  virtual void whitenInPlace(Eigen::Block<Vector>& v) const {
110  v = whiten(v);
111  }
112 
114  virtual void unwhitenInPlace(Eigen::Block<Vector>& v) const {
115  v = unwhiten(v);
116  }
117 
118  private:
120  friend class boost::serialization::access;
121  template<class ARCHIVE>
122  void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
123  ar & BOOST_SERIALIZATION_NVP(dim_);
124  }
125  };
126 
127  //---------------------------------------------------------------------------------------
128 
141  class GTSAM_EXPORT Gaussian: public Base {
142 
143  protected:
144 
146  boost::optional<Matrix> sqrt_information_;
147 
148  private:
149 
153  const Matrix& thisR() const {
154  // should never happen
155  if (!sqrt_information_) throw std::runtime_error("Gaussian: has no R matrix");
156  return *sqrt_information_;
157  }
158 
159  protected:
160 
162  Gaussian(size_t dim = 1, const boost::optional<Matrix>& sqrt_information = boost::none) :
163  Base(dim), sqrt_information_(sqrt_information) {
164  }
165 
166  public:
167 
168  typedef boost::shared_ptr<Gaussian> shared_ptr;
169 
170  virtual ~Gaussian() {}
171 
177  static shared_ptr SqrtInformation(const Matrix& R, bool smart = true);
178 
184  static shared_ptr Information(const Matrix& M, bool smart = true);
185 
191  static shared_ptr Covariance(const Matrix& covariance, bool smart = true);
192 
193  virtual void print(const std::string& name) const;
194  virtual bool equals(const Base& expected, double tol=1e-9) const;
195  virtual Vector sigmas() const;
196  virtual Vector whiten(const Vector& v) const;
197  virtual Vector unwhiten(const Vector& v) const;
198 
202  virtual double Mahalanobis(const Vector& v) const;
203 
204  inline virtual double distance(const Vector& v) const {
205  return Mahalanobis(v);
206  }
207 
212  virtual Matrix Whiten(const Matrix& H) const;
213 
217  virtual void WhitenInPlace(Matrix& H) const;
218 
222  virtual void WhitenInPlace(Eigen::Block<Matrix> H) const;
223 
227  virtual void WhitenSystem(std::vector<Matrix>& A, Vector& b) const;
228  virtual void WhitenSystem(Matrix& A, Vector& b) const;
229  virtual void WhitenSystem(Matrix& A1, Matrix& A2, Vector& b) const;
230  virtual void WhitenSystem(Matrix& A1, Matrix& A2, Matrix& A3, Vector& b) const;
231 
241  virtual boost::shared_ptr<Diagonal> QR(Matrix& Ab) const;
242 
244  virtual Matrix R() const { return thisR();}
245 
247  virtual Matrix information() const { return R().transpose() * R(); }
248 
250  virtual Matrix covariance() const { return information().inverse(); }
251 
252  private:
254  friend class boost::serialization::access;
255  template<class ARCHIVE>
256  void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
257  ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
258  ar & BOOST_SERIALIZATION_NVP(sqrt_information_);
259  }
260 
261  }; // Gaussian
262 
263  //---------------------------------------------------------------------------------------
264 
270  class GTSAM_EXPORT Diagonal : public Gaussian {
271  protected:
272 
278  Vector sigmas_, invsigmas_, precisions_;
279 
280  protected:
282  Diagonal();
283 
285  Diagonal(const Vector& sigmas);
286 
287  public:
288 
289  typedef boost::shared_ptr<Diagonal> shared_ptr;
290 
291  virtual ~Diagonal() {}
292 
297  static shared_ptr Sigmas(const Vector& sigmas, bool smart = true);
298 
305  static shared_ptr Variances(const Vector& variances, bool smart = true);
306 
311  static shared_ptr Precisions(const Vector& precisions, bool smart = true) {
312  return Variances(precisions.array().inverse(), smart);
313  }
314 
315  virtual void print(const std::string& name) const;
316  virtual Vector sigmas() const { return sigmas_; }
317  virtual Vector whiten(const Vector& v) const;
318  virtual Vector unwhiten(const Vector& v) const;
319  virtual Matrix Whiten(const Matrix& H) const;
320  virtual void WhitenInPlace(Matrix& H) const;
321  virtual void WhitenInPlace(Eigen::Block<Matrix> H) const;
322 
326  inline double sigma(size_t i) const { return sigmas_(i); }
327 
331  inline const Vector& invsigmas() const { return invsigmas_; }
332  inline double invsigma(size_t i) const {return invsigmas_(i);}
333 
337  inline const Vector& precisions() const { return precisions_; }
338  inline double precision(size_t i) const {return precisions_(i);}
339 
343  virtual Matrix R() const {
344  return invsigmas().asDiagonal();
345  }
346 
347  private:
349  friend class boost::serialization::access;
350  template<class ARCHIVE>
351  void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
352  ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Gaussian);
353  ar & BOOST_SERIALIZATION_NVP(sigmas_);
354  ar & BOOST_SERIALIZATION_NVP(invsigmas_);
355  }
356  }; // Diagonal
357 
358  //---------------------------------------------------------------------------------------
359 
372  class GTSAM_EXPORT Constrained : public Diagonal {
373  protected:
374 
375  // Sigmas are contained in the base class
376  Vector mu_;
377 
384  Constrained(const Vector& sigmas = Z_1x1);
385 
391  Constrained(const Vector& mu, const Vector& sigmas);
392 
393  public:
394 
395  typedef boost::shared_ptr<Constrained> shared_ptr;
396 
397  virtual ~Constrained() {}
398 
400  virtual bool isConstrained() const { return true; }
401 
403  bool constrained(size_t i) const;
404 
406  const Vector& mu() const { return mu_; }
407 
412  static shared_ptr MixedSigmas(const Vector& mu, const Vector& sigmas);
413 
418  static shared_ptr MixedSigmas(const Vector& sigmas) {
419  return MixedSigmas(Vector::Constant(sigmas.size(), 1000.0), sigmas);
420  }
421 
426  static shared_ptr MixedSigmas(double m, const Vector& sigmas) {
427  return MixedSigmas(Vector::Constant(sigmas.size(), m), sigmas);
428  }
429 
434  static shared_ptr MixedVariances(const Vector& mu, const Vector& variances) {
435  return shared_ptr(new Constrained(mu, variances.cwiseSqrt()));
436  }
437  static shared_ptr MixedVariances(const Vector& variances) {
438  return shared_ptr(new Constrained(variances.cwiseSqrt()));
439  }
440 
445  static shared_ptr MixedPrecisions(const Vector& mu, const Vector& precisions) {
446  return MixedVariances(mu, precisions.array().inverse());
447  }
448  static shared_ptr MixedPrecisions(const Vector& precisions) {
449  return MixedVariances(precisions.array().inverse());
450  }
451 
457  virtual double distance(const Vector& v) const;
458 
460  static shared_ptr All(size_t dim) {
461  return shared_ptr(new Constrained(Vector::Constant(dim, 1000.0), Vector::Constant(dim,0)));
462  }
463 
465  static shared_ptr All(size_t dim, const Vector& mu) {
466  return shared_ptr(new Constrained(mu, Vector::Constant(dim,0)));
467  }
468 
470  static shared_ptr All(size_t dim, double mu) {
471  return shared_ptr(new Constrained(Vector::Constant(dim, mu), Vector::Constant(dim,0)));
472  }
473 
474  virtual void print(const std::string& name) const;
475 
477  virtual Vector whiten(const Vector& v) const;
478 
481  virtual Matrix Whiten(const Matrix& H) const;
482  virtual void WhitenInPlace(Matrix& H) const;
483  virtual void WhitenInPlace(Eigen::Block<Matrix> H) const;
484 
494  virtual Diagonal::shared_ptr QR(Matrix& Ab) const;
495 
500  shared_ptr unit() const;
501 
502  private:
504  friend class boost::serialization::access;
505  template<class ARCHIVE>
506  void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
507  ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Diagonal);
508  ar & BOOST_SERIALIZATION_NVP(mu_);
509  }
510 
511  }; // Constrained
512 
513  //---------------------------------------------------------------------------------------
514 
519  class GTSAM_EXPORT Isotropic : public Diagonal {
520  protected:
521  double sigma_, invsigma_;
522 
524  Isotropic(size_t dim, double sigma) :
525  Diagonal(Vector::Constant(dim, sigma)),sigma_(sigma),invsigma_(1.0/sigma) {}
526 
527  /* dummy constructor to allow for serialization */
528  Isotropic() : Diagonal(Vector1::Constant(1.0)),sigma_(1.0),invsigma_(1.0) {}
529 
530  public:
531 
532  virtual ~Isotropic() {}
533 
534  typedef boost::shared_ptr<Isotropic> shared_ptr;
535 
539  static shared_ptr Sigma(size_t dim, double sigma, bool smart = true);
540 
547  static shared_ptr Variance(size_t dim, double variance, bool smart = true);
548 
552  static shared_ptr Precision(size_t dim, double precision, bool smart = true) {
553  return Variance(dim, 1.0/precision, smart);
554  }
555 
556  virtual void print(const std::string& name) const;
557  virtual double Mahalanobis(const Vector& v) const;
558  virtual Vector whiten(const Vector& v) const;
559  virtual Vector unwhiten(const Vector& v) const;
560  virtual Matrix Whiten(const Matrix& H) const;
561  virtual void WhitenInPlace(Matrix& H) const;
562  virtual void whitenInPlace(Vector& v) const;
563  virtual void WhitenInPlace(Eigen::Block<Matrix> H) const;
564 
568  inline double sigma() const { return sigma_; }
569 
570  private:
572  friend class boost::serialization::access;
573  template<class ARCHIVE>
574  void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
575  ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Diagonal);
576  ar & BOOST_SERIALIZATION_NVP(sigma_);
577  ar & BOOST_SERIALIZATION_NVP(invsigma_);
578  }
579 
580  };
581 
582  //---------------------------------------------------------------------------------------
583 
587  class GTSAM_EXPORT Unit : public Isotropic {
588  protected:
589 
590  Unit(size_t dim=1): Isotropic(dim,1.0) {}
591 
592  public:
593 
594  typedef boost::shared_ptr<Unit> shared_ptr;
595 
596  virtual ~Unit() {}
597 
601  static shared_ptr Create(size_t dim) {
602  return shared_ptr(new Unit(dim));
603  }
604 
606  virtual bool isUnit() const { return true; }
607 
608  virtual void print(const std::string& name) const;
609  virtual double Mahalanobis(const Vector& v) const {return v.dot(v); }
610  virtual Vector whiten(const Vector& v) const { return v; }
611  virtual Vector unwhiten(const Vector& v) const { return v; }
612  virtual Matrix Whiten(const Matrix& H) const { return H; }
613  virtual void WhitenInPlace(Matrix& /*H*/) const {}
614  virtual void WhitenInPlace(Eigen::Block<Matrix> /*H*/) const {}
615  virtual void whitenInPlace(Vector& /*v*/) const {}
616  virtual void unwhitenInPlace(Vector& /*v*/) const {}
617  virtual void whitenInPlace(Eigen::Block<Vector>& /*v*/) const {}
618  virtual void unwhitenInPlace(Eigen::Block<Vector>& /*v*/) const {}
619 
620  private:
622  friend class boost::serialization::access;
623  template<class ARCHIVE>
624  void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
625  ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Isotropic);
626  }
627  };
628 
647  namespace mEstimator {
648 
649  //---------------------------------------------------------------------------------------
650 
651  class GTSAM_EXPORT Base {
652  public:
653  enum ReweightScheme { Scalar, Block };
654  typedef boost::shared_ptr<Base> shared_ptr;
655 
656  protected:
659  ReweightScheme reweight_;
660 
661  public:
662  Base(const ReweightScheme reweight = Block):reweight_(reweight) {}
663  virtual ~Base() {}
664 
665  /*
666  * This method is responsible for returning the total penalty for a given amount of error.
667  * For example, this method is responsible for implementing the quadratic function for an
668  * L2 penalty, the absolute value function for an L1 penalty, etc.
669  *
670  * TODO(mike): There is currently a bug in GTSAM, where none of the mEstimator classes
671  * implement a residual function, and GTSAM calls the weight function to evaluate the
672  * total penalty, rather than calling the residual function. The weight function should be
673  * used during iteratively reweighted least squares optimization, but should not be used to
674  * evaluate the total penalty. The long-term solution is for all mEstimators to implement
675  * both a weight and a residual function, and for GTSAM to call the residual function when
676  * evaluating the total penalty. But for now, I'm leaving this residual method as pure
677  * virtual, so the existing mEstimators can inherit this default fallback behavior.
678  */
679  virtual double residual(double error) const { return 0; };
680 
681  /*
682  * This method is responsible for returning the weight function for a given amount of error.
683  * The weight function is related to the analytic derivative of the residual function. See
684  * http://research.microsoft.com/en-us/um/people/zhang/INRIA/Publis/Tutorial-Estim/node24.html
685  * for details. This method is required when optimizing cost functions with robust penalties
686  * using iteratively re-weighted least squares.
687  */
688  virtual double weight(double error) const = 0;
689 
690  virtual void print(const std::string &s) const = 0;
691  virtual bool equals(const Base& expected, double tol=1e-8) const = 0;
692 
693  double sqrtWeight(double error) const {
694  return std::sqrt(weight(error));
695  }
696 
699  Vector weight(const Vector &error) const;
700 
702  Vector sqrtWeight(const Vector &error) const {
703  return weight(error).cwiseSqrt();
704  }
705 
707  void reweight(Vector &error) const;
708  void reweight(std::vector<Matrix> &A, Vector &error) const;
709  void reweight(Matrix &A, Vector &error) const;
710  void reweight(Matrix &A1, Matrix &A2, Vector &error) const;
711  void reweight(Matrix &A1, Matrix &A2, Matrix &A3, Vector &error) const;
712 
713  private:
715  friend class boost::serialization::access;
716  template<class ARCHIVE>
717  void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
718  ar & BOOST_SERIALIZATION_NVP(reweight_);
719  }
720  };
721 
723  class GTSAM_EXPORT Null : public Base {
724  public:
725  typedef boost::shared_ptr<Null> shared_ptr;
726 
727  Null(const ReweightScheme reweight = Block) : Base(reweight) {}
728  virtual ~Null() {}
729  virtual double weight(double /*error*/) const { return 1.0; }
730  virtual void print(const std::string &s) const;
731  virtual bool equals(const Base& /*expected*/, double /*tol*/) const { return true; }
732  static shared_ptr Create() ;
733 
734  private:
736  friend class boost::serialization::access;
737  template<class ARCHIVE>
738  void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
739  ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
740  }
741  };
742 
744  class GTSAM_EXPORT Fair : public Base {
745  protected:
746  double c_;
747 
748  public:
749  typedef boost::shared_ptr<Fair> shared_ptr;
750 
751  Fair(double c = 1.3998, const ReweightScheme reweight = Block);
752  double weight(double error) const {
753  return 1.0 / (1.0 + fabs(error) / c_);
754  }
755  void print(const std::string &s) const;
756  bool equals(const Base& expected, double tol=1e-8) const;
757  static shared_ptr Create(double c, const ReweightScheme reweight = Block) ;
758 
759  private:
761  friend class boost::serialization::access;
762  template<class ARCHIVE>
763  void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
764  ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
765  ar & BOOST_SERIALIZATION_NVP(c_);
766  }
767  };
768 
770  class GTSAM_EXPORT Huber : public Base {
771  protected:
772  double k_;
773 
774  public:
775  typedef boost::shared_ptr<Huber> shared_ptr;
776 
777  Huber(double k = 1.345, const ReweightScheme reweight = Block);
778  double weight(double error) const {
779  return (error < k_) ? (1.0) : (k_ / fabs(error));
780  }
781  void print(const std::string &s) const;
782  bool equals(const Base& expected, double tol=1e-8) const;
783  static shared_ptr Create(double k, const ReweightScheme reweight = Block) ;
784 
785  private:
787  friend class boost::serialization::access;
788  template<class ARCHIVE>
789  void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
790  ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
791  ar & BOOST_SERIALIZATION_NVP(k_);
792  }
793  };
794 
800  class GTSAM_EXPORT Cauchy : public Base {
801  protected:
802  double k_, ksquared_;
803 
804  public:
805  typedef boost::shared_ptr<Cauchy> shared_ptr;
806 
807  Cauchy(double k = 0.1, const ReweightScheme reweight = Block);
808  double weight(double error) const {
809  return ksquared_ / (ksquared_ + error*error);
810  }
811  void print(const std::string &s) const;
812  bool equals(const Base& expected, double tol=1e-8) const;
813  static shared_ptr Create(double k, const ReweightScheme reweight = Block) ;
814 
815  private:
817  friend class boost::serialization::access;
818  template<class ARCHIVE>
819  void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
820  ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
821  ar & BOOST_SERIALIZATION_NVP(k_);
822  }
823  };
824 
826  class GTSAM_EXPORT Tukey : public Base {
827  protected:
828  double c_, csquared_;
829 
830  public:
831  typedef boost::shared_ptr<Tukey> shared_ptr;
832 
833  Tukey(double c = 4.6851, const ReweightScheme reweight = Block);
834  double weight(double error) const {
835  if (std::fabs(error) <= c_) {
836  double xc2 = error*error/csquared_;
837  return (1.0-xc2)*(1.0-xc2);
838  }
839  return 0.0;
840  }
841  void print(const std::string &s) const;
842  bool equals(const Base& expected, double tol=1e-8) const;
843  static shared_ptr Create(double k, const ReweightScheme reweight = Block) ;
844 
845  private:
847  friend class boost::serialization::access;
848  template<class ARCHIVE>
849  void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
850  ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
851  ar & BOOST_SERIALIZATION_NVP(c_);
852  }
853  };
854 
856  class GTSAM_EXPORT Welsh : public Base {
857  protected:
858  double c_, csquared_;
859 
860  public:
861  typedef boost::shared_ptr<Welsh> shared_ptr;
862 
863  Welsh(double c = 2.9846, const ReweightScheme reweight = Block);
864  double weight(double error) const {
865  double xc2 = (error*error)/csquared_;
866  return std::exp(-xc2);
867  }
868  void print(const std::string &s) const;
869  bool equals(const Base& expected, double tol=1e-8) const;
870  static shared_ptr Create(double k, const ReweightScheme reweight = Block) ;
871 
872  private:
874  friend class boost::serialization::access;
875  template<class ARCHIVE>
876  void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
877  ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
878  ar & BOOST_SERIALIZATION_NVP(c_);
879  }
880  };
881 
888  class GTSAM_EXPORT GemanMcClure : public Base {
889  public:
890  typedef boost::shared_ptr<GemanMcClure> shared_ptr;
891 
892  GemanMcClure(double c = 1.0, const ReweightScheme reweight = Block);
893  virtual ~GemanMcClure() {}
894  virtual double weight(double error) const;
895  virtual void print(const std::string &s) const;
896  virtual bool equals(const Base& expected, double tol=1e-8) const;
897  static shared_ptr Create(double k, const ReweightScheme reweight = Block) ;
898 
899  protected:
900  double c_;
901 
902  private:
904  friend class boost::serialization::access;
905  template<class ARCHIVE>
906  void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
907  ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
908  ar & BOOST_SERIALIZATION_NVP(c_);
909  }
910  };
911 
917  class GTSAM_EXPORT DCS : public Base {
918  public:
919  typedef boost::shared_ptr<DCS> shared_ptr;
920 
921  DCS(double c = 1.0, const ReweightScheme reweight = Block);
922  virtual ~DCS() {}
923  virtual double weight(double error) const;
924  virtual void print(const std::string &s) const;
925  virtual bool equals(const Base& expected, double tol=1e-8) const;
926  static shared_ptr Create(double k, const ReweightScheme reweight = Block) ;
927 
928  protected:
929  double c_;
930 
931  private:
933  friend class boost::serialization::access;
934  template<class ARCHIVE>
935  void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
936  ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
937  ar & BOOST_SERIALIZATION_NVP(c_);
938  }
939  };
940 
946  class GTSAM_EXPORT L2WithDeadZone : public Base {
947  protected:
948  double k_;
949 
950  public:
951  typedef boost::shared_ptr<L2WithDeadZone> shared_ptr;
952 
953  L2WithDeadZone(double k, const ReweightScheme reweight = Block);
954  double residual(double error) const {
955  const double abs_error = fabs(error);
956  return (abs_error < k_) ? 0.0 : 0.5*(k_-abs_error)*(k_-abs_error);
957  }
958  double weight(double error) const {
959  // note that this code is slightly uglier than above, because there are three distinct
960  // cases to handle (left of deadzone, deadzone, right of deadzone) instead of the two
961  // cases (deadzone, non-deadzone) above.
962  if (fabs(error) <= k_) return 0.0;
963  else if (error > k_) return (-k_+error)/error;
964  else return (k_+error)/error;
965  }
966  void print(const std::string &s) const;
967  bool equals(const Base& expected, double tol=1e-8) const;
968  static shared_ptr Create(double k, const ReweightScheme reweight = Block);
969 
970  private:
972  friend class boost::serialization::access;
973  template<class ARCHIVE>
974  void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
975  ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
976  ar & BOOST_SERIALIZATION_NVP(k_);
977  }
978  };
979 
980  }
981 
999  class GTSAM_EXPORT Robust : public Base {
1000  public:
1001  typedef boost::shared_ptr<Robust> shared_ptr;
1002 
1003  protected:
1004  typedef mEstimator::Base RobustModel;
1005  typedef noiseModel::Base NoiseModel;
1006 
1007  const RobustModel::shared_ptr robust_;
1008  const NoiseModel::shared_ptr noise_;
1009 
1010  public:
1011 
1013  Robust() {};
1014 
1016  Robust(const RobustModel::shared_ptr robust, const NoiseModel::shared_ptr noise)
1017  : Base(noise->dim()), robust_(robust), noise_(noise) {}
1018 
1020  virtual ~Robust() {}
1021 
1022  virtual void print(const std::string& name) const;
1023  virtual bool equals(const Base& expected, double tol=1e-9) const;
1024 
1026  const RobustModel::shared_ptr& robust() const { return robust_; }
1027 
1029  const NoiseModel::shared_ptr& noise() const { return noise_; }
1030 
1031  // TODO: functions below are dummy but necessary for the noiseModel::Base
1032  inline virtual Vector whiten(const Vector& v) const
1033  { Vector r = v; this->WhitenSystem(r); return r; }
1034  inline virtual Matrix Whiten(const Matrix& A) const
1035  { Vector b; Matrix B=A; this->WhitenSystem(B,b); return B; }
1036  inline virtual Vector unwhiten(const Vector& /*v*/) const
1037  { throw std::invalid_argument("unwhiten is not currently supported for robust noise models."); }
1038  inline virtual double distance(const Vector& v) const
1039  { return this->whiten(v).squaredNorm(); }
1040  // TODO(mike): fold the use of the m-estimator residual(...) function into distance(...)
1041  inline virtual double distance_non_whitened(const Vector& v) const
1042  { return robust_->residual(v.norm()); }
1043  // TODO: these are really robust iterated re-weighting support functions
1044  virtual void WhitenSystem(Vector& b) const;
1045  virtual void WhitenSystem(std::vector<Matrix>& A, Vector& b) const;
1046  virtual void WhitenSystem(Matrix& A, Vector& b) const;
1047  virtual void WhitenSystem(Matrix& A1, Matrix& A2, Vector& b) const;
1048  virtual void WhitenSystem(Matrix& A1, Matrix& A2, Matrix& A3, Vector& b) const;
1049 
1050  static shared_ptr Create(
1051  const RobustModel::shared_ptr &robust, const NoiseModel::shared_ptr noise);
1052 
1053  private:
1055  friend class boost::serialization::access;
1056  template<class ARCHIVE>
1057  void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
1058  ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
1059  ar & boost::serialization::make_nvp("robust_", const_cast<RobustModel::shared_ptr&>(robust_));
1060  ar & boost::serialization::make_nvp("noise_", const_cast<NoiseModel::shared_ptr&>(noise_));
1061  }
1062  };
1063 
1064  // Helper function
1065  GTSAM_EXPORT boost::optional<Vector> checkIfDiagonal(const Matrix M);
1066 
1067  } // namespace noiseModel
1068 
1072  typedef noiseModel::Base::shared_ptr SharedNoiseModel;
1073  typedef noiseModel::Gaussian::shared_ptr SharedGaussian;
1074  typedef noiseModel::Diagonal::shared_ptr SharedDiagonal;
1075  typedef noiseModel::Constrained::shared_ptr SharedConstrained;
1076  typedef noiseModel::Isotropic::shared_ptr SharedIsotropic;
1077 
1079  template<> struct traits<noiseModel::Gaussian> : public Testable<noiseModel::Gaussian> {};
1080  template<> struct traits<noiseModel::Diagonal> : public Testable<noiseModel::Diagonal> {};
1081  template<> struct traits<noiseModel::Constrained> : public Testable<noiseModel::Constrained> {};
1082  template<> struct traits<noiseModel::Isotropic> : public Testable<noiseModel::Isotropic> {};
1083  template<> struct traits<noiseModel::Unit> : public Testable<noiseModel::Unit> {};
1084 
1085 } //\ namespace gtsam
1086 
1087 
const NoiseModel::shared_ptr noise_
noise model used
Definition: NoiseModel.h:1008
virtual void whitenInPlace(Vector &) const
in-place whiten, override if can be done more efficiently
Definition: NoiseModel.h:615
static shared_ptr MixedVariances(const Vector &mu, const Vector &variances)
A diagonal noise model created by specifying a Vector of standard devations, some of which might be z...
Definition: NoiseModel.h:434
noiseModel::Base is the abstract base class for all noise models.
Definition: NoiseModel.h:51
virtual void unwhitenInPlace(Eigen::Block< Vector > &v) const
in-place unwhiten, override if can be done more efficiently
Definition: NoiseModel.h:114
GemanMcClure implements the "Geman-McClure" robust error model (Zhang97ivc).
Definition: NoiseModel.h:888
static shared_ptr MixedSigmas(double m, const Vector &sigmas)
A diagonal noise model created by specifying a Vector of standard devations, some of which might be z...
Definition: NoiseModel.h:426
virtual Matrix Whiten(const Matrix &H) const
Multiply a derivative with R (derivative of whiten) Equivalent to whitening each column of the input ...
Definition: NoiseModel.h:612
const Vector & invsigmas() const
Return sqrt precisions.
Definition: NoiseModel.h:331
double sigma() const
Return standard deviation.
Definition: NoiseModel.h:568
virtual Matrix Whiten(const Matrix &A) const
Whiten a matrix.
Definition: NoiseModel.h:1034
virtual void whitenInPlace(Eigen::Block< Vector > &) const
in-place whiten, override if can be done more efficiently
Definition: NoiseModel.h:617
static shared_ptr Precision(size_t dim, double precision, bool smart=true)
An isotropic noise model created by specifying a precision.
Definition: NoiseModel.h:552
void print(const Matrix &A, const string &s, ostream &stream)
print without optional string, must specify cout yourself
Definition: Matrix.cpp:141
Unit: i.i.d.
Definition: NoiseModel.h:587
static shared_ptr All(size_t dim)
Fully constrained variations.
Definition: NoiseModel.h:460
A diagonal noise model implements a diagonal covariance matrix, with the elements of the diagonal spe...
Definition: NoiseModel.h:270
virtual Vector unwhiten(const Vector &) const
Unwhiten an error vector.
Definition: NoiseModel.h:1036
virtual Matrix R() const
Return R itself, but note that Whiten(H) is cheaper than R*H.
Definition: NoiseModel.h:244
virtual void whitenInPlace(Vector &v) const
in-place whiten, override if can be done more efficiently
Definition: NoiseModel.h:99
Template to create a binary predicate.
Definition: Testable.h:110
Cauchy implements the "Cauchy" robust error model (Lee2013IROS).
Definition: NoiseModel.h:800
Base(size_t dim=1)
primary constructor
Definition: NoiseModel.h:63
Null class is not robust so is a Gaussian ?
Definition: NoiseModel.h:723
An isotropic noise model corresponds to a scaled diagonal covariance To construct,...
Definition: NoiseModel.h:519
A helper that implements the traits interface for GTSAM types.
Definition: Testable.h:150
static shared_ptr All(size_t dim, const Vector &mu)
Fully constrained variations.
Definition: NoiseModel.h:465
Gaussian implements the mathematical model |R*x|^2 = |y|^2 with R'*R=inv(Sigma) where y = whiten(x) =...
Definition: NoiseModel.h:141
virtual bool isUnit() const
true if a unit noise model, saves slow/clumsy dynamic casting
Definition: NoiseModel.h:606
L2WithDeadZone implements a standard L2 penalty, but with a dead zone of width 2*k,...
Definition: NoiseModel.h:946
static shared_ptr MixedPrecisions(const Vector &mu, const Vector &precisions)
A diagonal noise model created by specifying a Vector of precisions, some of which might be inf.
Definition: NoiseModel.h:445
ReweightScheme reweight_
the rows can be weighted independently according to the error or uniformly with the norm of the right...
Definition: NoiseModel.h:659
Welsh implements the "Welsh" robust error model (Zhang97ivc)
Definition: NoiseModel.h:856
virtual Vector unwhiten(const Vector &v) const
Unwhiten an error vector.
Definition: NoiseModel.h:611
Huber implements the "Huber" robust error model (Zhang97ivc)
Definition: NoiseModel.h:770
Definition: NoiseModel.h:651
virtual bool isConstrained() const
true if a constrained noise model, saves slow/clumsy dynamic casting
Definition: NoiseModel.h:67
virtual bool isConstrained() const
true if a constrained noise mode, saves slow/clumsy dynamic casting
Definition: NoiseModel.h:400
static shared_ptr Create(size_t dim)
Create a unit covariance noise model.
Definition: NoiseModel.h:601
const RobustModel::shared_ptr robust_
robust error function used
Definition: NoiseModel.h:1007
virtual Matrix information() const
Compute information matrix.
Definition: NoiseModel.h:247
DCS implements the Dynamic Covariance Scaling robust error model from the paper Robust Map Optimizati...
Definition: NoiseModel.h:917
virtual void whitenInPlace(Eigen::Block< Vector > &v) const
in-place whiten, override if can be done more efficiently
Definition: NoiseModel.h:109
virtual Matrix covariance() const
Compute covariance matrix.
Definition: NoiseModel.h:250
virtual void unwhitenInPlace(Vector &v) const
in-place unwhiten, override if can be done more efficiently
Definition: NoiseModel.h:104
Tukey implements the "Tukey" robust error model (Zhang97ivc)
Definition: NoiseModel.h:826
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition: concepts.h:30
virtual void WhitenInPlace(Eigen::Block< Matrix >) const
In-place version.
Definition: NoiseModel.h:614
static shared_ptr All(size_t dim, double mu)
Fully constrained variations with a mu parameter.
Definition: NoiseModel.h:470
Gaussian(size_t dim=1, const boost::optional< Matrix > &sqrt_information=boost::none)
protected constructor takes square root information matrix
Definition: NoiseModel.h:162
double sigma(size_t i) const
Return standard deviations (sqrt of diagonal)
Definition: NoiseModel.h:326
virtual Vector whiten(const Vector &v) const
Whiten an error vector.
Definition: NoiseModel.h:1032
static shared_ptr Precisions(const Vector &precisions, bool smart=true)
A diagonal noise model created by specifying a Vector of precisions, i.e.
Definition: NoiseModel.h:311
Base class for robust error models The robust M-estimators above simply tell us how to re-weight the ...
Definition: NoiseModel.h:999
Vector sigmas_
Standard deviations (sigmas), their inverse and inverse square (weights/precisions) These are all com...
Definition: NoiseModel.h:278
const NoiseModel::shared_ptr & noise() const
Return the contained noise model.
Definition: NoiseModel.h:1029
Vector sqrtWeight(const Vector &error) const
square root version of the weight function
Definition: NoiseModel.h:702
virtual ~Robust()
Destructor.
Definition: NoiseModel.h:1020
Global functions in a separate testing namespace.
Definition: chartTesting.h:28
Concept check for values that can be used in unit tests.
noiseModel::Base::shared_ptr SharedNoiseModel
Note, deliberately not in noiseModel namespace.
Definition: NoiseModel.h:1072
Robust(const RobustModel::shared_ptr robust, const NoiseModel::shared_ptr noise)
Constructor.
Definition: NoiseModel.h:1016
virtual void WhitenInPlace(Matrix &) const
In-place version.
Definition: NoiseModel.h:613
typedef and functions to augment Eigen's MatrixXd
const Vector & mu() const
Access mu as a vector.
Definition: NoiseModel.h:406
virtual Matrix R() const
Return R itself, but note that Whiten(H) is cheaper than R*H.
Definition: NoiseModel.h:343
const Vector & precisions() const
Return precisions.
Definition: NoiseModel.h:337
Vector mu_
Penalty function weight - needs to be large enough to dominate soft constraints.
Definition: NoiseModel.h:376
virtual void unwhitenInPlace(Eigen::Block< Vector > &) const
in-place unwhiten, override if can be done more efficiently
Definition: NoiseModel.h:618
Robust()
Default Constructor for serialization.
Definition: NoiseModel.h:1013
virtual double Mahalanobis(const Vector &v) const
Mahalanobis distance v'*R'*R*v = <R*v,R*v>
Definition: NoiseModel.h:609
virtual Vector whiten(const Vector &v) const
Whiten an error vector.
Definition: NoiseModel.h:610
A Constrained constrained model is a specialization of Diagonal which allows some or all of the sigma...
Definition: NoiseModel.h:372
virtual bool isUnit() const
true if a unit noise model, saves slow/clumsy dynamic casting
Definition: NoiseModel.h:70
virtual void unwhitenInPlace(Vector &) const
in-place unwhiten, override if can be done more efficiently
Definition: NoiseModel.h:616
virtual Vector sigmas() const
Calculate standard deviations.
Definition: NoiseModel.h:316
size_t dim() const
Dimensionality.
Definition: NoiseModel.h:73
boost::optional< Matrix > sqrt_information_
Matrix square root of information matrix (R)
Definition: NoiseModel.h:146
Fair implements the "Fair" robust error model (Zhang97ivc)
Definition: NoiseModel.h:744
const RobustModel::shared_ptr & robust() const
Return the contained robust error function.
Definition: NoiseModel.h:1026
Isotropic(size_t dim, double sigma)
protected constructor takes sigma
Definition: NoiseModel.h:524
static shared_ptr MixedSigmas(const Vector &sigmas)
A diagonal noise model created by specifying a Vector of standard devations, some of which might be z...
Definition: NoiseModel.h:418