OpenKalman
TransformationTraits.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) 2020-2021 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_TRANSFORMATIONTRAITS_HPP
17 #define OPENKALMAN_TRANSFORMATIONTRAITS_HPP
18 
19 #include <type_traits>
20 
21 namespace OpenKalman
22 {
23  namespace oin = OpenKalman::internal;
24 
25 
26  namespace internal
27  {
34 #ifdef __cpp_concepts
35  template<typename T, std::size_t order = 1>
36 #else
37  template<typename T, std::size_t order = 1, typename = void>
38 #endif
39  struct is_linearized_function : std::false_type {};
40  }
41 
42 
49  template<typename T, std::size_t order = 1>
50 #ifdef __cpp_concepts
51  concept linearized_function =
52 #else
53  constexpr bool linearized_function =
54 #endif
56 
57 
58  namespace internal
59  {
60 
61 #ifdef __cpp_concepts
62  template<typename T> requires
63  (std::is_member_function_pointer_v<decltype(&T::operator())> or std::is_function_v<T>)
64  struct is_linearized_function<T, 0> : std::true_type {};
65 #else
66  template<typename T>
67  struct is_linearized_function<T, 0, std::enable_if_t<
68  (std::is_member_function_pointer_v<decltype(&T::operator())> or std::is_function_v<T>)>> : std::true_type {};
69 #endif
70 
71 
72 #ifdef __cpp_concepts
73  template<typename T> requires
74  (std::is_member_function_pointer_v<decltype(&T::jacobian)> and linearized_function<T, 0>)
75  struct is_linearized_function<T, 1> : std::true_type {};
76 #else
77  template<typename T>
78  struct is_linearized_function<T, 1, std::enable_if_t<
79  (std::is_member_function_pointer_v<decltype(&T::jacobian)> and linearized_function<T, 0>)>> : std::true_type {};
80 #endif
81 
82 
83 #ifdef __cpp_concepts
84  template<typename T> requires
85  (std::is_member_function_pointer_v<decltype(&T::hessian)> and linearized_function<T, 1>)
86  struct is_linearized_function<T, 2> : std::true_type {};
87 #else
88  template<typename T>
89  struct is_linearized_function<T, 2, std::enable_if_t<
90  (std::is_member_function_pointer_v<decltype(&T::hessian)> and linearized_function<T, 1>)>> : std::true_type {};
91 #endif
92 
93 
98 #ifdef __cpp_concepts
99  template<std::size_t order = 1, typename T> requires (order > 0) and (order <= 2)
100 #else
101  template<std::size_t order = 1, typename T, std::enable_if_t<(order > 0) and (order <= 2), int> = 0>
102 #endif
103  static constexpr auto get_Taylor_term(const T& t)
104  {
105  if constexpr (order == 1)
106  {
107  return [&t](auto&& ...inputs) { return t.jacobian(std::forward<decltype(inputs)>(inputs)...); };
108  }
109  else if constexpr (order == 2)
110  {
111  return [&t](auto&& ...inputs) { return t.hessian(std::forward<decltype(inputs)>(inputs)...); };
112  }
113  }
114 
115 
116  } // namespace internal
117 
118 
119  namespace internal
120  {
125 #ifdef __cpp_concepts
126  template<typename T>
127  struct PerturbationTraits;
128 
129  template<typename T> requires gaussian_distribution<T>
130  struct PerturbationTraits<T> : MatrixTraits<typename DistributionTraits<T>::Mean> {};
131 
132  template<typed_matrix T>
133  struct PerturbationTraits<T> : MatrixTraits<std::decay_t<T>> {};
134 #else
135  template<typename T, typename = void>
137 
138  template<typename T>
139  struct PerturbationTraits<T, std::enable_if_t<gaussian_distribution<T>>>
140  : MatrixTraits<typename DistributionTraits<T>::Mean> {};
141 
142  template<typename T>
143  struct PerturbationTraits<T, std::enable_if_t<typed_matrix<T>>>
144  : MatrixTraits<std::decay_t<T>> {};
145 #endif
146 
147  } // namespace internal
148 
149 
154  template<typename T, typename Coeffs = typename oin::PerturbationTraits<T>::RowCoefficients>
155 #ifdef __cpp_concepts
156  concept transformation_input =
157 #else
158  constexpr bool transformation_input =
159 #endif
160  typed_matrix<T> and vector<T> and has_untyped_index<T, 1> and (not euclidean_transformed<T>) and
161  coordinates::compares_with<typename oin::PerturbationTraits<T>::RowCoefficients, Coeffs>;
162 
163 
168 #ifdef __cpp_concepts
169  template<typename T, typename Coeffs = typename oin::PerturbationTraits<T>::RowCoefficients>
170  concept perturbation = (gaussian_distribution<T> and
171  compares_with<typename oin::PerturbationTraits<T>::RowCoefficients, Coeffs>) or transformation_input<T, Coeffs>;
172 #else
173  namespace detail
174  {
175  template<typename T, typename Coeffs, typename = void>
176  struct is_perturbation : std::false_type {};
177 
178  template<typename T, typename Coeffs>
179  struct is_perturbation<T, Coeffs, std::enable_if_t<gaussian_distribution<T> and
180  compares_with<typename oin::PerturbationTraits<T>::RowCoefficients, Coeffs>>>: std::true_type {};
181 
182  template<typename T, typename Coeffs>
183  struct is_perturbation<T, Coeffs, std::enable_if_t<
184  (not gaussian_distribution<T>) and transformation_input<T, Coeffs>>> : std::true_type {};
185  }
186 
187  template<typename T, typename Coeffs = typename oin::PerturbationTraits<T>::RowCoefficients>
188  constexpr bool perturbation = OpenKalman::detail::is_perturbation<T, Coeffs>::value;
189 #endif
190 
191 
192  namespace internal
193  {
198 #ifdef __cpp_concepts
199  template<perturbation Arg>
200 #else
201  template<typename Arg, std::enable_if_t<perturbation<Arg>, int> = 0>
202 #endif
203  inline auto
204  get_perturbation(Arg&& arg)
205  {
206  if constexpr(gaussian_distribution<Arg>)
207  return std::forward<Arg>(arg)();
208  else
209  return std::forward<Arg>(arg);
210  }
211  }
212 
213 
214  namespace detail
215  {
216  template<typename OutputCoefficients, typename In>
217  inline auto zero_hessian_impl()
218  {
219  using InputCoefficients = vector_space_descriptor_of_t<In, 0>;
221  std::tuple<coordinates::dimension_of<InputCoefficients>, coordinates::dimension_of<InputCoefficients>>>;
223  using HessianArrayIn = std::array<HessianMatrixIn, coordinates::dimension_of_v<OutputCoefficients>>;
224 
225  HessianArrayIn a;
226  a.fill(make_zero(a));
227  return a;
228  }
229  }
230 
231 
233  template<typename OutputCoefficients, typename In, typename ... Perturbations>
234  inline auto zero_hessian()
235  {
236  static_assert(typed_matrix<In> and has_untyped_index<In, 1>);
237  static_assert((perturbation<Perturbations> and ...));
238  return std::tuple {OpenKalman::detail::zero_hessian_impl<OutputCoefficients, In>(),
239  OpenKalman::detail::zero_hessian_impl<OutputCoefficients, Perturbations>()...};
240  }
241 
242 
244  template<typename OutputCoefficients, typename In, typename ... Perturbations>
245  inline auto zero_hessian(In&&, Perturbations&&...)
246  {
247  return zero_hessian<OutputCoefficients, In, Perturbations...>();
248  }
249 
250 }
251 
252 
253 #endif //OPENKALMAN_TRANSFORMATIONTRAITS_HPP
auto zero_hessian()
A tuple of zero-filled arrays of Hessian matrices, based on the input and each perturbation term...
Definition: TransformationTraits.hpp:234
Definition: tuple_reverse.hpp:103
Definition: TransformationTraits.hpp:136
constexpr bool value
T is numerical value or is reducible to a numerical value.
Definition: value.hpp:31
constexpr bool transformation_input
T is an acceptable input to a tests.
Definition: TransformationTraits.hpp:158
The size of a coordinates::pattern.
Definition: dimension_of.hpp:37
The root namespace for OpenKalman.
Definition: basics.hpp:34
typename vector_space_descriptor_of< T, N >::type vector_space_descriptor_of_t
helper template for vector_space_descriptor_of.
Definition: vector_space_descriptor_of.hpp:56
std::decay_t< decltype(make_dense_object< T, layout, S >(std::declval< D >()))> dense_writable_matrix_t
An alias for a dense, writable matrix, patterned on parameter T.
Definition: dense_writable_matrix_t.hpp:38
Definition: TransformationTraits.hpp:176
constexpr auto make_zero(Descriptors &&descriptors)
Make a zero associated with a particular library.
Definition: make_zero.hpp:36
constexpr bool linearized_function
A linearized function (with defined Jacobian and optionally Hessian functions).
Definition: TransformationTraits.hpp:53
Definition: TransformationTraits.hpp:39
Definition: basics.hpp:48
A matrix with typed rows and columns.
Definition: forward-class-declarations.hpp:448