farm-ng-core
translation_factor_group_product.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
10 
15 
16 namespace sophus {
17 namespace lie {
18 
19 /// Semi direct product of a Lie group (factor group) and the
20 /// vector space (translation).
21 template <
22  class TScalar,
23  int kTranslationDim,
24  template <class>
25  class TFactorGroup>
26 requires concepts::LieFactorGroupImpl<TFactorGroup<TScalar>>
28  public:
29  using Scalar = TScalar;
30  using FactorGroup = TFactorGroup<Scalar>;
31 
32  // The is also the dimension of the translation.
33  static int const kPointDim = kTranslationDim;
34  static_assert(kPointDim == FactorGroup::kPointDim);
35  static_assert(kPointDim == FactorGroup::kAmbientDim);
36 
37  // Non-zero translation shift the coordinate origin.
38  static bool constexpr kIsOriginPreserving = false;
39  static_assert(
40  static_cast<bool>(FactorGroup::kIsOriginPreserving),
41  "The factor group is origin preserving by definition.");
42  static bool constexpr kIsAxisDirectionPreserving =
43  FactorGroup::kIsAxisDirectionPreserving;
44  static bool constexpr kIsDirectionVectorPreserving =
45  FactorGroup::kIsDirectionVectorPreserving;
46  static bool constexpr kIsShapePreserving = FactorGroup::kIsShapePreserving;
47  static bool constexpr kIsSizePreserving = FactorGroup::kIsSizePreserving;
48 
49  static_assert(
50  static_cast<bool>(FactorGroup::kIisParallelLinePreserving),
51  "The factor group by definition needs to map parallel lines to parallel "
52  "lines. In particular projective mappings are not allowed.");
53  static bool constexpr kIisParallelLinePreserving = true;
54 
55  static int const kDof = FactorGroup::kDof + kPointDim;
56  static int const kNumParams = FactorGroup::kNumParams + kPointDim;
57  static int const kAmbientDim = kPointDim + 1;
58 
59  using Tangent = Eigen::Vector<Scalar, kDof>;
60  using Params = Eigen::Vector<Scalar, kNumParams>;
61  using Point = Eigen::Vector<Scalar, kPointDim>;
62 
63  template <class TCompatibleScalar>
64  using ScalarReturn = typename Eigen::
65  ScalarBinaryOpTraits<Scalar, TCompatibleScalar>::ReturnType;
66 
67  template <class TCompatibleScalar>
68  using ParamsReturn =
69  Eigen::Vector<ScalarReturn<TCompatibleScalar>, kNumParams>;
70 
71  template <class TCompatibleScalar>
72  using PointReturn = Eigen::Vector<ScalarReturn<TCompatibleScalar>, kPointDim>;
73 
74  template <class TCompatibleScalar>
75  using UnitVectorReturn =
77 
78  // constructors and factories
79 
80  static auto identityParams() -> Params {
81  return params(FactorGroup::identityParams(), Point::Zero().eval());
82  }
83 
84  static auto areParamsValid(Params const& params)
85  -> sophus::Expected<Success> {
86  return FactorGroup::areParamsValid(factorGroupParams(params));
87  }
88 
89  static auto hasShortestPathAmbiguity(Params const& params) -> bool {
90  return FactorGroup::hasShortestPathAmbiguity(factorGroupParams(params));
91  }
92 
93  // Manifold / Lie Group concepts
94 
95  static auto exp(Tangent tangent) -> Params {
96  Eigen::Vector<Scalar, FactorGroup::kNumParams> factor_group_params =
97  FactorGroup::exp(factorTangent(tangent));
98  return params(
99  factor_group_params,
100  (FactorGroup::matV(factor_group_params, factorTangent(tangent)) *
101  translationTangent(tangent))
102  .eval());
103  }
104 
105  static auto log(Params const& params) -> Tangent {
106  Eigen::Vector<Scalar, FactorGroup::kDof> factor_tangent =
107  FactorGroup::log(factorGroupParams(params));
108  return tangent(
109  FactorGroup::matVInverse(factorGroupParams(params), factor_tangent) *
110  translation(params),
111  factor_tangent);
112  }
113 
114  static auto hat(Tangent const& tangent)
115  -> Eigen::Matrix<Scalar, kAmbientDim, kAmbientDim> {
116  Eigen::Matrix<Scalar, kAmbientDim, kAmbientDim> hat_mat;
117  hat_mat.setZero();
118  hat_mat.template topLeftCorner<kPointDim, kPointDim>() =
119  FactorGroup::hat(factorTangent(tangent));
120  hat_mat.template topRightCorner<kPointDim, 1>() =
121  translationTangent(tangent);
122  return hat_mat;
123  }
124 
125  static auto vee(Eigen::Matrix<Scalar, kAmbientDim, kAmbientDim> const& mat)
126  -> Eigen::Matrix<Scalar, kDof, 1> {
127  return tangent(
128  mat.template topRightCorner<kPointDim, 1>().eval(),
129  FactorGroup::vee(
130  mat.template topLeftCorner<kPointDim, kPointDim>().eval()));
131  }
132 
133  // group operations
134  template <class TCompatibleScalar>
135  static auto multiplication(
136  Params const& lhs_params,
137  Eigen::Vector<TCompatibleScalar, kNumParams> const& rhs_params)
139  typename FactorGroup::template ParamsReturn<TCompatibleScalar> p =
140  FactorGroup::multiplication(
141  factorGroupParams(lhs_params), factorGroupParams(rhs_params));
142 
143  typename FactorGroup::template PointReturn<TCompatibleScalar> t =
144  FactorGroup::action(
145  factorGroupParams(lhs_params), translation(rhs_params)) +
146  translation(lhs_params);
147 
148  return TranslationFactorGroupProduct::params(p, t);
149  }
150 
151  static auto inverse(Params const& params) -> Params {
152  Eigen::Vector<Scalar, FactorGroup::kNumParams> factor_group_params =
153  FactorGroup::inverse(factorGroupParams(params));
154  return TranslationFactorGroupProduct::params(
155  factor_group_params,
156  (-FactorGroup::action(factor_group_params, translation(params)))
157  .eval());
158  }
159 
160  // Point actions
161 
162  template <class TCompatibleScalar>
163  static auto action(
164  Params const& params,
165  Eigen::Matrix<TCompatibleScalar, kPointDim, 1> const& point)
167  return FactorGroup::action(factorGroupParams(params), point) +
168  translation(params);
169  }
170 
171  static auto toAmbient(Point const& point)
172  -> Eigen::Vector<Scalar, kAmbientDim> {
173  return unproj(point);
174  }
175 
176  template <class TCompatibleScalar>
177  static auto action(
178  Params const& params,
181  return FactorGroup::action(factorGroupParams(params), direction);
182  }
183 
184  static auto adj(Params const& params) -> Eigen::Matrix<Scalar, kDof, kDof> {
185  Eigen::Matrix<Scalar, kDof, kDof> mat_adjoint;
186 
187  Eigen::Vector<Scalar, FactorGroup::kNumParams> factor_group_params =
188  factorGroupParams(params);
189 
190  mat_adjoint.template topLeftCorner<kPointDim, kPointDim>() =
191  FactorGroup::matrix(factor_group_params);
192  mat_adjoint.template topRightCorner<kPointDim, FactorGroup::kDof>() =
193  FactorGroup::adjOfTranslation(factor_group_params, translation(params));
194 
195  mat_adjoint.template bottomLeftCorner<FactorGroup::kDof, kPointDim>()
196  .setZero();
197  mat_adjoint
198  .template bottomRightCorner<FactorGroup::kDof, FactorGroup::kDof>() =
199  FactorGroup::adj(factor_group_params);
200 
201  return mat_adjoint;
202  }
203 
204  static auto ad(Tangent const& tangent) -> Eigen::Matrix<Scalar, kDof, kDof> {
205  Eigen::Matrix<Scalar, kDof, kDof> ad;
206  ad.template topLeftCorner<kPointDim, kPointDim>() =
207  FactorGroup::hat(factorTangent(tangent));
208  ad.template topRightCorner<kPointDim, FactorGroup::kDof>() =
209  FactorGroup::adOfTranslation(translationTangent(tangent));
210 
211  ad.template bottomLeftCorner<FactorGroup::kDof, kPointDim>().setZero();
212 
213  ad.template bottomRightCorner<FactorGroup::kDof, FactorGroup::kDof>() =
214  FactorGroup::ad(factorTangent(tangent));
215 
216  return ad;
217  }
218 
219  // Matrices
220 
221  static auto compactMatrix(Params const& params)
222  -> Eigen::Matrix<Scalar, kPointDim, kAmbientDim> {
223  Eigen::Matrix<Scalar, kPointDim, kAmbientDim> mat;
224  mat.template topLeftCorner<kPointDim, kPointDim>() =
225  FactorGroup::compactMatrix(factorGroupParams(params));
226  mat.template topRightCorner<kPointDim, 1>() = translation(params);
227  return mat;
228  }
229 
230  static auto matrix(Params const& params)
231  -> Eigen::Matrix<Scalar, kAmbientDim, kAmbientDim> {
232  Eigen::Matrix<Scalar, kAmbientDim, kAmbientDim> mat;
233  mat.setZero();
234  mat.template topLeftCorner<kPointDim, kAmbientDim>() =
235  compactMatrix(params);
236  mat(kPointDim, kPointDim) = 1.0;
237  return mat;
238  }
239 
240  // derivatives
241 
242  // static auto dxExpX(Tangent const& tangent)
243  // -> Eigen::Matrix<Scalar, kNumParams, kDof> {
244  // Eigen::Matrix<Scalar, kNumParams, kDof> j;
245  // j.setZero();
246  // j.template topRightCorner<FactorGroup::kNumParams, FactorGroup::kDof>() =
247  // FactorGroup::dxExpX(factorTangent(tangent));
248  // j.template bottomLeftCorner<kPointDim, kPointDim>().setIdentity();
249  // return j;
250  // }
251 
252  static auto dxExpXAt0() -> Eigen::Matrix<Scalar, kNumParams, kDof> {
253  Eigen::Matrix<Scalar, kNumParams, kDof> j;
254  j.setZero();
255  j.template topRightCorner<FactorGroup::kNumParams, FactorGroup::kDof>() =
256  FactorGroup::dxExpXAt0();
257  j.template bottomLeftCorner<kPointDim, kPointDim>().setIdentity();
258  return j;
259  }
260 
261  static auto dxExpXTimesPointAt0(Point const& point)
262  -> Eigen::Matrix<Scalar, kPointDim, kDof> {
263  Eigen::Matrix<Scalar, kPointDim, kDof> j;
264  j.template topLeftCorner<kPointDim, kPointDim>().setIdentity();
265  j.template topRightCorner<kPointDim, FactorGroup::kDof>() =
266  FactorGroup::dxExpXTimesPointAt0(point);
267  return j;
268  }
269 
270  static auto dxThisMulExpXAt0(Params const& params)
271  -> Eigen::Matrix<Scalar, kNumParams, kDof> {
272  Eigen::Matrix<Scalar, kNumParams, kDof> j;
273  j.setZero();
274  Eigen::Vector<Scalar, FactorGroup::kNumParams> factor_group_params =
275  factorGroupParams(params);
276  j.template topRightCorner<FactorGroup::kNumParams, FactorGroup::kDof>() =
277  FactorGroup::dxThisMulExpXAt0(factor_group_params);
278  j.template bottomLeftCorner<kPointDim, kPointDim>() =
279  FactorGroup::matrix(factor_group_params);
280  return j;
281  }
282 
283  static auto dxLogThisInvTimesXAtThis(Params const& params)
284  -> Eigen::Matrix<Scalar, kDof, kNumParams> {
285  Eigen::Matrix<Scalar, kDof, kNumParams> j;
286  j.setZero();
287  Eigen::Vector<Scalar, FactorGroup::kNumParams> factor_group_params =
288  factorGroupParams(params);
289  j.template bottomLeftCorner<FactorGroup::kDof, FactorGroup::kNumParams>() =
290  FactorGroup::dxLogThisInvTimesXAtThis(factor_group_params);
291  j.template topRightCorner<kPointDim, kPointDim>() =
292  FactorGroup::matrix(factor_group_params).inverse();
293  return j;
294  }
295 
296  // for tests
297 
298  static auto tangentExamples() -> std::vector<Tangent> {
299  std::vector<Tangent> examples;
300  for (auto const& group_tangent : FactorGroup::tangentExamples()) {
301  for (auto const& translation_tangents : exampleTranslations()) {
302  examples.push_back(tangent(translation_tangents, group_tangent));
303  }
304  }
305  return examples;
306  }
307 
308  static auto paramsExamples() -> std::vector<Params> {
309  std::vector<Params> examples;
310  for (auto const& factor_group_params : FactorGroup::paramsExamples()) {
311  for (auto const& right_params : exampleTranslations()) {
312  examples.push_back(params(factor_group_params, right_params));
313  }
314  }
315  return examples;
316  }
317 
318  static auto invalidParamsExamples() -> std::vector<Params> {
319  std::vector<Params> examples;
320  for (auto const& factor_group_params :
321  FactorGroup::invalidParamsExamples()) {
322  for (auto const& right_params : exampleTranslations()) {
323  examples.push_back(params(factor_group_params, right_params));
324  }
325  }
326  return examples;
327  }
328 
329  private:
330  template <class TScalar2>
331  static auto factorGroupParams(
332  Eigen::Vector<TScalar2, kNumParams> const& params)
333  -> Eigen::Vector<TScalar2, FactorGroup::kNumParams> {
334  return params.template head<FactorGroup::kNumParams>();
335  }
336 
337  template <class TScalar2>
338  static auto translation(Eigen::Vector<TScalar2, kNumParams> const& params)
339  -> Eigen::Vector<TScalar2, kPointDim> {
340  return params.template tail<kPointDim>();
341  }
342 
343  template <class TScalar2>
344  static auto params(
345  Eigen::Vector<TScalar2, FactorGroup::kNumParams> const&
346  factor_grop_tarams,
347  Eigen::Vector<TScalar2, kPointDim> const& translation)
348  -> Eigen::Vector<TScalar2, kNumParams> {
349  Eigen::Vector<TScalar2, kNumParams> params;
350  params.template head<FactorGroup::kNumParams>() = factor_grop_tarams;
351  params.template tail<kPointDim>() = translation;
352  return params;
353  }
354 
355  static auto factorTangent(Tangent const& tangent)
356  -> Eigen::Vector<Scalar, FactorGroup::kDof> {
357  return tangent.template tail<FactorGroup::kDof>();
358  }
359 
360  static auto translationTangent(Tangent const& tangent) -> Point {
361  return tangent.template head<kPointDim>();
362  }
363 
364  static auto tangent(
365  Point const& translation,
366  Eigen::Vector<Scalar, FactorGroup::kDof> const& factor_tangent)
367  -> Tangent {
368  Tangent tangent;
369  tangent.template head<kPointDim>() = translation;
370  tangent.template tail<FactorGroup::kDof>() = factor_tangent;
371  return tangent;
372  }
373 
374  static auto exampleTranslations() -> std::vector<Point> {
375  return ::sophus::pointExamples<Scalar, kPointDim>();
376  }
377 };
378 
379 template <int kTranslationDim, template <class> class TFactorGroup>
381  template <class TScalar>
382  using SemiDirectProduct =
384 };
385 
386 } // namespace lie
387 } // namespace sophus
sophus::lie::TranslationFactorGroupProduct::adj
static auto adj(Params const &params) -> Eigen::Matrix< Scalar, kDof, kDof >
Definition: translation_factor_group_product.h:184
sophus::lie::TranslationFactorGroupProduct::paramsExamples
static auto paramsExamples() -> std::vector< Params >
Definition: translation_factor_group_product.h:308
sophus::unproj
auto unproj(Eigen::MatrixBase< TPoint > const &p, const typename TPoint::Scalar &z=1.0) -> Eigen::Vector< typename TPoint::Scalar, TPoint::RowsAtCompileTime+1 >
Maps point on the z=1 plane (a,b) to homogeneous representation of the same point: (z*a,...
Definition: homogeneous.h:31
lie_group.h
sophus::lie::TranslationFactorGroupProduct::Params
Eigen::Vector< Scalar, kNumParams > Params
Definition: translation_factor_group_product.h:60
sophus::lie::TranslationFactorGroupProduct::kPointDim
static const int kPointDim
Definition: translation_factor_group_product.h:33
sophus::UnitVector
Definition: lie_group.h:14
sophus::lie::TranslationFactorGroupProduct::kIisParallelLinePreserving
static constexpr bool kIisParallelLinePreserving
Definition: translation_factor_group_product.h:53
sophus::lie::TranslationFactorGroupProduct
Semi direct product of a Lie group (factor group) and the vector space (translation).
Definition: translation_factor_group_product.h:27
sophus::lie::TranslationFactorGroupProduct::PointReturn
Eigen::Vector< ScalarReturn< TCompatibleScalar >, kPointDim > PointReturn
Definition: translation_factor_group_product.h:72
sophus
Image MutImage, owning images types.
Definition: num_diff.h:20
sophus::lie::TranslationFactorGroupProduct::kIsShapePreserving
static constexpr bool kIsShapePreserving
Definition: translation_factor_group_product.h:46
sophus::lie::TranslationFactorGroupProduct::kIsOriginPreserving
static constexpr bool kIsOriginPreserving
Definition: translation_factor_group_product.h:38
sophus::lie::TranslationFactorGroupProduct::tangentExamples
static auto tangentExamples() -> std::vector< Tangent >
Definition: translation_factor_group_product.h:298
sophus::lie::TranslationFactorGroupProduct::dxExpXTimesPointAt0
static auto dxExpXTimesPointAt0(Point const &point) -> Eigen::Matrix< Scalar, kPointDim, kDof >
Definition: translation_factor_group_product.h:261
sophus::lie::TranslationFactorGroupProduct::dxExpXAt0
static auto dxExpXAt0() -> Eigen::Matrix< Scalar, kNumParams, kDof >
Definition: translation_factor_group_product.h:252
sophus::lie::TranslationFactorGroupProduct::Tangent
Eigen::Vector< Scalar, kDof > Tangent
Definition: translation_factor_group_product.h:59
sophus::lie::TranslationFactorGroupProduct::log
static auto log(Params const &params) -> Tangent
Definition: translation_factor_group_product.h:105
sophus::lie::TranslationFactorGroupProduct::action
static auto action(Params const &params, UnitVector< TCompatibleScalar, kPointDim > const &direction) -> UnitVectorReturn< TCompatibleScalar >
Definition: translation_factor_group_product.h:177
sophus::lie::TranslationFactorGroupProduct::action
static auto action(Params const &params, Eigen::Matrix< TCompatibleScalar, kPointDim, 1 > const &point) -> PointReturn< TCompatibleScalar >
Definition: translation_factor_group_product.h:163
sophus::lie::TranslationFactorGroupProduct::identityParams
static auto identityParams() -> Params
Definition: translation_factor_group_product.h:80
sophus::lie::TranslationFactorGroupProduct::kNumParams
static const int kNumParams
Definition: translation_factor_group_product.h:56
sophus::lie::TranslationFactorGroupProduct::kAmbientDim
static const int kAmbientDim
Definition: translation_factor_group_product.h:57
sophus::lie::TranslationFactorGroupProduct::dxLogThisInvTimesXAtThis
static auto dxLogThisInvTimesXAtThis(Params const &params) -> Eigen::Matrix< Scalar, kDof, kNumParams >
Definition: translation_factor_group_product.h:283
sophus::lie::WithDimAndSubgroup
Definition: translation_factor_group_product.h:380
sophus::lie::TranslationFactorGroupProduct::kDof
static const int kDof
Definition: translation_factor_group_product.h:55
sophus::lie::TranslationFactorGroupProduct::vee
static auto vee(Eigen::Matrix< Scalar, kAmbientDim, kAmbientDim > const &mat) -> Eigen::Matrix< Scalar, kDof, 1 >
Definition: translation_factor_group_product.h:125
sophus::lie::TranslationFactorGroupProduct::toAmbient
static auto toAmbient(Point const &point) -> Eigen::Vector< Scalar, kAmbientDim >
Definition: translation_factor_group_product.h:171
homogeneous.h
unit_vector.h
sophus::lie::TranslationFactorGroupProduct::kIsDirectionVectorPreserving
static constexpr bool kIsDirectionVectorPreserving
Definition: translation_factor_group_product.h:44
sophus::lie::TranslationFactorGroupProduct::invalidParamsExamples
static auto invalidParamsExamples() -> std::vector< Params >
Definition: translation_factor_group_product.h:318
sophus::lie::TranslationFactorGroupProduct::dxThisMulExpXAt0
static auto dxThisMulExpXAt0(Params const &params) -> Eigen::Matrix< Scalar, kNumParams, kDof >
Definition: translation_factor_group_product.h:270
sophus::lie::TranslationFactorGroupProduct::ScalarReturn
typename Eigen::ScalarBinaryOpTraits< Scalar, TCompatibleScalar >::ReturnType ScalarReturn
Definition: translation_factor_group_product.h:65
sophus::lie::TranslationFactorGroupProduct::multiplication
static auto multiplication(Params const &lhs_params, Eigen::Vector< TCompatibleScalar, kNumParams > const &rhs_params) -> ParamsReturn< TCompatibleScalar >
Definition: translation_factor_group_product.h:135
sophus::lie::TranslationFactorGroupProduct::Point
Eigen::Vector< Scalar, kPointDim > Point
Definition: translation_factor_group_product.h:61
sophus::lie::TranslationFactorGroupProduct::matrix
static auto matrix(Params const &params) -> Eigen::Matrix< Scalar, kAmbientDim, kAmbientDim >
Definition: translation_factor_group_product.h:230
sophus::lie::TranslationFactorGroupProduct::areParamsValid
static auto areParamsValid(Params const &params) -> sophus::Expected< Success >
Definition: translation_factor_group_product.h:84
sophus::lie::TranslationFactorGroupProduct::compactMatrix
static auto compactMatrix(Params const &params) -> Eigen::Matrix< Scalar, kPointDim, kAmbientDim >
Definition: translation_factor_group_product.h:221
sophus::lie::TranslationFactorGroupProduct::Scalar
TScalar Scalar
Definition: translation_factor_group_product.h:29
sophus::lie::TranslationFactorGroupProduct::kIsSizePreserving
static constexpr bool kIsSizePreserving
Definition: translation_factor_group_product.h:47
sophus::lie::TranslationFactorGroupProduct::ad
static auto ad(Tangent const &tangent) -> Eigen::Matrix< Scalar, kDof, kDof >
Definition: translation_factor_group_product.h:204
sophus::lie::TranslationFactorGroupProduct::hasShortestPathAmbiguity
static auto hasShortestPathAmbiguity(Params const &params) -> bool
Definition: translation_factor_group_product.h:89
sophus::eval
auto eval(TPoint const &p)
Definition: vector_space.h:44
sophus::lie::TranslationFactorGroupProduct::inverse
static auto inverse(Params const &params) -> Params
Definition: translation_factor_group_product.h:151
sophus::lie::TranslationFactorGroupProduct::FactorGroup
TFactorGroup< Scalar > FactorGroup
Definition: translation_factor_group_product.h:30
sophus::lie::TranslationFactorGroupProduct::exp
static auto exp(Tangent tangent) -> Params
Definition: translation_factor_group_product.h:95
sophus::lie::TranslationFactorGroupProduct::hat
static auto hat(Tangent const &tangent) -> Eigen::Matrix< Scalar, kAmbientDim, kAmbientDim >
Definition: translation_factor_group_product.h:114
sophus::lie::TranslationFactorGroupProduct::ParamsReturn
Eigen::Vector< ScalarReturn< TCompatibleScalar >, kNumParams > ParamsReturn
Definition: translation_factor_group_product.h:69
vector_space.h
sophus::lie::TranslationFactorGroupProduct::kIsAxisDirectionPreserving
static constexpr bool kIsAxisDirectionPreserving
Definition: translation_factor_group_product.h:42