OpenKalman
tensor_order.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) 2022-2023 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_TENSOR_ORDER_HPP
17 #define OPENKALMAN_TENSOR_ORDER_HPP
18 
19 #include "coordinates/coordinates.hpp"
22 
23 namespace OpenKalman
24 {
25 
26  namespace detail
27  {
28  template<typename T>
29  constexpr auto get_tensor_order_of_impl(std::index_sequence<>, const T& t)
30  {
31  return std::integral_constant<std::size_t, 0>{};
32  }
33 
34  template<std::size_t I, std::size_t...Is, typename T>
35  constexpr auto get_tensor_order_of_impl(std::index_sequence<I, Is...>, const T& t)
36  {
37  auto dim = get_index_extent<I>(t);
38  if constexpr (values::fixed<decltype(dim)>)
39  {
40  constexpr std::size_t stat_dim = std::decay_t<decltype(dim)>::value;
41  if constexpr (stat_dim == 0) return dim;
42  else
43  {
44  auto next = get_tensor_order_of_impl(std::index_sequence<Is...> {}, t);
45  if constexpr (stat_dim == 1) return next;
46  else return values::operation(std::plus{}, std::integral_constant<std::size_t, 1>{}, next);
47  }
48  }
49  else
50  {
51  if (dim == 0) return dim;
52  else
53  {
54  std::size_t next = get_tensor_order_of_impl(std::index_sequence<Is...> {}, t);
55  if (dim == 1) return next;
56  else return 1_uz + next;
57  }
58  }
59  }
60  }
61 
62 
70 #ifdef __cpp_concepts
71  template<indexible T>
72  constexpr values::index auto
73 #else
74  template<typename T, std::enable_if_t<indexible<T>, int> = 0>
75  constexpr auto
76 #endif
77  tensor_order(const T& t)
78  {
79  if constexpr (values::fixed<decltype(count_indices(t))>)
80  {
81  constexpr std::make_index_sequence<std::decay_t<decltype(count_indices(t))>::value> seq;
82  return detail::get_tensor_order_of_impl(seq, t);
83  }
84  else
85  {
86  std::size_t count = 0;
87  for (std::size_t i = 0; i < count_indices(t); ++i)
88  {
89  auto dim = get_index_extent(t, i);
90  if (dim > 1) ++count;
91  else if (dim == 0) return 0;
92  }
93  return count;
94  }
95  }
96 
97 
98 }
99 
100 #endif
constexpr auto count_indices(const T &)
Get the number of indices necessary to address all the components of an indexible object...
Definition: count_indices.hpp:51
Definition of get_index_extent function.
constexpr bool value
T is a fixed or dynamic value that is reducible to a number.
Definition: value.hpp:45
Definition of count_indices.
constexpr auto tensor_order(const T &t)
Return the tensor order of T (i.e., the number of indices of dimension greater than 1)...
Definition: tensor_order.hpp:77
constexpr auto get_index_extent(T &&t, I i=I{})
Get the runtime dimensions of index N of indexible T.
Definition: get_index_extent.hpp:36
The root namespace for OpenKalman.
Definition: basics.hpp:34
Definition: trait_backports.hpp:64
constexpr bool index
T is an index value.
Definition: index.hpp:62
constexpr bool fixed
T is a value that is determinable at compile time.
Definition: fixed.hpp:66
constexpr auto operation(Operation &&op, Args &&...args)
A potentially constant-evaluated operation involving some number of values.
Definition: operation.hpp:98