OpenKalman
Spherical.hpp
Go to the documentation of this file.
1 /* This file is part of OpenKalman, a header-only C++ library for
2  * Kalman filters and other recursive filters.
3  *
4  * Copyright (c) 2019-2021 Christopher Lee Ogden <ogden@gatech.edu>
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
9  */
10 
16 #ifndef OPENKALMAN_SPHERICAL_HPP
17 #define OPENKALMAN_SPHERICAL_HPP
18 
19 #include <type_traits>
20 #include <typeinfo>
21 #include <cmath>
22 #include <array>
24 #include "coordinates/interfaces/coordinate_descriptor_traits.hpp"
26 #include "Distance.hpp"
27 #include "Angle.hpp"
28 #include "Inclination.hpp"
29 #include "Any.hpp"
30 
31 
33 {
47  template<typename C1 = Distance, typename C2 = inclination::Radians, typename C3 = angle::Radians>
48 #ifdef __cpp_concepts
49  requires
50  (std::same_as<C1, Distance> and inclination::inclination<C2> and angle::angle<C3>) or
51  (std::same_as<C1, Distance> and inclination::inclination<C3> and angle::angle<C2>) or
52  (std::same_as<C2, Distance> and inclination::inclination<C1> and angle::angle<C3>) or
53  (std::same_as<C2, Distance> and inclination::inclination<C3> and angle::angle<C1>) or
54  (std::same_as<C3, Distance> and inclination::inclination<C1> and angle::angle<C2>) or
55  (std::same_as<C3, Distance> and inclination::inclination<C2> and angle::angle<C1>)
56 #endif
57  struct Spherical
58  {
59 #ifndef __cpp_concepts
60  static_assert(
61  (std::is_same_v<C1, Distance> and inclination::inclination<C2> and angle::angle<C3>) or
62  (std::is_same_v<C1, Distance> and inclination::inclination<C3> and angle::angle<C2>) or
63  (std::is_same_v<C2, Distance> and inclination::inclination<C1> and angle::angle<C3>) or
64  (std::is_same_v<C2, Distance> and inclination::inclination<C3> and angle::angle<C1>) or
65  (std::is_same_v<C3, Distance> and inclination::inclination<C1> and angle::angle<C2>) or
66  (std::is_same_v<C3, Distance> and inclination::inclination<C2> and angle::angle<C1>));
67 #endif
68  };
69 
70 }
71 
72 
73 namespace OpenKalman::interface
74 {
75  namespace detail
76  {
77  // Implementation of polar coordinates.
78  template<typename T, typename Min, typename Max, typename Down, std::size_t d_i, std::size_t a_i, std::size_t i_i>
80  {
81  private:
82 
83  static constexpr auto min = values::fixed_value_of_v<Min>;
84  static constexpr auto max = values::fixed_value_of_v<Max>;
85  static constexpr auto down = values::fixed_value_of_v<Down>;
86  static constexpr std::size_t d2_i = 0, x_i = 1, y_i = 2, z_i = 3;
87 
88  public:
89 
90  static constexpr bool is_specialized = true;
91 
92 
93  static constexpr auto dimension = [](const T&) { return std::integral_constant<std::size_t, 3>{}; };
94 
95 
96  static constexpr auto stat_dimension = [](const T&) { return std::integral_constant<std::size_t, 4>{}; };
97 
98 
99  static constexpr auto is_euclidean = [](const T&) { return std::false_type{}; };
100 
101 
102  static constexpr auto hash_code = [](const T&) -> std::size_t
103  {
104  constexpr auto a = coordinates::internal::get_descriptor_hash_code(coordinates::Angle<Min, Max>{});
105  constexpr auto b = coordinates::internal::get_descriptor_hash_code(coordinates::Inclination<Down>{});
106  constexpr std::size_t f = (a_i * 2 + i_i * 3 - 2);
107  constexpr auto bits = std::numeric_limits<std::size_t>::digits;
108  if constexpr (bits < 32)
109  return std::integral_constant<std::size_t, (a - 0x83B0_uz) + (b - 0x83B0_uz) + f * 0x1000_uz>{};
110  else if constexpr (bits < 64)
111  return std::integral_constant<std::size_t, (a - 0x83B023AB_uz) + (b - 0x83B023AB_uz) + f * 0x10000000_uz>{};
112  else
113  return std::integral_constant<std::size_t, (a - 0x83B023AB3EEFB99A_uz) + (b - 0x83B023AB3EEFB99A_uz) + f * 0x1000000000000000_uz>{};
114  };
115 
116  private:
117 
118  struct flip
119  {
120  template<typename R>
121  constexpr std::decay_t<R> operator()(bool f, R&& r) const
122  {
123  if (f)
124  return values::internal::update_real_part(std::forward<R>(r), -values::real(values::real(r)));
125  else
126  return std::forward<R>(r);
127  }
128  };
129 
130 
131  template<typename...Args>
132  static constexpr auto make_range(Args&&...args)
133  {
134  if constexpr ((... or values::fixed<Args>))
135  {
136  return std::tuple {std::forward<Args>(args)...};
137  }
138  else
139  {
140  using C = std::common_type_t<Args...>;
141  return std::array {static_cast<C>(std::forward<Args>(args))...};
142  }
143  }
144 
145  public:
146 
152  static constexpr auto
153  to_stat_space = [](const T&, auto&& data_view)
154  {
155  decltype(auto) d = collections::get<d_i>(std::forward<decltype(data_view)>(data_view));
156  decltype(auto) i = collections::get<i_i>(std::forward<decltype(data_view)>(data_view));
157  decltype(auto) a = collections::get<a_i>(std::forward<decltype(data_view)>(data_view));
158 
160 
161  auto theta = [](auto&& i)
162  {
163  if constexpr (down == stdex::numbers::pi_v<R>) //< Avoid scaling, if possible.
164  {
165  return std::forward<decltype(i)>(i);
166  }
167  else
168  {
169  constexpr auto scale = values::operation(std::divides{}, values::fixed_pi<R>{}, values::cast_to<R>(Down{}));
170  return values::operation(std::multiplies{}, std::forward<decltype(i)>(i), scale);
171  }
172  }(std::forward<decltype(i)>(i));
173 
174  auto phi = [](auto&& a)
175  {
176  if constexpr (min == -stdex::numbers::pi_v<R> and max == stdex::numbers::pi_v<R>) //< Avoid scaling, if possible.
177  {
178  return std::forward<decltype(a)>(a);
179  }
180  else
181  {
182  constexpr auto period = values::cast_to<R>(values::operation(std::minus{}, Max{}, Min{}));
183  constexpr auto scale = values::operation(std::divides{}, values::fixed_2pi<R>{}, period);
184  return values::operation(std::multiplies{}, std::forward<decltype(a)>(a), scale);
185  }
186  }(std::forward<decltype(a)>(a));
187 
188  auto x = values::operation(std::multiplies{}, values::sin(theta), values::cos(phi));
189  auto y = values::operation(std::multiplies{}, values::sin(theta), values::sin(phi));
190  auto z = values::cos(theta);
191 
192  auto f = values::signbit(values::real(d));
193 
194  return make_range(
195  values::operation(flip{}, f, std::forward<decltype(d)>(d)),
196  values::operation(flip{}, f, std::move(x)),
197  values::operation(flip{}, f, std::move(y)),
198  values::operation(flip{}, f, std::move(z)));
199  };
200 
201  private:
202 
203  struct calc_theta
204  {
205  template<typename R>
206  constexpr auto operator()(R h, const R& z) const
207  {
208  return (R{down} / stdex::numbers::pi_v<R>) * (h == R{0} ? std::move(h) : values::acos(z/h));
209  }
210  };
211 
212 
213  struct calc_phi
214  {
215  template<typename R>
216  constexpr auto operator()(R hypot_xy, const R& x, const R& signed_scale) const
217  {
218  return signed_scale * (hypot_xy == R{0} ? std::move(hypot_xy) : values::acos(x / hypot_xy));
219  }
220  };
221 
222 
223  struct wrap_phi
224  {
225  template<typename R>
226  constexpr auto operator()(const R& phi_real) const
227  {
228  constexpr R period = max - min;
229  if (phi_real < R{min}) return phi_real + period;
230  if (phi_real >= R{max}) return phi_real - period;
231  return phi_real;
232  }
233  };
234 
235 
236  template<typename D, typename I, typename A>
237  static constexpr auto make_ordered_range(D d, I i, A a)
238  {
239  if constexpr (d_i == 0 and i_i == 1 and a_i == 2)
240  return make_range(std::move(d), std::move(i), std::move(a));
241  else if constexpr (d_i == 0 and a_i == 1 and i_i == 2)
242  return make_range(std::move(d), std::move(a), std::move(i));
243  else if constexpr (i_i == 0 and d_i == 1 and a_i == 2)
244  return make_range(std::move(i), std::move(d), std::move(a));
245  else if constexpr (a_i == 0 and d_i == 1 and i_i == 2)
246  return make_range(std::move(a), std::move(d), std::move(i));
247  else if constexpr (i_i == 0 and a_i == 1 and d_i == 2)
248  return make_range(std::move(i), std::move(a), std::move(d));
249  else // if constexpr (a_i == 0 and i_i == 1 and d_i == 2)
250  return make_range(std::move(a), std::move(i), std::move(d));
251  }
252 
253  public:
254 
260  static constexpr auto
261  from_stat_space = [](const T&, auto&& data_view)
262  {
263  decltype(auto) d = collections::get<d2_i>(std::forward<decltype(data_view)>(data_view));
264  decltype(auto) x = collections::get<x_i>(std::forward<decltype(data_view)>(data_view));
265  decltype(auto) y = collections::get<y_i>(std::forward<decltype(data_view)>(data_view));
266  decltype(auto) z = collections::get<z_i>(std::forward<decltype(data_view)>(data_view));
267 
269 
270  constexpr auto period = values::cast_to<R>(values::operation(std::minus{}, Max{}, Min{}));
271  constexpr auto scale = values::operation(std::divides{}, period, values::fixed_2pi<R>{});
272 
273  auto signed_scale = values::copysign(scale, values::real(y));
274  if constexpr (values::fixed<decltype(d)> and values::fixed<decltype(x)> and values::fixed<decltype(y)> and values::fixed<decltype(z)>)
275  static_assert(values::fixed<decltype(signed_scale)>);
276  auto hypot_xy = values::hypot(x, std::forward<decltype(y)>(y));
277  auto x2y2 = values::operation(std::multiplies{}, hypot_xy, hypot_xy);
278  auto z2 = values::operation(std::multiplies{}, z, z);
279  auto h = values::sqrt(values::operation(std::plus{}, x2y2, z2));
280 
281  auto theta = values::operation(calc_theta{}, std::move(h), z);
282  auto phi = values::operation(calc_phi{}, std::move(hypot_xy), x, signed_scale);
283 
284  return make_ordered_range(
285  std::forward<decltype(d)>(d),
286  std::move(theta),
287  values::internal::update_real_part(std::move(phi), values::operation(wrap_phi{}, values::real(phi))));
288  };
289 
290  private:
291 
292  struct wrap_theta
293  {
294  template<typename R>
295  constexpr auto operator()(bool flip_d, R i_a) const
296  {
297  constexpr R half_period {down};
298  if (i_a > half_period) return flip_d ? i_a - half_period : R{down * 2} - i_a;
299  return flip_d ? half_period - i_a : std::move(i_a);
300  }
301  };
302 
303 
304  struct wrap_phi_mod
305  {
306  template<typename R>
307  constexpr auto operator()(bool flip_a, R a_r) const
308  {
309  constexpr R period = max - min;
310  R a_real = flip_a ? a_r + period * R{0.5} : std::move(a_r);
311  auto ar = values::fmod(a_real - R{min}, period);
312  return (ar < 0 ? ar + period : std::move(ar)) + R{min};
313  }
314  };
315 
316  public:
317 
322  static constexpr auto
323  wrap = [](const T&, auto&& data_view)
324  {
325  decltype(auto) d = collections::get<d_i>(std::forward<decltype(data_view)>(data_view));
326  decltype(auto) i = collections::get<i_i>(std::forward<decltype(data_view)>(data_view));
327  decltype(auto) a = collections::get<a_i>(std::forward<decltype(data_view)>(data_view));
328 
330  auto d_real = values::real(values::real(d));
331  auto flip_d = values::signbit(d_real);
332  auto d_new = values::internal::update_real_part(std::forward<decltype(d)>(d), values::abs(d_real));
333 
334  constexpr auto i_period = values::operation(std::multiplies{}, values::cast_to<R>(Down{}), values::fixed_value<R, 2>{});
335  auto i_real = values::real(values::real(i));
336  auto im = values::fmod(i_real, i_period);
337  auto iabs = values::abs(im);
338  auto high_i = values::operation(std::greater{}, iabs, values::cast_to<R>(Down{}));
339  auto flip_i = values::operation(std::not_equal_to{}, values::signbit(im), high_i);
340  auto i_new = values::internal::update_real_part(std::forward<decltype(i)>(i), values::operation(wrap_theta{}, flip_d, std::move(iabs)));
341 
342  auto flip_a = values::operation(std::not_equal_to{}, flip_i, flip_d);
343  auto aw = values::operation(wrap_phi_mod{}, flip_a, values::real(values::real(a)));
344  auto a_new = values::internal::update_real_part(std::forward<decltype(a)>(a), aw);
345 
346  return make_ordered_range(std::move(d_new), std::move(i_new), std::move(a_new));
347  };
348 
349  };
350 
351  }
352 
353 
358  template<typename Down, typename Min, typename Max>
359  struct coordinate_descriptor_traits<coordinates::Spherical<coordinates::Distance, coordinates::Inclination<Down>, coordinates::Angle<Min, Max>>>
360  : detail::SphericalBase<coordinates::Spherical<coordinates::Distance, coordinates::Inclination<Down>, coordinates::Angle<Min, Max>>, Min, Max, Down, 0, 2, 1>
361  {};
362 
363 
368  template<typename Min, typename Max, typename Down>
369  struct coordinate_descriptor_traits<coordinates::Spherical<coordinates::Distance, coordinates::Angle<Min, Max>, coordinates::Inclination<Down>>>
370  : detail::SphericalBase<coordinates::Spherical<coordinates::Distance, coordinates::Angle<Min, Max>, coordinates::Inclination<Down>>, Min, Max, Down, 0, 1, 2>
371  {};
372 
373 
378  template<typename Min, typename Max, typename Down>
379  struct coordinate_descriptor_traits<coordinates::Spherical<coordinates::Angle<Min, Max>, coordinates::Distance, coordinates::Inclination<Down>>>
380  : detail::SphericalBase<coordinates::Spherical<coordinates::Angle<Min, Max>, coordinates::Distance, coordinates::Inclination<Down>>, Min, Max, Down, 1, 0, 2>
381  {};
382 
383 
388  template<typename Down, typename Min, typename Max>
389  struct coordinate_descriptor_traits<coordinates::Spherical<coordinates::Inclination<Down>, coordinates::Distance, coordinates::Angle<Min, Max>>>
390  : detail::SphericalBase<coordinates::Spherical<coordinates::Inclination<Down>, coordinates::Distance, coordinates::Angle<Min, Max>>, Min, Max, Down, 1, 2, 0>
391  {};
392 
393 
398  template<typename Min, typename Max, typename Down>
399  struct coordinate_descriptor_traits<coordinates::Spherical<coordinates::Angle<Min, Max>, coordinates::Inclination<Down>, coordinates::Distance>>
400  : detail::SphericalBase<coordinates::Spherical<coordinates::Angle<Min, Max>, coordinates::Inclination<Down>, coordinates::Distance>, Min, Max, Down, 2, 0, 1>
401  {};
402 
403 
408  template<typename Down, typename Min, typename Max>
409  struct coordinate_descriptor_traits<coordinates::Spherical<coordinates::Inclination<Down>, coordinates::Angle<Min, Max>, coordinates::Distance>>
410  : detail::SphericalBase<coordinates::Spherical<coordinates::Inclination<Down>, coordinates::Angle<Min, Max>, coordinates::Distance>, Min, Max, Down, 2, 1, 0>
411  {};
412 
413 
414 }
415 
416 
417 namespace std
418 {
419  template<typename Min1, typename Max1, typename Min2, typename Max2, typename Down1, typename Down2>
420  struct common_type<
421  OpenKalman::coordinates::Spherical<
422  OpenKalman::coordinates::Distance,
423  OpenKalman::coordinates::Inclination<Down1>,
424  OpenKalman::coordinates::Angle<Min1, Max1>>,
426  OpenKalman::coordinates::Distance,
427  OpenKalman::coordinates::Inclination<Down2>,
428  OpenKalman::coordinates::Angle<Min2, Max2>>>
429  : std::conditional<
430  OpenKalman::values::fixed_value_of_v<Min1> == OpenKalman::values::fixed_value_of_v<Min2> and
431  OpenKalman::values::fixed_value_of_v<Max1> == OpenKalman::values::fixed_value_of_v<Max2> and
432  OpenKalman::values::fixed_value_of_v<Down1> == OpenKalman::values::fixed_value_of_v<Down2>,
433  OpenKalman::coordinates::Spherical<
434  OpenKalman::coordinates::Distance,
435  OpenKalman::coordinates::Inclination<Down1>,
436  OpenKalman::coordinates::Angle<Min1, Max1>>,
437  OpenKalman::coordinates::Any<>> {};
438 
439 
440  template<typename Min1, typename Max1, typename Min2, typename Max2, typename Down1, typename Down2>
441  struct common_type<
442  OpenKalman::coordinates::Spherical<
443  OpenKalman::coordinates::Distance,
444  OpenKalman::coordinates::Angle<Min1, Max1>,
445  OpenKalman::coordinates::Inclination<Down1>>,
447  OpenKalman::coordinates::Distance,
448  OpenKalman::coordinates::Angle<Min2, Max2>,
449  OpenKalman::coordinates::Inclination<Down2>>>
450  : std::conditional<
451  OpenKalman::values::fixed_value_of_v<Min1> == OpenKalman::values::fixed_value_of_v<Min2> and
452  OpenKalman::values::fixed_value_of_v<Max1> == OpenKalman::values::fixed_value_of_v<Max2> and
453  OpenKalman::values::fixed_value_of_v<Down1> == OpenKalman::values::fixed_value_of_v<Down2>,
454  OpenKalman::coordinates::Spherical<
455  OpenKalman::coordinates::Distance,
456  OpenKalman::coordinates::Angle<Min1, Max1>,
457  OpenKalman::coordinates::Inclination<Down1>>,
458  OpenKalman::coordinates::Any<>> {};
459 
460 
461  template<typename Min1, typename Max1, typename Min2, typename Max2, typename Down1, typename Down2>
462  struct common_type<
463  OpenKalman::coordinates::Spherical<
464  OpenKalman::coordinates::Inclination<Down1>,
465  OpenKalman::coordinates::Distance,
466  OpenKalman::coordinates::Angle<Min1, Max1>>,
468  OpenKalman::coordinates::Inclination<Down2>,
469  OpenKalman::coordinates::Distance,
470  OpenKalman::coordinates::Angle<Min2, Max2>>>
471  : std::conditional<
472  OpenKalman::values::fixed_value_of_v<Min1> == OpenKalman::values::fixed_value_of_v<Min2> and
473  OpenKalman::values::fixed_value_of_v<Max1> == OpenKalman::values::fixed_value_of_v<Max2> and
474  OpenKalman::values::fixed_value_of_v<Down1> == OpenKalman::values::fixed_value_of_v<Down2>,
475  OpenKalman::coordinates::Spherical<
476  OpenKalman::coordinates::Inclination<Down1>,
477  OpenKalman::coordinates::Distance,
478  OpenKalman::coordinates::Angle<Min1, Max1>>,
479  OpenKalman::coordinates::Any<>> {};
480 
481 
482  template<typename Min1, typename Max1, typename Min2, typename Max2, typename Down1, typename Down2>
483  struct common_type<
484  OpenKalman::coordinates::Spherical<
485  OpenKalman::coordinates::Inclination<Down1>,
486  OpenKalman::coordinates::Angle<Min1, Max1>,
487  OpenKalman::coordinates::Distance>,
489  OpenKalman::coordinates::Inclination<Down2>,
490  OpenKalman::coordinates::Angle<Min2, Max2>,
491  OpenKalman::coordinates::Distance>>
492  : std::conditional<
493  OpenKalman::values::fixed_value_of_v<Min1> == OpenKalman::values::fixed_value_of_v<Min2> and
494  OpenKalman::values::fixed_value_of_v<Max1> == OpenKalman::values::fixed_value_of_v<Max2> and
495  OpenKalman::values::fixed_value_of_v<Down1> == OpenKalman::values::fixed_value_of_v<Down2>,
496  OpenKalman::coordinates::Spherical<
497  OpenKalman::coordinates::Inclination<Down1>,
498  OpenKalman::coordinates::Angle<Min1, Max1>,
499  OpenKalman::coordinates::Distance>,
500  OpenKalman::coordinates::Any<>> {};
501 
502 
503  template<typename Min1, typename Max1, typename Min2, typename Max2, typename Down1, typename Down2>
504  struct common_type<
505  OpenKalman::coordinates::Spherical<
506  OpenKalman::coordinates::Angle<Min1, Max1>,
507  OpenKalman::coordinates::Distance,
508  OpenKalman::coordinates::Inclination<Down1>>,
510  OpenKalman::coordinates::Angle<Min2, Max2>,
511  OpenKalman::coordinates::Distance,
512  OpenKalman::coordinates::Inclination<Down2>>>
513  : std::conditional<
514  OpenKalman::values::fixed_value_of_v<Min1> == OpenKalman::values::fixed_value_of_v<Min2> and
515  OpenKalman::values::fixed_value_of_v<Max1> == OpenKalman::values::fixed_value_of_v<Max2> and
516  OpenKalman::values::fixed_value_of_v<Down1> == OpenKalman::values::fixed_value_of_v<Down2>,
517  OpenKalman::coordinates::Spherical<
518  OpenKalman::coordinates::Angle<Min1, Max1>,
519  OpenKalman::coordinates::Distance,
520  OpenKalman::coordinates::Inclination<Down1>>,
521  OpenKalman::coordinates::Any<>> {};
522 
523 
524  template<typename Min1, typename Max1, typename Min2, typename Max2, typename Down1, typename Down2>
525  struct common_type<
526  OpenKalman::coordinates::Spherical<
527  OpenKalman::coordinates::Angle<Min1, Max1>,
528  OpenKalman::coordinates::Inclination<Down1>,
529  OpenKalman::coordinates::Distance>,
531  OpenKalman::coordinates::Angle<Min2, Max2>,
532  OpenKalman::coordinates::Inclination<Down2>,
533  OpenKalman::coordinates::Distance>>
534  : std::conditional<
535  OpenKalman::values::fixed_value_of_v<Min1> == OpenKalman::values::fixed_value_of_v<Min2> and
536  OpenKalman::values::fixed_value_of_v<Max1> == OpenKalman::values::fixed_value_of_v<Max2> and
537  OpenKalman::values::fixed_value_of_v<Down1> == OpenKalman::values::fixed_value_of_v<Down2>,
538  OpenKalman::coordinates::Spherical<
539  OpenKalman::coordinates::Angle<Min1, Max1>,
540  OpenKalman::coordinates::Inclination<Down1>,
541  OpenKalman::coordinates::Distance>,
542  OpenKalman::coordinates::Any<>> {};
543 
544 
545  template<typename C1, typename C2, typename C3, typename Scalar>
546  struct common_type<OpenKalman::coordinates::Spherical<C1, C2, C3>, OpenKalman::coordinates::Any<Scalar>>
547  : common_type<OpenKalman::coordinates::Any<Scalar>, OpenKalman::coordinates::Spherical<C1, C2, C3>> {};
548 
549 
550  template<typename C1, typename C2, typename C3, typename T>
551  struct common_type<OpenKalman::coordinates::Spherical<C1, C2, C3>, T>
552  : std::conditional_t<
553  OpenKalman::coordinates::descriptor<T>,
554  OpenKalman::stdex::type_identity<OpenKalman::coordinates::Any<>>,
555  std::monostate> {};
556 }
557 
558 #endif
A fixed version of pi.
Definition: fixed-constants.hpp:33
constexpr auto fmod(const X &x, const Y &y)
A constexpr function for fmod.
Definition: fmod.hpp:44
Definition of the Distance class.
Definition: basics.hpp:41
decltype(auto) constexpr to_stat_space(const T &t, R &&data_view)
Maps a range reflecting vector-space data to a corresponding range in a vector space for directional ...
Definition: to_stat_space.hpp:44
A fixed version of 2*pi.
Definition: fixed-constants.hpp:73
A non-negative real number φ representing an inclination (angle from the positive z axis)...
Definition: Inclination.hpp:40
typename real_type_of< T >::type real_type_of_t
Helper template for real_type_of.
Definition: real_type_of.hpp:55
Definition: fixed_value.hpp:41
decltype(auto) constexpr wrap(const T &t, R &&data_view)
wraps a range reflecting vector-space data to its primary range.
Definition: wrap.hpp:59
constexpr auto copysign(const Mag &mag, const Sgn &sgn)
A constexpr function for copysign.
Definition: copysign.hpp:48
constexpr auto cos(const Arg &arg)
Constexpr alternative to the std::cos function.
Definition: cos.hpp:42
constexpr auto sin(const Arg &arg)
Constexpr alternative to the std::sin function.
Definition: sin.hpp:43
The root namespace for OpenKalman.
Definition: basics.hpp:34
The namespace for features relating to coordinates::pattern object.
Definition: compares_with.hpp:25
Definition for get_descriptor_hash_code.
Inclusion file for collections.
constexpr auto sqrt(const Arg &arg)
A constexpr alternative to std::sqrt.
Definition: sqrt.hpp:46
A coordinates::descriptor reflecting spherical coordinates according to the ISO 80000-2:2019 conventi...
Definition: Spherical.hpp:57
constexpr auto real(const Arg &arg)
A constexpr function to obtain the real part of a (complex) number.
Definition: real.hpp:40
constexpr auto acos(const Arg &arg)
Constexpr alternative to the std::acos function.
Definition: acos.hpp:41
Traits for coordinates::pattern objects.
Definition: coordinate_descriptor_traits.hpp:36
constexpr auto signbit(const Arg &arg)
A constexpr function analogous to std::signbit.
Definition: signbit.hpp:41
constexpr auto abs(const Arg &arg)
A constexpr alternative to std::abs.
Definition: abs.hpp:38
Definition of the Inclination class and related limits.
decltype(auto) constexpr from_stat_space(const T &t, R &&stat_data_view)
Maps a range in a vector space for directional-statistics back to a range reflecting vector-space dat...
Definition: from_stat_space.hpp:44
constexpr bool fixed
T is a value that is determinable at compile time.
Definition: fixed.hpp:66
auto scale(M &&m, const S s)
Scale a covariance by a factor.
Definition: covariance-arithmetic.hpp:518
An angle or any other simple modular value.
Definition: Angle.hpp:46
constexpr auto hypot(const Args &...args)
A constexpr alternative to std::hypot.
Definition: hypot.hpp:45
Definition: Any.hpp:42
Definition of the Angle class and related limits.
constexpr auto operation(Operation &&op, Args &&...args)
A potentially constant-evaluated operation involving some number of values.
Definition: operation.hpp:98