farm-ng-core
spiral_similarity2.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 #pragma once
15 
16 namespace sophus {
17 namespace lie {
18 
19 template <class TScalar>
21  public:
22  using Scalar = TScalar;
24 
25  static bool constexpr kIsOriginPreserving = true;
26  static bool constexpr kIsAxisDirectionPreserving = false;
27  static bool constexpr kIsDirectionVectorPreserving = false;
28  static bool constexpr kIsShapePreserving = false;
29  static bool constexpr kIisSizePreserving = true;
30  static bool constexpr kIisParallelLinePreserving = true;
31 
32  static int const kDof = 2;
33  static int const kNumParams = 2;
34  static int const kPointDim = 2;
35  static int const kAmbientDim = 2;
36 
37  using Tangent = Eigen::Vector<Scalar, kDof>;
38  using Params = Eigen::Vector<Scalar, kNumParams>;
39  using Point = Eigen::Vector<Scalar, kPointDim>;
40 
41  template <class TCompatibleScalar>
42  using ScalarReturn = typename Eigen::
43  ScalarBinaryOpTraits<Scalar, TCompatibleScalar>::ReturnType;
44 
45  template <class TCompatibleScalar>
46  using ParamsReturn =
47  Eigen::Vector<ScalarReturn<TCompatibleScalar>, kNumParams>;
48 
49  template <class TCompatibleScalar>
50  using PointReturn = Eigen::Vector<ScalarReturn<TCompatibleScalar>, kPointDim>;
51 
52  template <class TCompatibleScalar>
53  using UnitVectorReturn =
55 
56  // constructors and factories
57 
58  static auto identityParams() -> Params {
59  return Eigen::Vector<Scalar, 2>(1.0, 0.0);
60  }
61 
62  static auto areParamsValid(Params const& non_zero_complex)
63  -> sophus::Expected<Success> {
64  static const Scalar kThr = kEpsilon<Scalar> * kEpsilon<Scalar>;
65  const Scalar squared_norm = non_zero_complex.squaredNorm();
66  using std::abs;
67  if (!(squared_norm > kThr || squared_norm < 1.0 / kThr)) {
68  return SOPHUS_UNEXPECTED(
69  "complex number ({}, {}) is too large or too small.\n"
70  "Squared norm: {}, thr: {}",
71  non_zero_complex[0],
72  non_zero_complex[1],
73  squared_norm,
74  kThr);
75  }
76  return sophus::Expected<Success>{};
77  }
78 
79  static auto hasShortestPathAmbiguity(Params const& non_zero_complex) -> bool {
81  non_zero_complex.normalized());
82  }
83 
84  // Manifold / Lie Group concepts
85 
86  static auto exp(Tangent const& angle_logscale) -> Params {
87  using std::exp;
88  using std::max;
89  using std::min;
90 
91  Scalar const sigma = angle_logscale[1];
92  Scalar s = exp(sigma);
93  // Ensuring proper scale
94  s = max(s, kEpsilonPlus<Scalar>);
95  s = min(s, Scalar(1.) / kEpsilonPlus<Scalar>);
96  Eigen::Vector2<Scalar> z =
97  Rotation2Impl<Scalar>::exp(angle_logscale.template head<1>());
98  z *= s;
99  return z;
100  }
101 
102  static auto log(Params const& complex) -> Tangent {
103  using std::log;
104  Tangent theta_sigma;
105  theta_sigma[0] =
106  Eigen::Vector<Scalar, 1>{atan2(complex.y(), complex.x())}[0];
107  theta_sigma[1] = log(complex.norm());
108  return theta_sigma;
109  }
110 
111  static auto hat(Tangent const& angle_logscale)
112  -> Eigen::Matrix<Scalar, kAmbientDim, kAmbientDim> {
113  return Eigen::Matrix<Scalar, 2, 2>{
114  {angle_logscale[1], -angle_logscale[0]},
115  {angle_logscale[0], angle_logscale[1]}};
116  }
117 
118  static auto vee(Eigen::Matrix<Scalar, kAmbientDim, kAmbientDim> const& mat)
119  -> Eigen::Matrix<Scalar, kDof, 1> {
120  return Eigen::Matrix<Scalar, kDof, 1>{mat(1, 0), mat(0, 0)};
121  }
122 
123  // group operations
124 
125  static auto inverse(Params const& non_zero_complex) -> Params {
126  Scalar squared_scale = non_zero_complex.squaredNorm();
127  return Params(
128  non_zero_complex.x() / squared_scale,
129  -non_zero_complex.y() / squared_scale);
130  }
131 
132  template <class TCompatibleScalar>
133  static auto multiplication(
134  Params const& lhs_params,
135  Eigen::Vector<TCompatibleScalar, kNumParams> const& rhs_params)
137  auto result = Complex::multiplication(lhs_params, rhs_params);
139  ScalarReturn const squared_scale = result.squaredNorm();
140 
141  if (squared_scale < kEpsilon<Scalar> * kEpsilon<Scalar>) {
142  /// Saturation to ensure class invariant.
143  result.normalize();
144  result *= kEpsilonPlus<ScalarReturn>;
145  }
146  if (squared_scale >
147  Scalar(1.) / (kEpsilon<ScalarReturn> * kEpsilon<ScalarReturn>)) {
148  /// Saturation to ensure class invariant.
149  result.normalize();
150  result /= kEpsilonPlus<ScalarReturn>;
151  }
152  return result;
153  }
154 
155  // Group actions
156  template <class TCompatibleScalar>
157  static auto action(
158  Params const& non_zero_complex,
159  Eigen::Vector<TCompatibleScalar, kPointDim> const& point)
161  return matrix(non_zero_complex) * point;
162  }
163 
164  static auto toAmbient(Point const& point)
165  -> Eigen::Vector<Scalar, kAmbientDim> {
166  return point;
167  }
168 
169  template <class TCompatibleScalar>
170  static auto action(
171  Params const& non_zero_complex,
172  UnitVector<TCompatibleScalar, kPointDim> const& direction_vector)
175  Rotation2Impl<Scalar>::matrix(non_zero_complex.normalized()) *
176  direction_vector.params());
177  }
178 
179  static auto adj(Params const& /*unused*/)
180  -> Eigen::Matrix<Scalar, kDof, kDof> {
181  return Eigen::Matrix<Scalar, 2, 2>::Identity();
182  }
183 
184  // matrices
185 
186  static auto compactMatrix(Params const& non_zero_complex)
187  -> Eigen::Matrix<Scalar, kPointDim, kPointDim> {
188  return Eigen::Matrix<Scalar, 2, 2>{
189  {Scalar(non_zero_complex.x()), Scalar(-non_zero_complex.y())},
190  {Scalar(non_zero_complex.y()), Scalar(non_zero_complex.x())}};
191  }
192 
193  static auto matrix(Params const& non_zero_complex)
194  -> Eigen::Matrix<Scalar, kPointDim, kPointDim> {
195  return compactMatrix(non_zero_complex);
196  }
197 
198  // Sub-group concepts
199  static auto matV(Params const&, Tangent const& angle_logscale)
200  -> Eigen::Matrix<Scalar, kPointDim, kPointDim> {
201  return details::calcW<Scalar, 2>(
202  Rotation2Impl<Scalar>::hat(angle_logscale.template head<1>()),
203  angle_logscale[0],
204  angle_logscale[1]);
205  }
206 
207  static auto matVInverse(
208  Params const& non_zero_complex, Tangent const& angle_logscale)
209  -> Eigen::Matrix<Scalar, kPointDim, kPointDim> {
210  return details::calcWInv<Scalar, 2>(
211  Rotation2Impl<Scalar>::hat(angle_logscale.template head<1>()),
212  angle_logscale[0],
213  angle_logscale[1],
214  non_zero_complex.norm());
215  }
216 
217  static auto adjOfTranslation(Params const& /*unused*/, Point const& point)
218  -> Eigen::Matrix<Scalar, kPointDim, kDof> {
219  return Eigen::Matrix<Scalar, 2, 2>{
220  {point[1], -point[0]}, {-point[0], -point[1]}};
221  }
222 
223  static auto adOfTranslation(Point const& point)
224  -> Eigen::Matrix<Scalar, kPointDim, kDof> {
225  Eigen::Matrix<Scalar, 2, 2> mat;
226  mat.col(0) = Eigen::Vector2<Scalar>(point[1], -point[0]);
227  mat.col(1) = -point;
228  return mat;
229  }
230 
231  // derivatives
232 
233  static auto ad(Tangent const& /*unused*/)
234  -> Eigen::Matrix<Scalar, kDof, kDof> {
235  return Eigen::Matrix<Scalar, 2, 2>::Zero();
236  }
237 
238  static auto dxExpX(Tangent const& a)
239  -> Eigen::Matrix<Scalar, kNumParams, kDof> {
240  using std::cos;
241  using std::exp;
242  using std::sin;
243  Scalar const theta = a[0];
244  Scalar const sigma = a[1];
245 
246  Eigen::Matrix<Scalar, 2, 2> d;
247  // clang-format off
248  d << -sin(theta), cos(theta),
249  cos(theta), sin(theta);
250  // clang-format on
251  return d * exp(sigma);
252  }
253 
254  static auto dxExpXAt0() -> Eigen::Matrix<Scalar, kNumParams, kDof> {
255  Eigen::Matrix<Scalar, 2, 2> d;
256  Scalar const i(1.);
257  Scalar const o(0.);
258  // clang-format off
259  d << o, i,
260  i, o;
261  // clang-format on
262  return d;
263  }
264 
265  static auto dxExpXTimesPointAt0(Point const& point)
266  -> Eigen::Matrix<Scalar, kPointDim, kDof> {
267  Eigen::Matrix<Scalar, 2, 2> d;
268  d << Rotation2Impl<Scalar>::dxExpXTimesPointAt0(point), point;
269  return d;
270  }
271 
272  static auto dxThisMulExpXAt0(Params const& non_zero_complex)
273  -> Eigen::Matrix<Scalar, kNumParams, kDof> {
274  Eigen::Matrix<Scalar, 2, 2> d;
275  // clang-format off
276  d << -non_zero_complex.y(), non_zero_complex.x(),
277  non_zero_complex.x(), non_zero_complex.y();
278  // clang-format on
279  return d;
280  }
281 
282  static auto dxLogThisInvTimesXAtThis(Params const& non_zero_complex)
283  -> Eigen::Matrix<Scalar, kDof, kNumParams> {
284  Eigen::Matrix<Scalar, 2, 2> d;
285  const Scalar norm_sq_inv = Scalar(1.) / non_zero_complex.squaredNorm();
286  // clang-format off
287  d << -non_zero_complex.y(), non_zero_complex.x(),
288  non_zero_complex.x(), non_zero_complex.y();
289  // clang-format on
290  return d * norm_sq_inv;
291  }
292 
293  // for tests
294 
295  static auto tangentExamples() -> std::vector<Tangent> {
296  return std::vector<Tangent>({
297  Tangent{0.2, 1},
298  Tangent{0.2, 1.1},
299  Tangent{0.0, 1.1},
300  Tangent{0.00001, 0},
301  Tangent{0.00001, 0.00001},
302  Tangent{0.5 * kPi<Scalar>, 0.9},
303  Tangent{0.5 * kPi<Scalar> + 0.00001, 0.2},
304  });
305  }
306 
307  static auto paramsExamples() -> std::vector<Params> {
308  return std::vector<Params>({
309  SpiralSimilarity2Impl::exp({0.2, 1}),
310  SpiralSimilarity2Impl::exp({0.2, 1.1}),
311  SpiralSimilarity2Impl::exp({0.0, 1.1}),
312  SpiralSimilarity2Impl::exp({0.00001, 0}),
313  SpiralSimilarity2Impl::exp({0.00001, 0.00001}),
314  SpiralSimilarity2Impl::exp({0.5 * kPi<Scalar>, 0.9}),
315  SpiralSimilarity2Impl::exp({0.5 * kPi<Scalar> + 0.00001, 0.2}),
316  });
317  }
318 
319  static auto invalidParamsExamples() -> std::vector<Params> {
320  return std::vector<Params>({
321  Params::Zero(),
322  -Params::Ones(),
323  -Params::UnitX(),
324  });
325  }
326 };
327 
328 } // namespace lie
329 } // namespace sophus
sophus::lie::SpiralSimilarity2Impl::kIsDirectionVectorPreserving
static constexpr bool kIsDirectionVectorPreserving
Definition: spiral_similarity2.h:27
sophus::lie::SpiralSimilarity2Impl::kPointDim
static const int kPointDim
Definition: spiral_similarity2.h:34
sophus::lie::SpiralSimilarity2Impl::action
static auto action(Params const &non_zero_complex, Eigen::Vector< TCompatibleScalar, kPointDim > const &point) -> PointReturn< TCompatibleScalar >
Definition: spiral_similarity2.h:157
sim_mat_w.h
lie_group.h
sophus::lie::SpiralSimilarity2Impl::matV
static auto matV(Params const &, Tangent const &angle_logscale) -> Eigen::Matrix< Scalar, kPointDim, kPointDim >
Definition: spiral_similarity2.h:199
sophus::lie::SpiralSimilarity2Impl::paramsExamples
static auto paramsExamples() -> std::vector< Params >
Definition: spiral_similarity2.h:307
sophus::lie::SpiralSimilarity2Impl::matrix
static auto matrix(Params const &non_zero_complex) -> Eigen::Matrix< Scalar, kPointDim, kPointDim >
Definition: spiral_similarity2.h:193
sophus::lie::SpiralSimilarity2Impl::hasShortestPathAmbiguity
static auto hasShortestPathAmbiguity(Params const &non_zero_complex) -> bool
Definition: spiral_similarity2.h:79
sophus::lie::SpiralSimilarity2Impl::dxExpXTimesPointAt0
static auto dxExpXTimesPointAt0(Point const &point) -> Eigen::Matrix< Scalar, kPointDim, kDof >
Definition: spiral_similarity2.h:265
sophus::lie::SpiralSimilarity2Impl::PointReturn
Eigen::Vector< ScalarReturn< TCompatibleScalar >, kPointDim > PointReturn
Definition: spiral_similarity2.h:50
sophus::lie::SpiralSimilarity2Impl::Tangent
Eigen::Vector< Scalar, kDof > Tangent
Definition: spiral_similarity2.h:37
sophus::UnitVector
Definition: lie_group.h:14
sophus
Image MutImage, owning images types.
Definition: num_diff.h:20
sophus::lie::SpiralSimilarity2Impl::kAmbientDim
static const int kAmbientDim
Definition: spiral_similarity2.h:35
sophus::min
auto min(TPoint const &a, TPoint const &b) -> TPoint
Definition: vector_space.h:104
sophus::lie::SpiralSimilarity2Impl::ParamsReturn
Eigen::Vector< ScalarReturn< TCompatibleScalar >, kNumParams > ParamsReturn
Definition: spiral_similarity2.h:47
sophus::lie::SpiralSimilarity2Impl::invalidParamsExamples
static auto invalidParamsExamples() -> std::vector< Params >
Definition: spiral_similarity2.h:319
sophus::lie::SpiralSimilarity2Impl::kIsOriginPreserving
static constexpr bool kIsOriginPreserving
Definition: spiral_similarity2.h:25
sophus::lie::SpiralSimilarity2Impl::identityParams
static auto identityParams() -> Params
Definition: spiral_similarity2.h:58
sophus::lie::SpiralSimilarity2Impl::kDof
static const int kDof
Definition: spiral_similarity2.h:32
sophus::lie::SpiralSimilarity2Impl::Point
Eigen::Vector< Scalar, kPointDim > Point
Definition: spiral_similarity2.h:39
sophus::lie::SpiralSimilarity2Impl::kNumParams
static const int kNumParams
Definition: spiral_similarity2.h:33
sophus::ComplexImpl
Definition: complex.h:17
sophus::lie::SpiralSimilarity2Impl::adOfTranslation
static auto adOfTranslation(Point const &point) -> Eigen::Matrix< Scalar, kPointDim, kDof >
Definition: spiral_similarity2.h:223
sophus::lie::SpiralSimilarity2Impl::ad
static auto ad(Tangent const &) -> Eigen::Matrix< Scalar, kDof, kDof >
Definition: spiral_similarity2.h:233
sophus::lie::SpiralSimilarity2Impl::vee
static auto vee(Eigen::Matrix< Scalar, kAmbientDim, kAmbientDim > const &mat) -> Eigen::Matrix< Scalar, kDof, 1 >
Definition: spiral_similarity2.h:118
sophus::lie::SpiralSimilarity2Impl::adj
static auto adj(Params const &) -> Eigen::Matrix< Scalar, kDof, kDof >
Definition: spiral_similarity2.h:179
complex.h
sophus::lie::SpiralSimilarity2Impl::tangentExamples
static auto tangentExamples() -> std::vector< Tangent >
Definition: spiral_similarity2.h:295
sophus::lie::SpiralSimilarity2Impl::hat
static auto hat(Tangent const &angle_logscale) -> Eigen::Matrix< Scalar, kAmbientDim, kAmbientDim >
Definition: spiral_similarity2.h:111
sophus::lie::SpiralSimilarity2Impl::multiplication
static auto multiplication(Params const &lhs_params, Eigen::Vector< TCompatibleScalar, kNumParams > const &rhs_params) -> ParamsReturn< TCompatibleScalar >
Definition: spiral_similarity2.h:133
sophus::lie::Rotation2Impl::hasShortestPathAmbiguity
static auto hasShortestPathAmbiguity(Params const &foo_from_bar) -> bool
Definition: rotation2.h:78
sophus::lie::SpiralSimilarity2Impl::compactMatrix
static auto compactMatrix(Params const &non_zero_complex) -> Eigen::Matrix< Scalar, kPointDim, kPointDim >
Definition: spiral_similarity2.h:186
SOPHUS_UNEXPECTED
#define SOPHUS_UNEXPECTED(...)
Definition: common.h:57
sophus::lie::SpiralSimilarity2Impl::areParamsValid
static auto areParamsValid(Params const &non_zero_complex) -> sophus::Expected< Success >
Definition: spiral_similarity2.h:62
sophus::lie::SpiralSimilarity2Impl::dxExpX
static auto dxExpX(Tangent const &a) -> Eigen::Matrix< Scalar, kNumParams, kDof >
Definition: spiral_similarity2.h:238
sophus::lie::SpiralSimilarity2Impl::kIsAxisDirectionPreserving
static constexpr bool kIsAxisDirectionPreserving
Definition: spiral_similarity2.h:26
sophus::lie::SpiralSimilarity2Impl::matVInverse
static auto matVInverse(Params const &non_zero_complex, Tangent const &angle_logscale) -> Eigen::Matrix< Scalar, kPointDim, kPointDim >
Definition: spiral_similarity2.h:207
sophus::lie::SpiralSimilarity2Impl::dxThisMulExpXAt0
static auto dxThisMulExpXAt0(Params const &non_zero_complex) -> Eigen::Matrix< Scalar, kNumParams, kDof >
Definition: spiral_similarity2.h:272
sophus::lie::SpiralSimilarity2Impl::action
static auto action(Params const &non_zero_complex, UnitVector< TCompatibleScalar, kPointDim > const &direction_vector) -> UnitVectorReturn< TCompatibleScalar >
Definition: spiral_similarity2.h:170
unit_vector.h
sophus::lie::SpiralSimilarity2Impl::Params
Eigen::Vector< Scalar, kNumParams > Params
Definition: spiral_similarity2.h:38
sophus::lie::SpiralSimilarity2Impl::log
static auto log(Params const &complex) -> Tangent
Definition: spiral_similarity2.h:102
sophus::lie::SpiralSimilarity2Impl::dxLogThisInvTimesXAtThis
static auto dxLogThisInvTimesXAtThis(Params const &non_zero_complex) -> Eigen::Matrix< Scalar, kDof, kNumParams >
Definition: spiral_similarity2.h:282
sophus::lie::SpiralSimilarity2Impl::kIisParallelLinePreserving
static constexpr bool kIisParallelLinePreserving
Definition: spiral_similarity2.h:30
sophus::UnitVector::fromParams
static auto fromParams(Eigen::Matrix< TScalar, kN, 1 > const &v) -> UnitVector
Definition: unit_vector.h:166
sophus::lie::SpiralSimilarity2Impl::kIsShapePreserving
static constexpr bool kIsShapePreserving
Definition: spiral_similarity2.h:28
sophus::lie::Rotation2Impl::exp
static auto exp(Tangent const &angle) -> Params
Definition: rotation2.h:87
sophus::lie::SpiralSimilarity2Impl
Definition: spiral_similarity2.h:20
rotation2.h
sophus::ComplexImpl::multiplication
static auto multiplication(Eigen::Vector< Scalar, 2 > const &lhs_real_imag, Eigen::Vector< TCompatibleScalar, 2 > const &rhs_real_imag) -> ParamsReturn< TCompatibleScalar >
Definition: complex.h:64
sophus::lie::SpiralSimilarity2Impl::exp
static auto exp(Tangent const &angle_logscale) -> Params
Definition: spiral_similarity2.h:86
sophus::lie::SpiralSimilarity2Impl::toAmbient
static auto toAmbient(Point const &point) -> Eigen::Vector< Scalar, kAmbientDim >
Definition: spiral_similarity2.h:164
sophus::max
auto max(TPoint const &a, TPoint const &b) -> TPoint
Definition: vector_space.h:114
sophus::lie::SpiralSimilarity2Impl::inverse
static auto inverse(Params const &non_zero_complex) -> Params
Definition: spiral_similarity2.h:125
sophus::lie::SpiralSimilarity2Impl::ScalarReturn
typename Eigen::ScalarBinaryOpTraits< Scalar, TCompatibleScalar >::ReturnType ScalarReturn
Definition: spiral_similarity2.h:43
sophus::lie::Rotation2Impl
Definition: rotation2.h:19
sophus::lie::SpiralSimilarity2Impl::Scalar
TScalar Scalar
Definition: spiral_similarity2.h:22
sophus::lie::SpiralSimilarity2Impl::kIisSizePreserving
static constexpr bool kIisSizePreserving
Definition: spiral_similarity2.h:29
sophus::lie::SpiralSimilarity2Impl::dxExpXAt0
static auto dxExpXAt0() -> Eigen::Matrix< Scalar, kNumParams, kDof >
Definition: spiral_similarity2.h:254
sophus::lie::SpiralSimilarity2Impl::adjOfTranslation
static auto adjOfTranslation(Params const &, Point const &point) -> Eigen::Matrix< Scalar, kPointDim, kDof >
Definition: spiral_similarity2.h:217