smooth
A C++ library for Lie theory
Loading...
Searching...
No Matches
vector.hpp
Go to the documentation of this file.
1// Copyright (C) 2021-2022 Petter Nilsson. MIT License.
2
3#pragma once
4
10#include <algorithm>
11#include <ranges>
12#include <vector>
13
15#include "smooth/detail/utils.hpp"
16
17SMOOTH_BEGIN_NAMESPACE
18
19namespace traits {
23template<Manifold M>
24struct man<std::vector<M>>
25{
26 // \cond
27 using Scalar = ::smooth::Scalar<M>;
28 using PlainObject = std::vector<M>;
29 template<typename NewScalar>
30 using CastT = std::vector<typename man<M>::template CastT<NewScalar>>;
31
32 static constexpr int Dof = -1;
33
34 static inline Eigen::Index dof(const PlainObject & m)
35 {
36 if constexpr (traits::man<M>::Dof > 0) {
37 return static_cast<Eigen::Index>(m.size()) * traits::man<M>::Dof;
38 } else {
39 return std::accumulate(
40 m.begin(), m.end(), 0u, [](auto s, const auto & item) { return s + traits::man<M>::dof(item); });
41 }
42 }
43
44 static inline PlainObject Default(Eigen::Index dof)
45 {
47 const Eigen::Index mdof = ::smooth::Dof<M> != -1 ? ::smooth::Dof<M> : 1;
48 const auto size = static_cast<std::size_t>(dof / mdof);
49
50 return PlainObject(size, traits::man<M>::Default(mdof));
51 }
52
53 template<typename NewScalar>
54 static inline auto cast(const PlainObject & m)
55 {
56 const auto transformer = [](const M & mi) ->
57 typename traits::man<M>::template CastT<NewScalar> { return traits::man<M>::template cast<NewScalar>(mi); };
58 const auto casted_view = m | std::views::transform(transformer);
59 return std::vector(std::ranges::begin(casted_view), std::ranges::end(casted_view));
60 }
61
62 template<typename Derived>
63 static inline PlainObject rplus(const PlainObject & m, const Eigen::MatrixBase<Derived> & a)
64 {
65 PlainObject m_plus_a;
66 m_plus_a.reserve(m.size());
67 for (Eigen::Index dof_cntr = 0; const auto & mi : m) {
68 const auto dof_i = traits::man<M>::dof(mi);
69 m_plus_a.push_back(traits::man<M>::rplus(mi, a.template segment<traits::man<M>::Dof>(dof_cntr, dof_i)));
70 dof_cntr += dof_i;
71 }
72 return m_plus_a;
73 }
74
75 static inline Eigen::Matrix<Scalar, Dof, 1> rminus(const PlainObject & m1, const PlainObject & m2)
76 {
77 Eigen::Index dof_cnts = 0;
78 if (traits::man<M>::Dof > 0) {
79 dof_cnts = static_cast<Eigen::Index>(traits::man<M>::Dof * static_cast<Eigen::Index>(m1.size()));
80 } else {
81 for (auto i = 0u; i != m1.size(); ++i) { dof_cnts += ::smooth::dof<M>(m1[i]); }
82 }
83
84 Eigen::VectorX<Scalar> ret(dof_cnts);
85
86 for (Eigen::Index idx = 0; const auto & [m1i, m2i] : utils::zip(m1, m2)) {
87 const auto & size_i = ::smooth::dof<M>(m1i);
88
89 ret.template segment<traits::man<M>::Dof>(idx, size_i) = traits::man<M>::rminus(m1i, m2i);
90 idx += size_i;
91 }
92
93 return ret;
94 }
95 // \endcond
96};
97
98} // namespace traits
99
100SMOOTH_END_NAMESPACE
PlainObject< M > Default()
Default-initialized Manifold with static dof.
Definition manifold.hpp:135
typename traits::man< M >::Scalar Scalar
Manifold scalar type.
Definition manifold.hpp:88
Eigen::Index dof(const M &m)
Manifold degrees of freedom (tangent space dimension)
Definition manifold.hpp:145
Tangent< M > rminus(const M &g1, const Mo &g2)
Manifold right-minus.
Definition manifold.hpp:172
PlainObject< M > rplus(const M &m, const Eigen::MatrixBase< Derived > &a)
Manifold right-plus.
Definition manifold.hpp:163
typename traits::man< M >::template CastT< NewScalar > CastT
Cast'ed type.
Definition manifold.hpp:100
CastT< NewScalar, M > cast(const M &m)
Cast to different scalar type.
Definition manifold.hpp:154
typename traits::man< M >::PlainObject PlainObject
Manifold default type.
Definition manifold.hpp:94
Trait class for making a class a Manifold instance via specialization.
Definition manifold.hpp:21