OpenKalman
make_constant.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-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 
16 #ifndef OPENKALMAN_MAKE_CONSTANT_HPP
17 #define OPENKALMAN_MAKE_CONSTANT_HPP
18 
19 namespace OpenKalman
20 {
21 
29 #ifdef __cpp_concepts
30  template<indexible T, values::scalar C, pattern_collection Descriptors>
31  constexpr constant_matrix auto
32 #else
33  template<typename T, typename C, typename Ds, std::enable_if_t<
34  indexible<T> and values::scalar<C> and pattern_collection<Ds>, int> = 0>
35  constexpr auto
36 #endif
37  make_constant(C&& c, Descriptors&& descriptors)
38  {
39  decltype(auto) d = internal::remove_trailing_1D_descriptors(std::forward<Descriptors>(descriptors));
40  using D = decltype(d);
42 
43  if constexpr (coordinates::euclidean_pattern_collection<D> and interface::make_constant_defined_for<T, C&&, D>)
44  {
45  return Trait::template make_constant(std::forward<C>(c), std::forward<D>(d));
46  }
47  else if constexpr (interface::make_constant_defined_for<T, C&&, decltype(internal::to_euclidean_vector_space_descriptor_collection(d))>)
48  {
49  auto ed = internal::to_euclidean_vector_space_descriptor_collection(d);
50  return make_vector_space_adapter(Trait::template make_constant(std::forward<C>(c), ed), std::forward<D>(d));
51  }
52  else
53  {
54  // Default behavior if interface function not defined:
55  using Scalar = values::number_type_of_t<C>;
56  using U = std::decay_t<decltype(make_dense_object<T, Layout::none, Scalar>(d))>;
57  return ConstantAdapter<U, std::decay_t<C>> {std::forward<C>(c), std::forward<D>(d)};
58  }
59  }
60 
61 
66 #ifdef __cpp_concepts
67  template<indexible T, values::scalar C, coordinates::pattern...Ds>
68  constexpr constant_matrix auto
69 #else
70  template<typename T, typename C, typename...Ds, std::enable_if_t<
71  indexible<T> and values::scalar<C> and (coordinates::pattern<Ds> and ...), int> = 0>
72  constexpr auto
73 #endif
74  make_constant(C&& c, Ds&&...ds)
75  {
76  return make_constant<T>(std::forward<C>(c), std::tuple {std::forward<Ds>(ds)...});
77  }
78 
79 
87 #ifdef __cpp_concepts
88  template<indexible T, values::scalar C>
89  constexpr constant_matrix auto
90 #else
91  template<typename T, typename C, std::enable_if_t<indexible<T> and values::scalar<C>, int> = 0>
92  constexpr auto
93 #endif
94  make_constant(const T& t, C&& c)
95  {
96  return make_constant<T>(std::forward<C>(c), all_vector_space_descriptors(t));
97  }
98 
99 
109 #ifdef __cpp_concepts
110  template<indexible T, values::scalar C, auto...constant, pattern_collection Ds> requires
111  ((values::fixed<C> and sizeof...(constant) == 0) or requires { C {constant...}; })
112  constexpr constant_matrix auto
113 #else
114  template<typename T, typename C, auto...constant, typename Ds, std::enable_if_t<
115  indexible<T> and values::scalar<C> and pattern_collection<Ds> and
116  ((values::fixed<C> and sizeof...(constant) == 0) or
117  std::is_constructible<C, decltype(constant)...>::value), int> = 0>
118  constexpr auto
119 #endif
120  make_constant(Ds&& ds)
121  {
122  using Scalar = values::number_type_of_t<C>;
123  if constexpr (sizeof...(constant) == 0)
124  return make_constant<T>(C{}, std::forward<Ds>(ds));
125  else
126  return make_constant<T>(values::Fixed<Scalar, constant...>{}, std::forward<Ds>(ds));
127  }
128 
129 
135 #ifdef __cpp_concepts
136  template<indexible T, auto constant, pattern_collection Ds> requires values::number<decltype(constant)>
137  constexpr constant_matrix auto
138 #else
139  template<typename T, auto constant, typename Ds, std::enable_if_t<
140  indexible<T> and values::number<decltype(constant)> and pattern_collection<Ds>, int> = 0>
141  constexpr auto
142 #endif
143  make_constant(Ds&& ds)
144  {
145  return make_constant<T, decltype(constant), constant>(std::forward<Ds>(ds));
146  }
147 
148 
158 #ifdef __cpp_concepts
159  template<indexible T, values::scalar C, auto...constant, coordinates::pattern...Ds> requires
160  ((values::fixed<C> and sizeof...(constant) == 0) or requires { C {constant...}; })
161  constexpr constant_matrix auto
162 #else
163  template<typename T, typename C, auto...constant, typename...Ds, std::enable_if_t<
164  indexible<T> and values::scalar<C> and (coordinates::pattern<Ds> and ...) and
165  ((values::fixed<C> and sizeof...(constant) == 0) or
166  std::is_constructible<C, decltype(constant)...>::value), int> = 0>
167  constexpr auto
168 #endif
169  make_constant(Ds&&...ds)
170  {
171  return make_constant<T, C, constant...>(std::forward_as_tuple(std::forward<Ds>(ds)...));
172  }
173 
174 
180 #ifdef __cpp_concepts
181  template<indexible T, auto constant, coordinates::pattern...Ds> requires values::number<decltype(constant)>
182  constexpr constant_matrix auto
183 #else
184  template<typename T, auto constant, typename...Ds, std::enable_if_t<
185  indexible<T> and values::number<decltype(constant)> and (coordinates::pattern<Ds> and ...), int> = 0>
186  constexpr auto
187 #endif
188  make_constant(Ds&&...ds)
189  {
190  return make_constant<T, decltype(constant), constant>(std::forward_as_tuple(std::forward<Ds>(ds)...));
191  }
192 
193 
198 #ifdef __cpp_concepts
199  template<values::scalar C, auto...constant, indexible T> requires
200  ((values::fixed<C> and sizeof...(constant) == 0) or requires { C {constant...}; })
201  constexpr constant_matrix auto
202 #else
203  template<typename C, auto...constant, typename T, std::enable_if_t<values::scalar<C> and indexible<T> and
204  ((values::fixed<C> and sizeof...(constant) == 0) or std::is_constructible<C, decltype(constant)...>::value), int> = 0>
205  constexpr auto
206 #endif
207  make_constant(const T& t)
208  {
209  return make_constant<T, C, constant...>(all_vector_space_descriptors(t));
210  }
211 
212 
217 #ifdef __cpp_concepts
218  template<auto constant, indexible T> requires values::number<decltype(constant)>
219  constexpr constant_matrix auto
220 #else
221  template<auto constant, typename T, std::enable_if_t<values::number<decltype(constant)> and indexible<T>, int> = 0>
222  constexpr auto
223 #endif
224  make_constant(const T& t)
225  {
226  return make_constant<decltype(constant), constant>(all_vector_space_descriptors(t));
227  }
228 
229 
230 } // namespace OpenKalman
231 
232 #endif //OPENKALMAN_MAKE_CONSTANT_HPP
constexpr bool constant_matrix
Specifies that all components of an object are the same constant value.
Definition: constant_matrix.hpp:31
auto make_vector_space_adapter(Arg &&arg, Descriptors &&descriptors)
If necessary, wrap an object in a wrapper that adds vector space descriptors for each index...
Definition: make_vector_space_adapter.hpp:37
constexpr bool indexible
T is a generalized tensor type.
Definition: indexible.hpp:32
constexpr bool value
T is numerical value or is reducible to a numerical value.
Definition: value.hpp:31
decltype(auto) constexpr all_vector_space_descriptors(const T &t)
Return a collection of coordinates::pattern objects associated with T.
Definition: all_vector_space_descriptors.hpp:52
The root namespace for OpenKalman.
Definition: basics.hpp:34
An interface to various routines from the linear algebra library associated with indexible object T...
Definition: library_interface.hpp:37
Definition: Fixed.hpp:36
A tensor or other matrix in which all elements are a constant scalar value.
Definition: ConstantAdapter.hpp:34
std::decay_t< decltype(values::to_number(std::declval< T >()))> number_type_of_t
Obtain the values::number type associated with avalues::value.
Definition: number_type_of_t.hpp:34
constexpr auto make_constant(C &&c, Descriptors &&descriptors)
Make a constant object based on a particular library object.
Definition: make_constant.hpp:37