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 
20 namespace OpenKalman
21 {
22 
23  namespace detail
24  {
25  template<typename T>
26  constexpr auto get_tensor_order_of_impl(std::index_sequence<>, const T& t) { return 0; }
27 
28  template<std::size_t I, std::size_t...Is, typename T>
29  constexpr auto get_tensor_order_of_impl(std::index_sequence<I, Is...>, const T& t)
30  {
31  auto dim = get_index_dimension_of<I>(t);
32  if constexpr (values::fixed<decltype(dim)>)
33  {
34  constexpr std::size_t stat_dim = std::decay_t<decltype(dim)>::value;
35  if constexpr (stat_dim == 0) return dim;
36  else
37  {
38  auto next = get_tensor_order_of_impl(std::index_sequence<Is...> {}, t);
39  if constexpr (stat_dim == 1) return next;
40  else if constexpr (values::fixed<decltype(next)>)
41  return std::integral_constant<std::size_t, 1_uz + std::decay_t<decltype(next)>::value> {};
42  else
43  return 1_uz + next;
44  }
45  }
46  else
47  {
48  if (dim == 0) return dim;
49  else
50  {
51  std::size_t next = get_tensor_order_of_impl(std::index_sequence<Is...> {}, t);
52  if (dim == 1) return next;
53  else return 1_uz + next;
54  }
55  }
56  }
57  }
58 
59 
67 #ifdef __cpp_concepts
68  template<interface::count_indices_defined_for T> requires interface::get_vector_space_descriptor_defined_for<T>
69  constexpr values::index auto
70 #else
71  template<typename T, std::enable_if_t<interface::count_indices_defined_for<T> and interface::get_vector_space_descriptor_defined_for<T>, int> = 0>
72  constexpr auto
73 #endif
74  tensor_order(const T& t)
75  {
76  if constexpr (values::fixed<decltype(count_indices(t))>)
77  {
79  return detail::get_tensor_order_of_impl(seq, t);
80  }
81  else
82  {
83  std::size_t count = 0;
84  for (std::size_t i = 0; i < count_indices(t); ++i)
85  {
86  auto dim = get_index_dimension_of(t, i);
87  if (dim > 1) ++count;
88  else if (dim == 0) return 0;
89  }
90  return count;
91  }
92  }
93 
94 
95 } // namespace OpenKalman
96 
97 #endif //OPENKALMAN_TENSOR_ORDER_HPP
constexpr auto count_indices(const T &t)
Get the number of indices available to address the components of an indexible object.
Definition: count_indices.hpp:33
Definition: tuple_reverse.hpp:103
constexpr bool value
T is numerical value or is reducible to a numerical value.
Definition: value.hpp:31
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:74
The root namespace for OpenKalman.
Definition: basics.hpp:34
constexpr bool index
T is an index value.
Definition: index.hpp:56
constexpr bool fixed
T is a values::value that is determinable at compile time.
Definition: fixed.hpp:60
constexpr auto get_index_dimension_of(const T &t, N n=N{})
Get the runtime dimensions of index N of indexible T.
Definition: get_index_dimension_of.hpp:34