SOn.h
Go to the documentation of this file.
1 /* ----------------------------------------------------------------------------
2 
3  * GTSAM Copyright 2010-2019, 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/Lie.h>
22 #include <gtsam/base/Manifold.h>
23 #include <gtsam/base/make_shared.h>
24 #include <gtsam/dllexport.h>
25 #include <Eigen/Core>
26 
27 #include <iostream> // TODO(frank): how to avoid?
28 #include <string>
29 #include <type_traits>
30 #include <vector>
31 #include <random>
32 
33 namespace gtsam {
34 
35 namespace internal {
37 constexpr int DimensionSO(int N) {
38  return (N < 0) ? Eigen::Dynamic : N * (N - 1) / 2;
39 }
40 
41 // Calculate N^2 at compile time, or return Dynamic if so
42 constexpr int NSquaredSO(int N) { return (N < 0) ? Eigen::Dynamic : N * N; }
43 } // namespace internal
44 
49 template <int N>
50 class SO : public LieGroup<SO<N>, internal::DimensionSO(N)> {
51  public:
52  enum { dimension = internal::DimensionSO(N) };
56 
58 
59  protected:
60  MatrixNN matrix_;
61 
62  // enable_if_t aliases, used to specialize constructors/methods, see
63  // https://www.fluentcpp.com/2018/05/18/make-sfinae-pretty-2-hidden-beauty-sfinae/
64  template <int N_>
65  using IsDynamic = typename std::enable_if<N_ == Eigen::Dynamic, void>::type;
66  template <int N_>
67  using IsFixed = typename std::enable_if<N_ >= 2, void>::type;
68  template <int N_>
69  using IsSO3 = typename std::enable_if<N_ == 3, void>::type;
70 
71  public:
74 
76  template <int N_ = N, typename = IsFixed<N_>>
77  SO() : matrix_(MatrixNN::Identity()) {}
78 
80  template <int N_ = N, typename = IsDynamic<N_>>
81  explicit SO(size_t n = 0) {
82  // We allow for n=0 as the default constructor, needed for serialization,
83  // wrappers etc.
84  matrix_ = Eigen::MatrixXd::Identity(n, n);
85  }
86 
88  template <typename Derived>
89  explicit SO(const Eigen::MatrixBase<Derived>& R) : matrix_(R.eval()) {}
90 
92  template <typename Derived>
94  return SO(R);
95  }
96 
98  template <typename Derived, int N_ = N, typename = IsDynamic<N_>>
99  static SO Lift(size_t n, const Eigen::MatrixBase<Derived> &R) {
100  Matrix Q = Matrix::Identity(n, n);
101  const int p = R.rows();
102  assert(p >= 0 && p <= static_cast<int>(n) && R.cols() == p);
103  Q.topLeftCorner(p, p) = R;
104  return SO(Q);
105  }
106 
108  template <int M, int N_ = N, typename = IsDynamic<N_>>
109  explicit SO(const SO<M>& R) : matrix_(R.matrix()) {}
110 
112  template <int N_ = N, typename = IsSO3<N_>>
113  explicit SO(const Eigen::AngleAxisd& angleAxis) : matrix_(angleAxis) {}
114 
116  static SO AxisAngle(const Vector3& axis, double theta);
117 
120  static SO ClosestTo(const MatrixNN& M);
121 
124  static SO ChordalMean(const std::vector<SO>& rotations);
125 
127  template <int N_ = N, typename = IsDynamic<N_>>
128  static SO Random(std::mt19937& rng, size_t n = 0) {
129  if (n == 0) throw std::runtime_error("SO: Dimensionality not known.");
130  // TODO(frank): this might need to be re-thought
131  static std::uniform_real_distribution<double> randomAngle(-M_PI, M_PI);
132  const size_t d = SO::Dimension(n);
133  Vector xi(d);
134  for (size_t j = 0; j < d; j++) {
135  xi(j) = randomAngle(rng);
136  }
137  return SO::Retract(xi);
138  }
139 
141  template <int N_ = N, typename = IsFixed<N_>>
142  static SO Random(std::mt19937& rng) {
143  // By default, use dynamic implementation above. Specialized for SO(3).
144  return SO(SO<Eigen::Dynamic>::Random(rng, N).matrix());
145  }
146 
150 
152  const MatrixNN& matrix() const { return matrix_; }
153 
154  size_t rows() const { return matrix_.rows(); }
155  size_t cols() const { return matrix_.cols(); }
156 
160 
161  void print(const std::string& s = std::string()) const;
162 
163  bool equals(const SO& other, double tol) const {
164  return equal_with_abs_tol(matrix_, other.matrix_, tol);
165  }
166 
170 
172  SO operator*(const SO& other) const {
173  assert(dim() == other.dim());
174  return SO(matrix_ * other.matrix_);
175  }
176 
178  template <int N_ = N, typename = IsFixed<N_>>
179  static SO identity() {
180  return SO();
181  }
182 
184  template <int N_ = N, typename = IsDynamic<N_>>
185  static SO identity(size_t n = 0) {
186  return SO(n);
187  }
188 
190  SO inverse() const { return SO(matrix_.transpose()); }
191 
195 
198 
200  static int Dim() { return dimension; }
201 
202  // Calculate manifold dimensionality for SO(n).
203  // Available as dimension or Dim() for fixed N.
204  static size_t Dimension(size_t n) { return n * (n - 1) / 2; }
205 
206  // Calculate ambient dimension n from manifold dimensionality d.
207  static size_t AmbientDim(size_t d) { return (1 + std::sqrt(1 + 8 * d)) / 2; }
208 
209  // Calculate run-time dimensionality of manifold.
210  // Available as dimension or Dim() for fixed N.
211  size_t dim() const { return Dimension(static_cast<size_t>(matrix_.rows())); }
212 
228  static MatrixNN Hat(const TangentVector& xi);
229 
231  static void Hat(const Vector &xi, Eigen::Ref<MatrixNN> X);
232 
234  static TangentVector Vee(const MatrixNN& X);
235 
236  // Chart at origin
237  struct ChartAtOrigin {
242  static SO Retract(const TangentVector& xi, ChartJacobian H = boost::none);
243 
247  static TangentVector Local(const SO& R, ChartJacobian H = boost::none);
248  };
249 
250  // Return dynamic identity DxD Jacobian for given SO(n)
251  template <int N_ = N, typename = IsDynamic<N_>>
252  static MatrixDD IdentityJacobian(size_t n) {
253  const size_t d = Dimension(n);
254  return MatrixDD::Identity(d, d);
255  }
256 
260 
262  MatrixDD AdjointMap() const;
263 
267  static SO Expmap(const TangentVector& omega, ChartJacobian H = boost::none);
268 
270  static MatrixDD ExpmapDerivative(const TangentVector& omega);
271 
275  static TangentVector Logmap(const SO& R, ChartJacobian H = boost::none);
276 
278  static MatrixDD LogmapDerivative(const TangentVector& omega);
279 
280  // inverse with optional derivative
282 
286 
293  boost::none) const;
294 
296  template <int N_ = N, typename = IsFixed<N_>>
298  constexpr size_t N2 = static_cast<size_t>(N * N);
300  for (size_t j = 0; j < dimension; j++) {
301  const auto X = Hat(Vector::Unit(dimension, j));
302  G.col(j) = Eigen::Map<const VectorN2>(X.data());
303  }
304  return G;
305  }
306 
308  template <int N_ = N, typename = IsDynamic<N_>>
309  static Matrix VectorizedGenerators(size_t n = 0) {
310  const size_t n2 = n * n, dim = Dimension(n);
311  Matrix G(n2, dim);
312  for (size_t j = 0; j < dim; j++) {
313  const auto X = Hat(Vector::Unit(dim, j));
314  G.col(j) = Eigen::Map<const Matrix>(X.data(), n2, 1);
315  }
316  return G;
317  }
318 
322 
323  template <class Archive>
324  friend void save(Archive&, SO&, const unsigned int);
325  template <class Archive>
326  friend void load(Archive&, SO&, const unsigned int);
327  template <class Archive>
328  friend void serialize(Archive&, SO&, const unsigned int);
329  friend class boost::serialization::access;
330  friend class Rot3; // for serialize
331 
333 };
334 
336 
337 /*
338  * Specialize dynamic Hat and Vee, because recursion depends on dynamic nature.
339  * The definition is in SOn.cpp. Fixed-size SO3 and SO4 have their own version,
340  * and implementation for other fixed N is in SOn-inl.h.
341  */
342 
343 template <>
344 GTSAM_EXPORT
345 Matrix SOn::Hat(const Vector& xi);
346 
347 template <>
348 GTSAM_EXPORT
349 Vector SOn::Vee(const Matrix& X);
350 
351 /*
352  * Specialize dynamic compose and between, because the derivative is unknowable
353  * by the LieGroup implementations, who return a fixed-size matrix for H2.
354  */
355 
357 
358 template <>
360  DynamicJacobian H2) const;
361 
362 template <>
364  DynamicJacobian H2) const;
365 
366 /*
367  * Specialize dynamic vec.
368  */
369 template <> typename SOn::VectorN2 SOn::vec(DynamicJacobian H) const;
370 
372 template<class Archive>
374  Archive& ar, SOn& Q,
375  const unsigned int file_version
376 ) {
377  Matrix& M = Q.matrix_;
378  ar& BOOST_SERIALIZATION_NVP(M);
379 }
380 
381 /*
382  * Define the traits. internal::LieGroup provides both Lie group and Testable
383  */
384 
385 template <int N>
386 struct traits<SO<N>> : public internal::LieGroup<SO<N>> {};
387 
388 template <int N>
389 struct traits<const SO<N>> : public internal::LieGroup<SO<N>> {};
390 
391 } // namespace gtsam
392 
393 #include "SOn-inl.h"
void print(const Matrix &A, const string &s, ostream &stream)
Definition: Matrix.cpp:155
static MatrixNN Hat(const TangentVector &xi)
Definition: SOn-inl.h:29
static int Dim()
Return compile-time dimensionality: fixed size N or Eigen::Dynamic.
Definition: SOn.h:200
Matrix< RealScalar, Dynamic, Dynamic > M
Definition: bench_gemm.cpp:38
void save(const Matrix &A, const string &s, const string &filename)
Definition: Matrix.cpp:166
VectorN2 vec(OptionalJacobian< internal::NSquaredSO(N), dimension > H=boost::none) const
Definition: SOn-inl.h:88
Eigen::Vector3d Vector3
Definition: Vector.h:43
make_shared trampoline function to ensure proper alignment
std::string serialize(const T &input)
serializes to a string
JacobiRotation< float > G
static SO identity(size_t n=0)
SO<N> identity for N == Eigen::Dynamic.
Definition: SOn.h:185
A matrix or vector expression mapping an existing array of data.
Definition: Map.h:94
Template implementations for SO(n)
size_t cols() const
Definition: SOn.h:155
typename std::enable_if< N_==3, void >::type IsSO3
Definition: SOn.h:69
EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL EIGEN_DEVICE_FUNC BlockXpr topLeftCorner(Index cRows, Index cCols)
Definition: DenseBase.h:179
SO operator*(const SO &other) const
Multiplication.
Definition: SOn.h:172
static std::mt19937 rng
size_t dim() const
Definition: SOn.h:211
int n
Eigen::MatrixXd Matrix
Definition: base/Matrix.h:43
#define M_PI
Definition: main.h:78
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar * data() const
Rot2 R(Rot2::fromAngle(0.1))
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
static Matrix VectorizedGenerators()
Calculate N^2 x dim matrix of vectorized Lie algebra generators for SO(N)
Definition: SOn.h:297
Namespace containing all symbols from the Eigen library.
Definition: jet.h:637
Pose2_ Expmap(const Vector3_ &xi)
Definition: Half.h:150
const MatrixNN & matrix() const
Return matrix.
Definition: SOn.h:152
static size_t Dimension(size_t n)
Definition: SOn.h:204
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set set set set surface set nocontour set clabel set mapping cartesian set nohidden3d set cntrparam order set cntrparam linear set cntrparam levels auto set cntrparam points set size set set xzeroaxis lt lw set x2zeroaxis lt lw set yzeroaxis lt lw set y2zeroaxis lt lw set tics in set ticslevel set tics set mxtics default set mytics default set mx2tics default set my2tics default set xtics border mirror norotate autofreq set ytics border mirror norotate autofreq set ztics border nomirror norotate autofreq set nox2tics set noy2tics set timestamp bottom norotate set rrange[*:*] noreverse nowriteback set trange[*:*] noreverse nowriteback set urange[*:*] noreverse nowriteback set vrange[*:*] noreverse nowriteback set xlabel matrix size set x2label set timefmt d m y n H
#define N
Definition: gksort.c:12
SO inverse() const
inverse of a rotation = transpose
Definition: SOn.h:190
SO(const SO< M > &R)
Construct dynamic SO(n) from Fixed SO<M>
Definition: SOn.h:109
constexpr int DimensionSO(int N)
Calculate dimensionality of SO<N> manifold, or return Dynamic if so.
Definition: SOn.h:37
Rot2 theta
Definition: SOn.h:50
static Matrix VectorizedGenerators(size_t n=0)
Calculate n^2 x dim matrix of vectorized Lie algebra generators for SO(n)
Definition: SOn.h:309
void g(const string &key, int i)
Definition: testBTree.cpp:43
constexpr int NSquaredSO(int N)
Definition: SOn.h:42
#define GTSAM_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
Definition: types.h:278
MatrixNN matrix_
Rotation matrix.
Definition: SOn.h:60
static size_t AmbientDim(size_t d)
Definition: SOn.h:207
Class compose(const Class &g) const
Definition: Lie.h:47
Eigen::VectorXd Vector
Definition: Vector.h:38
size_t rows() const
Definition: SOn.h:154
Base class and basic functions for Manifold types.
static SO identity()
SO<N> identity for N >= 2.
Definition: SOn.h:179
static SO Random(std::mt19937 &rng, size_t n=0)
Random SO(n) element (no big claims about uniformity). SO(3) is specialized in SO3.cpp.
Definition: SOn.h:128
RealScalar s
typename std::enable_if< N_ >=2, void >::type IsFixed
Definition: SOn.h:67
SO(const Eigen::MatrixBase< Derived > &R)
Constructor from Eigen Matrix, dynamic version.
Definition: SOn.h:89
SO(const Eigen::AngleAxisd &angleAxis)
Constructor from AngleAxisd.
Definition: SOn.h:113
Base class and basic functions for Lie types.
bool equal_with_abs_tol(const Eigen::DenseBase< MATRIX > &A, const Eigen::DenseBase< MATRIX > &B, double tol=1e-9)
Definition: base/Matrix.h:84
Vector xi
Definition: testPose2.cpp:150
static SO FromMatrix(const Eigen::MatrixBase< Derived > &R)
Named constructor from Eigen Matrix.
Definition: SOn.h:93
A matrix or vector expression mapping an existing expression.
Definition: Ref.h:192
const mpreal dim(const mpreal &a, const mpreal &b, mp_rnd_t r=mpreal::get_default_rnd())
Definition: mpreal.h:2201
traits
Definition: chartTesting.h:28
static SO Lift(size_t n, const Eigen::MatrixBase< Derived > &R)
Named constructor from lower dimensional matrix.
Definition: SOn.h:99
Both LieGroupTraits and Testable.
Definition: Lie.h:228
The quaternion class used to represent 3D orientations and rotations.
float * p
Class between(const Class &g) const
Definition: Lie.h:51
static SO< N > Retract(const TangentVector &v)
Retract at origin: possible in Lie group because it has an identity.
Definition: Lie.h:110
static SO Random(std::mt19937 &rng)
Random SO(N) element (no big claims about uniformity)
Definition: SOn.h:142
internal::nested_eval< T, 1 >::type eval(const T &xpr)
static MatrixDD IdentityJacobian(size_t n)
Definition: SOn.h:252
const G double tol
Definition: Group.h:83
const int Dynamic
Definition: Constants.h:21
SO(size_t n=0)
Construct SO<N> identity for N == Eigen::Dynamic.
Definition: SOn.h:81
void load(Archive &ar, Eigen::Matrix< Scalar_, Rows_, Cols_, Ops_, MaxRows_, MaxCols_ > &m, const unsigned int)
Definition: base/Matrix.h:573
Map< Matrix< T, Dynamic, Dynamic, ColMajor >, 0, OuterStride<> > matrix(T *data, int rows, int cols, int stride)
#define X
Definition: icosphere.cpp:20
static TangentVector Vee(const MatrixNN &X)
Inverse of Hat. See note about xi element order in Hat.
Definition: SOn-inl.h:35
bool equals(const SO &other, double tol) const
Definition: SOn.h:163
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:48
Represents a 3D rotation as a rotation angle around an arbitrary 3D axis.
typename std::enable_if< N_==Eigen::Dynamic, void >::type IsDynamic
Definition: SOn.h:65
EIGEN_DEVICE_FUNC const InverseReturnType inverse() const
std::ptrdiff_t j
Definition: pytypes.h:897


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:44:17