v0.15.0
Loading...
Searching...
No Matches
Lie.hpp
Go to the documentation of this file.
1/**
2 * @file Lie.hpp
3 * @brief Lie algebra implementation
4 * @version 0.1
5 * @date 2024-12-22
6 *
7 * @copyright Copyright (c) 2024
8 *
9 */
10
11#pragma once
12
13namespace LieGroups {
14
15template <class T> struct TensorTypeExtractor {
16 typedef typename std::remove_pointer<T>::type Type;
17};
18template <class T, int I> struct TensorTypeExtractor<FTensor::PackPtr<T, I>> {
19 typedef typename std::remove_pointer<T>::type Type;
20};
21
22struct SO3 {
23
24 SO3() = delete;
25 ~SO3() = delete;
26
27 template <typename T> inline static auto getVee(T &&w1, T &&w2, T &&w3) {
29
30 std::forward<T>(w1), std::forward<T>(w2), std::forward<T>(w3)
31
32 );
33 }
34
35 template <typename T> inline static auto getHat(T &&w1, T &&w2, T &&w3) {
36 return getHatImpl(std::forward<A>(getVee(w1, w2, w3)));
37 }
38
39 template <typename A> inline static auto getVee(A &&t_w_hat) {
40 return getVeeImpl(std::forward<A>(t_w_hat));
41 }
42
43 template <typename A> inline static auto getHat(A &&t_w_vee) {
44 return getHatImpl(std::forward<A>(t_w_vee));
45 }
46
47 template <typename A, typename B>
48 inline static auto exp(A &&t_w_vee, B &&theta) {
49 return expImpl(std::forward<A>(t_w_vee), std::forward<B>(theta));
50 }
51
52 template <typename A, typename B>
53 inline static auto Jl(A &&t_w_vee, B &&theta) {
54 return JlImpl(std::forward<A>(t_w_vee), std::forward<B>(theta));
55 }
56
57 template <typename A, typename B>
58 inline static auto Jr(A &&t_w_vee, B &&theta) {
59 return JrImpl(std::forward<A>(t_w_vee), std::forward<B>(theta));
60 }
61
62 template <typename A, typename B, typename C>
63 inline static auto action(A &&t_w_vee, B &&theta, C &&t_A) {
64 return actionImpl(std::forward<A>(t_w_vee), std::forward<B>(theta),
65 std::forward<C>(t_A));
66 }
67
68 template <typename A, typename B>
69 inline static auto dActionJl(A &&t_w_vee, B &&t_A) {
70 return dActionJlImpl(std::forward<A>(t_w_vee), std::forward<B>(t_A));
71 }
72
73 template <typename A, typename B>
74 inline static auto dActionJr(A &&t_w_vee, B &&t_A) {
75 return dActionJrImpl(std::forward<A>(t_w_vee), std::forward<B>(t_A));
76 }
77
78 template <typename A, typename B>
79 inline static auto diffExp(A &&t_w_vee, B &&theta) {
80 return diffExpImpl(std::forward<A>(t_w_vee), std::forward<B>(theta));
81 }
82
83 template <typename A, typename B>
84 inline static auto diffDiffExp(A &&t_w_vee, B &&theta) {
85 return diffDiffExpImpl(std::forward<A>(t_w_vee), std::forward<B>(theta));
86 }
87
88private:
89 inline static constexpr int dim = 3;
90 inline static FTENSOR_INDEX(dim, i);
91 inline static FTENSOR_INDEX(dim, j);
92 inline static FTENSOR_INDEX(dim, k);
93 inline static FTENSOR_INDEX(dim, l);
94 inline static FTENSOR_INDEX(dim, m);
95 inline static FTENSOR_INDEX(dim, n);
96
97 template <typename T>
98 inline static auto getVeeImpl(FTensor::Tensor2<T, dim, dim> &t_w_hat) {
99 using D = typename TensorTypeExtractor<T>::Type;
101 t_w_vee(k) = (levi_civita(i, j, k) * t_w_hat(i, j)) / 2;
102 return t_w_vee;
103 }
104
105 template <typename T>
106 inline static auto getHatImpl(FTensor::Tensor1<T, dim> &t_w_vee) {
107 using D = typename TensorTypeExtractor<T>::Type;
109 t_w_hat(i, j) = levi_civita(i, j, k) * t_w_vee(k);
110 return t_w_hat;
111 }
112
113 template <typename T1, typename T2, typename T3>
114 inline static auto genericFormImpl(FTensor::Tensor1<T1, dim> &t_w_vee,
115 const T2 alpha, const T3 beta) {
116 using D = typename TensorTypeExtractor<T1>::Type;
118 auto t_hat = getHat(t_w_vee);
119 t_X(i, j) = FTensor::Kronecker_Delta<int>()(i, j) + alpha * t_hat(i, j) +
120 beta * (t_hat(i, k) * t_hat(k, j));
121 return t_X;
122 }
123
124 template <typename T1, typename T2>
125 inline static auto expImpl(FTensor::Tensor1<T1, dim> &t_w_vee,
126 const T2 theta) {
127 if (std::fabs(theta) < std::numeric_limits<T2>::epsilon()) {
128 return genericFormImpl(t_w_vee, 1, 0.5);
129 }
130 const auto s = sin(theta);
131 const auto s_half = sin(theta / 2);
132 const auto a = s / theta;
133 const auto b = 2 * (s_half / theta) * (s_half / theta);
134 return genericFormImpl(t_w_vee, a, b);
135 }
136
137 template <typename T1, typename T2>
138 inline static auto diffExpImpl(FTensor::Tensor1<T1, dim> &t_w_vee,
139 const T2 theta) {
140
141 auto get_tensor = [&t_w_vee](auto a, auto diff_a, auto b, auto diff_b) {
142 FTENSOR_INDEX(3, i);
143 FTENSOR_INDEX(3, j);
144 FTENSOR_INDEX(3, k);
145 FTENSOR_INDEX(3, l);
146
147 using D = typename TensorTypeExtractor<T1>::Type;
149 auto t_hat = getHat(t_w_vee);
150 t_diff_exp(i, j, k) =
151
153
154 +
155
156 diff_a * t_hat(i, j) * t_w_vee(k)
157
158 +
159
160 b * (t_hat(i, l) * FTensor::levi_civita<int>(l, j, k) +
161 FTensor::levi_civita<int>(i, l, k) * t_hat(l, j))
162
163 +
164
165 diff_b * t_hat(i, l) * t_hat(l, j) * t_w_vee(k);
166
167 return t_diff_exp;
168 };
169
170 if(std::fabs(theta) < std::numeric_limits<T2>::epsilon()){
171 return get_tensor(1., -1. / 3., 0., 1. / 1.2);
172 }
173
174 const auto ss = sin(theta);
175 const auto a = ss / theta;
176
177 const auto theta2 = theta * theta;
178 const auto cc = cos(theta);
179 const auto diff_a = (theta * cc - ss) / (theta2 * theta);
180
181 const auto ss_2 = sin(theta / 2.);
182 const auto cc_2 = cos(theta / 2.);
183 const auto b = 2. * ss_2 * ss_2 / theta2;
184 const auto diff_b =
185 (2. * theta * ss_2 * cc_2 - 4. * ss_2 * ss_2) / (theta2 * theta2);
186
187 return get_tensor(a, diff_a, b, diff_b);
188 }
189
190 template <typename T1, typename T2>
191 inline static auto diffDiffExpImpl(FTensor::Tensor1<T1, dim> &t_w_vee,
192 const T2 theta) {
193
194 auto get_tensor = [&t_w_vee](auto a, auto diff_a, auto diff_diff_a, auto b,
195 auto diff_b, auto diff_diff_b) {
196 FTENSOR_INDEX(3, i);
197 FTENSOR_INDEX(3, j);
198 FTENSOR_INDEX(3, k);
199 FTENSOR_INDEX(3, l);
200 FTENSOR_INDEX(3, m);
201
202 constexpr auto t_kd = FTensor::Kronecker_Delta<double>();
203
204 using D = typename TensorTypeExtractor<T1>::Type;
205 FTensor::Tensor4<D, 3, 3, 3, 3> t_diff_diff_exp;
206
208 auto t_hat = getHat(t_w_vee);
209 t_diff_diff_exp(i, j, k, m) =
210
211 diff_a * FTensor::levi_civita<int>(i, j, k) * t_w_vee(m)
212
213 +
214
215 diff_a * (
216
217 t_hat(i, j) * t_kd(k, m) +
218 FTensor::levi_civita<int>(i, j, m) * t_w_vee(k)
219
220 )
221
222 +
223
224 diff_diff_a * t_hat(i, j) * t_w_vee(k) * t_w_vee(m)
225
226 +
227
232
233 +
234
235 diff_b * ((t_hat(i, l) * FTensor::levi_civita<int>(l, j, k) +
236 FTensor::levi_civita<int>(i, l, k) * t_hat(l, j)) *
237 t_w_vee(m))
238
239 +
240
241 diff_b *
242 (
243
244 t_hat(i, l) * t_hat(l, j) * t_kd(k, m)
245
246 +
247
248 FTensor::levi_civita<int>(i, l, m) * t_hat(l, j) * t_w_vee(k)
249
250 +
251
252 t_hat(i, l) * FTensor::levi_civita<int>(l, j, m) * t_w_vee(k)
253
254 )
255
256 +
257
258 diff_diff_b * t_hat(i, l) * t_hat(l, j) * t_w_vee(k) * t_w_vee(m);
259
260 return t_diff_diff_exp;
261 };
262
263 if (std::fabs(theta) < std::numeric_limits<T2>::epsilon()) {
264 return get_tensor(1., -1. / 3., 1. / 15., 0., 1. / 1.2, 1. / 90.);
265 }
266
267 const auto ss = sin(theta);
268 const auto a = ss / theta;
269
270 const auto theta2 = theta * theta;
271 const auto cc = cos(theta);
272 const auto diff_a = (theta * cc - ss) / (theta2 * theta);
273 const auto diff_diff_a =
274 -(3 * theta * cc + (-3 * theta2) * ss) / pow(theta, 5);
275
276 const auto ss_2 = sin(theta / 2.);
277 const auto cc_2 = cos(theta / 2.);
278 const auto b = 2. * ss_2 * ss_2 / theta2;
279 const auto diff_b =
280 (2. * theta * ss_2 * cc_2 - 4. * ss_2 * ss_2) / (theta2 * theta2);
281 const auto diff_diff_b =
282 (8. + (-8. + theta2) * cc - 5. * theta * ss) / (std::pow(theta, 6));
283
284 return get_tensor(a, diff_a, diff_diff_a, b, diff_b, diff_diff_b);
285 }
286
287 template <typename T1, typename T2>
288 inline static auto JlImpl(FTensor::Tensor1<T1, dim> &t_w_vee,
289 const T2 &theta) {
290 if (std::fabs(theta) < std::numeric_limits<T2>::epsilon()) {
291 return genericFormImpl(t_w_vee, 0.5, 1. / 6.);
292 }
293 const auto s = sin(theta);
294 const auto s_half = sin(theta / 2);
295 const auto a = 2 * (s_half / theta) * (s_half / theta);
296 const auto b = ((theta - s) / theta) / theta / theta;
297 return genericFormImpl(t_w_vee, a, b);
298 }
299
300 template <typename T1, typename T2>
301 inline static auto JrImpl(FTensor::Tensor1<T1, dim> &t_w_vee,
302 const T2 theta) {
303 if (std::fabs(theta) < std::numeric_limits<T2>::epsilon()) {
304 return genericFormImpl(t_w_vee, -0.5, 1. / 6.);
305 }
306 const auto s = sin(theta);
307 const auto s_half = sin(theta / 2);
308 const auto a = 2 * (s_half / theta) * (s_half / theta);
309 const auto b = ((theta - s) / theta) / theta / theta;
310 return genericFormImpl(t_w_vee, -a, b);
311 }
312
313 template <typename T1, typename T2, typename T3>
314 inline static auto actionImpl(FTensor::Tensor1<T1, dim> &t_w_vee,
315 const T2 theta,
317 using D = typename TensorTypeExtractor<T3>::Type;
319 t_B(i, j) = exp(t_w_vee, theta)(i,k) * t_A(k, j);
320 return t_B;
321 }
322
323
324}; // namespace SO3
325
326}; // namespace LieGroups
#define FTENSOR_INDEX(DIM, I)
constexpr double a
Kronecker Delta class.
constexpr auto t_kd
FTensor::Index< 'i', SPACE_DIM > i
double D
const double n
refractive index of diffusive medium
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
Tensors class implemented by Walter Landry.
Definition FTensor.hpp:51
constexpr std::enable_if<(Dim0<=2 &&Dim1<=2), Tensor2_Expr< Levi_Civita< T >, T, Dim0, Dim1, i, j > >::type levi_civita(const Index< i, Dim0 > &, const Index< j, Dim1 > &)
levi_civita functions to make for easy adhoc use
FTensor::Index< 'm', 3 > m
static auto diffDiffExp(A &&t_w_vee, B &&theta)
Definition Lie.hpp:84
static auto diffExpImpl(FTensor::Tensor1< T1, dim > &t_w_vee, const T2 theta)
Definition Lie.hpp:138
static auto dActionJr(A &&t_w_vee, B &&t_A)
Definition Lie.hpp:74
static auto Jr(A &&t_w_vee, B &&theta)
Definition Lie.hpp:58
static constexpr int dim
Definition Lie.hpp:89
static auto Jl(A &&t_w_vee, B &&theta)
Definition Lie.hpp:53
static auto action(A &&t_w_vee, B &&theta, C &&t_A)
Definition Lie.hpp:63
static auto JrImpl(FTensor::Tensor1< T1, dim > &t_w_vee, const T2 theta)
Definition Lie.hpp:301
static FTENSOR_INDEX(dim, l)
static FTENSOR_INDEX(dim, k)
static auto JlImpl(FTensor::Tensor1< T1, dim > &t_w_vee, const T2 &theta)
Definition Lie.hpp:288
static auto getVee(A &&t_w_hat)
Definition Lie.hpp:39
static auto getHatImpl(FTensor::Tensor1< T, dim > &t_w_vee)
Definition Lie.hpp:106
static auto getHat(T &&w1, T &&w2, T &&w3)
Definition Lie.hpp:35
static FTENSOR_INDEX(dim, j)
static auto genericFormImpl(FTensor::Tensor1< T1, dim > &t_w_vee, const T2 alpha, const T3 beta)
Definition Lie.hpp:114
static auto diffExp(A &&t_w_vee, B &&theta)
Definition Lie.hpp:79
static auto diffDiffExpImpl(FTensor::Tensor1< T1, dim > &t_w_vee, const T2 theta)
Definition Lie.hpp:191
static auto dActionJl(A &&t_w_vee, B &&t_A)
Definition Lie.hpp:69
static auto actionImpl(FTensor::Tensor1< T1, dim > &t_w_vee, const T2 theta, FTensor::Tensor2_symmetric< T3, dim > &t_A)
Definition Lie.hpp:314
static auto expImpl(FTensor::Tensor1< T1, dim > &t_w_vee, const T2 theta)
Definition Lie.hpp:125
static auto getHat(A &&t_w_vee)
Definition Lie.hpp:43
static FTENSOR_INDEX(dim, n)
static FTENSOR_INDEX(dim, m)
static auto getVeeImpl(FTensor::Tensor2< T, dim, dim > &t_w_hat)
Definition Lie.hpp:98
static FTENSOR_INDEX(dim, i)
static auto getVee(T &&w1, T &&w2, T &&w3)
Definition Lie.hpp:27
static auto exp(A &&t_w_vee, B &&theta)
Definition Lie.hpp:48
std::remove_pointer< T >::type Type
Definition Lie.hpp:16