OpenKalman
get_uniform_pattern_component.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) 2020-2025 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_GET_UNIFORM_PATTERN_COMPONENT_HPP
17 #define OPENKALMAN_GET_UNIFORM_PATTERN_COMPONENT_HPP
18 
19 #include <optional>
20 #include <algorithm>
23 #include "coordinates/descriptors/Any.hpp"
26 
28 {
29  namespace detail
30  {
31  template<typename A, typename T, std::size_t i, std::size_t...is>
32  constexpr auto
33  equal_tuple_elements(const T& t, std::index_sequence<i, is...>)
34  {
35  auto t0 = collections::get<i>(t);
36  if ((... and compare(t0, collections::get<is>(t))))
37  return std::optional {A{t0}};
38  else
39  return std::optional<A> {};
40  }
41 
42 
43  template<typename T>
44  struct Any_value_type { using type = double; };
45 
46  template<typename S>
47  struct Any_value_type<Any<S>> { using type = S; };
48 
49  }
50 
51 
57 #ifdef __cpp_concepts
58  template<pattern T>
59 #else
60  template<typename T, std::enable_if_t<pattern<T>, int> = 0>
61 #endif
62  constexpr auto
64  {
65  if constexpr (euclidean_pattern<T>)
66  {
67  return std::optional {Dimensions<1>{}};
68  }
69  else if constexpr (descriptor<T>)
70  {
71  if constexpr (dimension_of_v<T> == 1)
72  return std::optional {std::forward<T>(t)};
73  else
74  return std::optional<std::decay_t<T>>{};
75  }
76  else // if constexpr (descriptor_collection<T>)
77  {
80  if constexpr (dimension_of_v<C> == 1)
81  {
82  return std::optional {C{}};
83  }
84  else if constexpr (dimension_of_v<C> != stdex::dynamic_extent or not collections::sized<T>)
85  {
86  return std::optional<A>{};
87  }
88  else if constexpr (collections::size_of_v<T> == 0)
89  {
90  return std::optional<C>{};
91  }
92  else if constexpr (collections::size_of_v<T> == stdex::dynamic_extent)
93  {
94  if (get_is_euclidean(t)) return std::optional {A{Dimensions<1>{}}};
95  decltype(auto) v = collections::views::all(std::forward<T>(t));
96  auto pred = [](const auto& x, const auto& y) -> bool { return compare<stdex::is_neq>(x, y); };
97 #ifdef __cpp_lib_ranges
98  if (std::ranges::adjacent_find(v, pred) == v.end()) return std::optional {A{v.front()}};
99 #else
100  if (std::adjacent_find(v.begin(), v.end(), pred) == v.end()) return std::optional {A{v.front()}};
101 #endif
102  return std::optional<A>{};
103  }
104  else
105  {
106  return detail::equal_tuple_elements<A>(t, std::make_index_sequence<collections::size_of_v<T>>{});
107  }
108  }
109  }
110 
111 }
112 
113 #endif
typename common_descriptor_type< T >::type common_descriptor_type_t
Helper template for common_descriptor_type.
Definition: common_descriptor_type.hpp:126
Definition: get_uniform_pattern_component.hpp:44
constexpr auto compare(const A &a, const B &b)
Compare two coordinates::pattern objects lexicographically.
Definition: compare.hpp:40
constexpr auto get_uniform_pattern_component(T &&t)
If the argument is a uniform pattern, return the 1D component that can be replicated to produce the a...
Definition: get_uniform_pattern_component.hpp:63
Definition for coordinates::pattern.
Definition of coordinates::compare.
constexpr auto get_is_euclidean(const Arg &arg)
Determine, whether coordinates::pattern Arg is euclidean.
Definition: get_is_euclidean.hpp:65
The namespace for features relating to coordinates::pattern object.
Definition: compares_with.hpp:25
constexpr detail::all_closure all
a std::ranges::range_adaptor_closure which returns a view to all members of its collection argument...
Definition: all.hpp:72
Inclusion file for collections.
A structure representing the dimensions associated with of a particular index.
Definition: Dimensions.hpp:42
Definition: trait_backports.hpp:64
Definition: Any.hpp:42
Definition for collections::common_descriptor_type.