OpenKalman
make_constant_diagonal_from_descriptors.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 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_MAKE_CONSTANT_DIAGONAL_FROM_DESCRIPTORS_HPP
18 #define OPENKALMAN_MAKE_CONSTANT_DIAGONAL_FROM_DESCRIPTORS_HPP
19 
20 #include <vector>
23 
24 namespace OpenKalman::internal
25 {
30  template<typename T, typename C, typename Descriptors>
31  static constexpr decltype(auto)
32  make_constant_diagonal_from_descriptors(C&& c, Descriptors&& descriptors)
33  {
34  if constexpr (coordinates::pattern_tuple<Descriptors>)
35  {
36  auto new_descriptors = std::tuple_cat(
37  std::tuple(internal::smallest_vector_space_descriptor<scalar_type_of_t<T>>(
38  std::get<0>(std::forward<Descriptors>(descriptors)), std::get<1>(std::forward<Descriptors>(descriptors)))),
39  internal::tuple_slice<2, std::tuple_size_v<Descriptors>>(descriptors));
40  return make_constant<T>(std::forward<C>(c), new_descriptors);
41  }
42  else
43  {
44 #if __cpp_lib_containers_ranges >= 202202L and __cpp_lib_ranges_concat >= 202403L
45  auto new_indices = std::views::concat(
46  internal::smallest_vector_space_descriptor<scalar_type_of_t<T>>(std::ranges::views::take(indices, 2)),
47  indices | std::ranges::views::drop(2));
48 #else
49 #ifdef __cpp_lib_ranges
50  namespace ranges = std::ranges;
51 #endif
52  auto it = ranges::begin(descriptors);
53  auto new_descriptors = std::vector<std::decay_t<decltype(*it)>>{};
54  auto i0 = it;
55  auto i1 = ++it;
56  if (i1 == end(descriptors))
57  {
58  new_descriptors.emplace_back(coordinates::Axis{});
59  }
60  else if (i0 != end(descriptors))
61  {
62  auto d0 = internal::smallest_vector_space_descriptor<scalar_type_of_t<T>>(*i0, *i1);
63  new_descriptors.emplace_back(d0);
64  std::copy(++it, ranges::end(descriptors), ++ranges::begin(new_descriptors));
65  }
66 #endif
67  return make_constant<T>(std::forward<C>(c), new_descriptors);
68  }
69  }
70 
71 } // namespace OpenKalman
72 
73 #endif //OPENKALMAN_MAKE_CONSTANT_DIAGONAL_FROM_DESCRIPTORS_HPP
Definition for coordinates::pattern.
constexpr auto tuple_slice(Arg &&arg)
Takes a slice of a tuple, given an index range.
Definition: tuple_slice.hpp:132
Definition for pattern_tuple.
Definition: basics.hpp:48