OpenKalman
constant_coefficient.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) 2019-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_CONSTANT_COEFFICIENT_HPP
17 #define OPENKALMAN_CONSTANT_COEFFICIENT_HPP
18 
19 #include <type_traits>
20 #include "values/values.hpp"
24 
26 {
31 #ifdef __cpp_concepts
32  template<indexible T>
33 #else
34  template<typename T, typename = void>
35 #endif
37  {
38  explicit constexpr constant_coefficient(const std::decay_t<T>&) {};
39  };
40 
41 
45  template<typename T>
46  explicit constant_coefficient(const T&) -> constant_coefficient<T>;
47 
48 
52 #ifdef __cpp_concepts
53  template<indexible T>
54 #else
55  template<typename T>
56 #endif
58 
59 
60 
61  namespace detail
62  {
63  template<typename T>
64  constexpr auto const_diag_value =
65  std::decay_t<decltype(interface::indexible_object_traits<std::decay_t<T>>::get_constant_diagonal(std::declval<T>()))>::value;
66 
67 
68 #ifdef __cpp_concepts
69  template<typename T>
70  concept has_static_constant =
71  values::fixed<typename interface::get_constant_return_type<T>::type> or
72  (values::fixed<typename interface::get_constant_diagonal_return_type<T>::type> and
73  (one_dimensional<T> or values::internal::near(const_diag_value<T>, 0)));
74 #else
75  template<typename T, typename = void>
76  struct has_static_constant_impl : std::false_type {};
77 
78  template<typename T>
79  struct has_static_constant_impl<T, std::enable_if_t<values::fixed<typename interface::get_constant_diagonal_return_type<T>::type>>>
80  : std::bool_constant<one_dimensional<T> or values::internal::near(const_diag_value<T>, 0)> {};
81 
82  template<typename T>
83  constexpr bool has_static_constant = values::fixed<typename interface::get_constant_return_type<T>::type> or
85 #endif
86  } // namespace detail
87 
88 
93 #ifdef __cpp_concepts
94  template<indexible T> requires detail::has_static_constant<T>
95  struct constant_coefficient<T>
96 #else
97  template<typename T>
98  struct constant_coefficient<T, std::enable_if_t<indexible<T> and detail::has_static_constant<T>>>
99 #endif
100  {
101  private:
102 
104 
105  public:
106 
107  constexpr constant_coefficient() = default;
108 
109  explicit constexpr constant_coefficient(const std::decay_t<T>&) {};
110 
111  using value_type = scalar_type_of_t<T>;
112 
113  using type = constant_coefficient;
114 
115  static constexpr value_type value = []{
116  if constexpr (values::fixed<typename interface::get_constant_return_type<T>::type>)
117  return std::decay_t<decltype(Trait::get_constant(std::declval<T>()))>::value;
118  else
119  return std::decay_t<decltype(Trait::get_constant_diagonal(std::declval<T>()))>::value;
120  }();
121 
122  constexpr operator value_type() const { return value; }
123 
124  constexpr value_type operator()() const { return value; }
125 
126  };
127 
128 
133 #ifdef __cpp_concepts
134  template<indexible T> requires (not detail::has_static_constant<T>) and
135  (values::dynamic<typename interface::get_constant_return_type<T>::type> or one_dimensional<T>)
136  struct constant_coefficient<T>
137 #else
138  template<typename T>
139  struct constant_coefficient<T, std::enable_if_t<
140  (values::dynamic<typename interface::get_constant_return_type<T>::type> or one_dimensional<T>) and
141  (not detail::has_static_constant<T>)>>
142 #endif
143  {
144  private:
145 
147 
148  public:
149 
150  explicit constexpr constant_coefficient(const std::decay_t<T>& t) : m_value {[](const auto& t){
151  if constexpr (values::dynamic<typename interface::get_constant_return_type<T>::type>)
152  return values::to_number(Trait::get_constant(t));
153  else if constexpr (values::dynamic<typename interface::get_constant_diagonal_return_type<T>::type>)
154  return values::to_number(Trait::get_constant_diagonal(t));
155  else
156  return internal::get_singular_component(t);
157  }(t)} {};
158 
159  using value_type = scalar_type_of_t<T>;
160 
161  using type = constant_coefficient;
162 
163  constexpr operator value_type() const { return m_value; }
164 
165  constexpr value_type operator()() const { return m_value; }
166 
167  private:
168 
169  value_type m_value;
170  };
171 
172 
173 } // namespace OpenKalman::values
174 
175 
176 namespace OpenKalman
177 {
180 }
181 
182 #endif //OPENKALMAN_CONSTANT_COEFFICIENT_HPP
Definition: indexible_object_traits.hpp:36
Header file for code relating to values (e.g., scalars and indices)
typename scalar_type_of< T >::type scalar_type_of_t
helper template for scalar_type_of.
Definition: scalar_type_of.hpp:54
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 to_number(Arg arg)
Convert any values::value to a values::number.
Definition: to_number.hpp:34
The constant associated with T, assuming T is a constant_matrix.
Definition: constant_coefficient.hpp:36
Concepts for testing whether indexible_object_traits are defined for a particular object...
The root namespace for OpenKalman.
Definition: basics.hpp:34
Definition for values::abs.
Definition: constant_coefficient.hpp:25
constexpr auto constant_coefficient_v
Helper template for constant_coefficient.
Definition: constant_coefficient.hpp:57
constexpr bool dynamic
T is a values::value that is not determinable at compile time.
Definition: dynamic.hpp:48
constexpr bool near(const Arg1 &arg1, const Arg2 &arg2)
Determine whether two numbers are within a rounding tolerance.
Definition: near.hpp:36
Definition: constant_coefficient.hpp:76
Definition for indexible.
constexpr bool fixed
T is a values::value that is determinable at compile time.
Definition: fixed.hpp:60
constant_coefficient(const T &) -> constant_coefficient< T >
Deduction guide for constant_coefficient.
Definition for one_dimensional.