farm-ng-core
orthogonal.h
Go to the documentation of this file.
1 // Copyright (c) 2011, Hauke Strasdat
2 // Copyright (c) 2012, Steven Lovegrove
3 // Copyright (c) 2021, farm-ng, inc.
4 //
5 // Use of this source code is governed by an MIT-style
6 // license that can be found in the LICENSE file or at
7 // https://opensource.org/licenses/MIT.
8 
9 /// @file
10 /// Rotation matrix helper functions.
11 
12 #pragma once
13 
14 #include "sophus/common/common.h"
15 
16 #include <Eigen/Dense>
17 #include <Eigen/SVD>
18 
19 namespace sophus {
20 
21 /// Takes in arbitrary square matrix and returns true if it is
22 /// orthogonal.
23 template <class TD>
24 auto isOrthogonal(Eigen::MatrixBase<TD> const& r) -> bool {
25  using Scalar = typename TD::Scalar;
26  static int const kMatrixDim = TD::RowsAtCompileTime;
27  static int const kM = TD::ColsAtCompileTime;
28 
29  static_assert(kMatrixDim == kM, "must be a square matrix");
30  static_assert(kMatrixDim >= 2, "must have compile time dimension >= 2");
31 
32  return (r * r.transpose() -
33  Eigen::Matrix<Scalar, kMatrixDim, kMatrixDim>::Identity())
34  .norm() < kEpsilonSqrt<Scalar>;
35 }
36 
37 /// Takes in arbitrary square matrix and returns true if it is
38 /// "scaled-orthogonal" with positive determinant.
39 ///
40 template <class TD>
41 auto isScaledOrthogonalAndPositive(Eigen::MatrixBase<TD> const& s_r) -> bool {
42  using Scalar = typename TD::Scalar;
43  static int const kMatrixDim = TD::RowsAtCompileTime;
44  static int const kM = TD::ColsAtCompileTime;
45  using std::pow;
46  using std::sqrt;
47 
48  Scalar det = s_r.determinant();
49 
50  if (det <= Scalar(0)) {
51  return false;
52  }
53 
54  Scalar scale_sqr = pow(det, Scalar(2. / kMatrixDim));
55 
56  static_assert(kMatrixDim == kM, "must be a square matrix");
57  static_assert(kMatrixDim >= 2, "must have compile time dimension >= 2");
58 
59  return (s_r * s_r.transpose() -
60  scale_sqr * Eigen::Matrix<Scalar, kMatrixDim, kMatrixDim>::Identity())
61  .template lpNorm<Eigen::Infinity>() < sqrt(kEpsilon<Scalar>);
62 }
63 
64 /// Takes in arbitrary square matrix (2x2 or larger) and returns closest
65 /// orthogonal matrix with positive determinant.
66 template <class TD>
67 auto makeRotationMatrix(Eigen::MatrixBase<TD> const& r) -> std::enable_if_t<
68  std::is_floating_point<typename TD::Scalar>::value,
69  Eigen::Matrix<
70  typename TD::Scalar,
71  TD::RowsAtCompileTime,
72  TD::RowsAtCompileTime>> {
73  using Scalar = typename TD::Scalar;
74  static int const kMatrixDim = TD::RowsAtCompileTime;
75  static int const kM = TD::ColsAtCompileTime;
76 
77  static_assert(kMatrixDim == kM, "must be a square matrix");
78  static_assert(kMatrixDim >= 2, "must have compile time dimension >= 2");
79 
80  Eigen::JacobiSVD<Eigen::Matrix<Scalar, kMatrixDim, kMatrixDim>> svd(
81  r, Eigen::ComputeFullU | Eigen::ComputeFullV);
82 
83  // Determine determinant of orthogonal matrix U*V'.
84  Scalar d = (svd.matrixU() * svd.matrixV().transpose()).determinant();
85  // Starting from the identity matrix D, set the last entry to d (+1 or
86  // -1), so that det(U*D*V') = 1.
87  Eigen::Matrix<Scalar, kMatrixDim, kMatrixDim> diag =
88  Eigen::Matrix<Scalar, kMatrixDim, kMatrixDim>::Identity();
89  diag(kMatrixDim - 1, kMatrixDim - 1) = d;
90  return svd.matrixU() * diag * svd.matrixV().transpose();
91 }
92 
93 } // namespace sophus
sophus::isScaledOrthogonalAndPositive
auto isScaledOrthogonalAndPositive(Eigen::MatrixBase< TD > const &s_r) -> bool
Takes in arbitrary square matrix and returns true if it is "scaled-orthogonal" with positive determin...
Definition: orthogonal.h:41
sophus
Image MutImage, owning images types.
Definition: num_diff.h:20
sophus::makeRotationMatrix
auto makeRotationMatrix(Eigen::MatrixBase< TD > const &r) -> std::enable_if_t< std::is_floating_point< typename TD::Scalar >::value, Eigen::Matrix< typename TD::Scalar, TD::RowsAtCompileTime, TD::RowsAtCompileTime >>
Takes in arbitrary square matrix (2x2 or larger) and returns closest orthogonal matrix with positive ...
Definition: orthogonal.h:67
common.h
sophus::isOrthogonal
auto isOrthogonal(Eigen::MatrixBase< TD > const &r) -> bool
Takes in arbitrary square matrix and returns true if it is orthogonal.
Definition: orthogonal.h:24