OpenKalman
largest_pattern.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) 2024-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 
17 #ifndef OPENKALMAN_LARGEST_PATTERN_HPP
18 #define OPENKALMAN_LARGEST_PATTERN_HPP
19 
20 #include <algorithm>
24 
26 {
27  namespace detail
28  {
29  template<std::size_t i = 0, typename P,
30  typename MI = std::integral_constant<std::size_t, 0>,
31  typename Max = std::integral_constant<std::size_t, 0>>
32  constexpr auto
33  largest_pattern_fixed(const P& p, MI mi = {}, Max max = {})
34  {
35  if constexpr (i < collections::size_of_v<P>)
36  {
37  auto ix = std::integral_constant<std::size_t, i>{};
38  auto p_i = get_dimension(collections::get<i>(p));
39  auto is_new_max = values::operation(std::greater{}, p_i, max);
40  auto select = [](bool q, std::size_t curr, std::size_t old){ return q ? curr : old; };
41  return largest_pattern_fixed<i + 1>(
42  p,
43  values::operation(select, is_new_max, ix, mi),
44  values::operation(select, is_new_max, p_i, max));
45  }
46  else
47  {
48  return mi;
49  }
50  }
51  }
52 
53 
60 #ifdef __cpp_concepts
61  template<pattern_collection P> requires collections::sized<P> and
62  (collections::size_of_v<P> == stdex::dynamic_extent or collections::size_of_v<P> > 0_uz)
63  constexpr values::index auto
64 #else
65  template<typename P, std::enable_if_t<pattern_collection<P> and collections::sized<P> and
66  (collections::size_of<P>::value == stdex::dynamic_extent or collections::size_of<P>::value > 0_uz), int> = 0>
67  constexpr auto
68 #endif
69  largest_pattern(const P& p)
70  {
71  if constexpr (collections::size_of_v<P> == stdex::dynamic_extent)
72  {
73  auto fn = [](auto a, auto b){ return get_dimension(a) < get_dimension(b); };
74  decltype(auto) pr = collections::views::all(p);
75 #ifdef __cpp_lib_ranges
76  auto it = std::ranges::max_element(pr, fn);
77 #else
78  auto it = std::max_element(pr.begin(), pr.end(), fn);
79 #endif
80  return static_cast<std::size_t>(std::distance(pr.begin(), it));
81  }
82  else
83  {
84  return detail::largest_pattern_fixed(p);
85  }
86  }
87 
88 }
89 
90 #endif
Definition for pattern_collection.
Definition: get_descriptor_dimension.hpp:25
Definition for coordinates::pattern.
constexpr auto get_dimension(const Arg &arg)
Get the vector dimension of coordinates::pattern Arg.
Definition: get_dimension.hpp:54
Inclusion file for collections.
constexpr bool index
T is an index value.
Definition: index.hpp:62
constexpr auto operation(Operation &&op, Args &&...args)
A potentially constant-evaluated operation involving some number of values.
Definition: operation.hpp:98