16 #ifndef OPENKALMAN_ANGLE_HPP 17 #define OPENKALMAN_ANGLE_HPP 19 #include "values/functions/internal/update_real_part.hpp" 21 #include "coordinates/interfaces/coordinate_descriptor_traits.hpp" 37 template<values::fixed Min = values::fixed_minus_pi<
long double>, values::fixed Max = values::fixed_pi<
long double>>
38 requires (values::fixed_value_of_v<Min> <= 0) and (values::
fixed_value_of_v<Max> > 0) and
44 template<
typename Min = values::fixed_minus_pi<
long double>,
typename Max = values::fixed_pi<
long double>>
48 #ifndef __cpp_concepts 49 static_assert(values::fixed<Min>);
50 static_assert(values::fixed<Max>);
51 static_assert(values::fixed_value_of_v<Min> <= 0);
52 static_assert(values::fixed_value_of_v<Max> > 0);
53 static_assert(not values::complex<Min>);
54 static_assert(not values::complex<Max>);
90 template<
typename Min,
typename Max>
102 static constexpr
bool angle =
117 template<
typename Min,
typename Max>
123 static constexpr
auto min = values::fixed_value_of_v<Min>;
124 static constexpr
auto max = values::fixed_value_of_v<Max>;
127 template<
typename...Args>
128 static constexpr
auto make_range(Args&&...args)
130 if constexpr ((... or values::fixed<Args>))
131 return std::tuple {std::forward<Args>(args)...};
133 return std::array<std::common_type_t<Args...>,
sizeof...(Args)> {std::forward<Args>(args)...};
138 static constexpr
bool is_specialized =
true;
141 static constexpr
auto dimension = [](
const T&) {
return std::integral_constant<std::size_t, 1>{}; };
144 static constexpr
auto stat_dimension = [](
const T&) {
return std::integral_constant<std::size_t, 2>{}; };
147 static constexpr
auto is_euclidean = [](
const T&) {
return std::false_type{}; };
150 static constexpr
auto hash_code = [](
const T&)
152 constexpr
auto min_float =
static_cast<float>(min);
153 constexpr
auto max_float =
static_cast<float>(max);
154 constexpr
float a = (max_float * 3.f + min_float * 2.f + 1.f) / (max_float - min_float + 1.f);
155 constexpr
auto bits = std::numeric_limits<std::size_t>::digits;
156 if constexpr (bits < 32)
157 return std::integral_constant<std::size_t, 0x62BB_uz + static_cast<std::size_t>(a * a * 0x1.p2f)>{};
158 else if constexpr (bits < 64)
159 return std::integral_constant<std::size_t, 0x62BB0D37_uz + static_cast<std::size_t>(a * a * 0x1.p4f)>{};
161 return std::integral_constant<std::size_t, 0x62BB0D37A58D6F96_uz + static_cast<std::size_t>(a * a * 0x1.p8f)>{};
168 static constexpr
auto 171 decltype(
auto) a = collections::get<0>(std::forward<decltype(data_view)>(data_view));
173 if constexpr (min == -stdex::numbers::pi_v<R> and max == stdex::numbers::pi_v<R>)
179 constexpr
auto period = values::cast_to<R>(
values::operation(std::minus{}, Max{}, Min{}));
181 auto phi =
values::operation(std::multiplies{}, std::forward<decltype(a)>(a), scale);
191 constexpr R operator()(
const R& phi_real)
const 193 constexpr R period = max - min;
194 if (phi_real < R{min})
return phi_real + period;
195 if (phi_real >= R{max})
return phi_real - period;
206 static constexpr
auto 209 decltype(
auto) x = collections::get<0>(std::forward<decltype(data_view)>(data_view));
210 decltype(
auto) y = collections::get<1>(std::forward<decltype(data_view)>(data_view));
212 if constexpr (min == -stdex::numbers::pi_v<R> and max == stdex::numbers::pi_v<R>)
214 return std::array {
values::atan2(std::forward<decltype(y)>(y), std::forward<decltype(x)>(x))};
218 constexpr
auto period = values::cast_to<R>(
values::operation(std::minus{}, Max{}, Min{}));
221 return std::array {values::internal::update_real_part(std::move(phi),
231 constexpr R operator()(
const R& phi_real)
const 233 constexpr R period = max - min;
234 if (phi_real >= R{min} and phi_real < max)
return phi_real;
235 R phi_real_mod {
values::fmod(phi_real - R{min}, period)};
236 if (phi_real_mod < 0)
return R{min} + phi_real_mod + period;
237 return R{min} + phi_real_mod;
246 static constexpr
auto 247 wrap = [](
const T&,
auto&& data_view)
249 decltype(
auto) phi = collections::get<0>(std::forward<decltype(data_view)>(data_view));
250 return std::array {values::internal::update_real_part(std::forward<decltype(phi)>(phi),
261 template<
typename Min1,
typename Max1,
typename Min2,
typename Max2>
264 OpenKalman::values::fixed_value_of_v<Min1> == OpenKalman::values::fixed_value_of_v<Min2> and
265 OpenKalman::values::fixed_value_of_v<Max1> == OpenKalman::values::fixed_value_of_v<Max2>,
266 OpenKalman::coordinates::Angle<Min1, Max1>,
267 OpenKalman::coordinates::Any<>> {};
270 template<
typename Min1,
typename Max1,
typename Scalar>
272 : common_type<OpenKalman::coordinates::Any<Scalar>, OpenKalman::coordinates::Angle<Min1, Max1>> {};
275 template<
typename Min1,
typename Max1,
typename T>
276 struct common_type<OpenKalman::coordinates::Angle<Min1, Max1>, T>
277 : std::conditional_t<
278 OpenKalman::coordinates::descriptor<T>,
279 OpenKalman::stdex::type_identity<OpenKalman::coordinates::Any<>>,
constexpr auto fmod(const X &x, const Y &y)
A constexpr function for fmod.
Definition: fmod.hpp:44
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
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
typename value_type_of< T >::type value_type_of_t
Helper template for value_type_of.
Definition: value_type_of.hpp:52
constexpr auto fixed_value_of_v
Helper template for fixed_value_of.
Definition: fixed_value_of.hpp:84
constexpr bool complex
T is a value that reduces to std::complex or a custom complex type.
Definition: complex.hpp:47
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 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
Inclusion file for collections.
constexpr auto atan2(const Y &y_arg, const X &x_arg)
Constexpr alternative to the std::atan2 function.
Definition: atan2.hpp:46
constexpr auto real(const Arg &arg)
A constexpr function to obtain the real part of a (complex) number.
Definition: real.hpp:40
Traits for coordinates::pattern objects.
Definition: coordinate_descriptor_traits.hpp:36
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
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 operation(Operation &&op, Args &&...args)
A potentially constant-evaluated operation involving some number of values.
Definition: operation.hpp:98