OpenKalman
functor_composition.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) 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_EIGEN_FUNCTOR_COMPOSITION_HPP
17 #define OPENKALMAN_EIGEN_FUNCTOR_COMPOSITION_HPP
18 
19 #include <type_traits>
20 
21 namespace OpenKalman::Eigen3
22 {
28  template<typename F1, typename F2>
30  {
31  private:
32 
33 #ifdef __cpp_concepts
34  template<typename T>
35 #else
36  template<typename T, typename = void>
37 #endif
38  struct maybe_constexpr { using type = T; };
39 
40 
41 #ifdef __cpp_concepts
42  template<constexpr_unary_operation_defined T>
43  struct maybe_constexpr<T>
44 #else
45  template<typename T>
46  struct maybe_constexpr<T, std::enable_if_t<constexpr_unary_operation_defined<T>>>
47 #endif
48  {
49  using type = decltype(UnaryFunctorTraits<std::decay_t<T>>::constexpr_operation());
50  };
51 
52 
53  using CF1 = typename maybe_constexpr<F1>::type;
54  using CF2 = typename maybe_constexpr<F2>::type;
55 
56  public:
57 
58 #ifdef __cpp_concepts
59  constexpr functor_composition() requires std::default_initializable<CF1> and std::default_initializable<CF2> = default;
60 #else
61  template<typename X = CF1, std::enable_if_t<std::is_default_constructible_v<X> and std::is_default_constructible_v<CF2>, int> = 0>
62  constexpr functor_composition() {};
63 #endif
64 
65  private:
66 
67  template<typename Arg>
68  static constexpr decltype(auto)
69  get_constexpr_op(Arg&& arg)
70  {
71  if constexpr (constexpr_unary_operation_defined<Arg>) return UnaryFunctorTraits<std::decay_t<Arg>>::constexpr_operation();
72  else return std::forward<Arg>(arg);
73  }
74 
75  public:
76 
77  template<typename MF1, typename MF2>
78  constexpr functor_composition(MF1&& f1, MF2&& f2)
79  : m_functor1 {get_constexpr_op(std::forward<MF1>(f1))}, m_functor2{get_constexpr_op(std::forward<MF2>(f2))} {}
80 
81 
82  template<typename Scalar>
83  constexpr auto operator()(const Scalar& a) const { return m_functor1(m_functor2(a)); }
84 
85 
86  template<typename Packet>
87  constexpr auto packetOp(const Packet& a) const { return m_functor1.packetOp(m_functor2.packetOp(a)); }
88 
89 
90  constexpr decltype(auto) functor1() const & { return m_functor1; }
91  constexpr decltype(auto) functor1() const && { return std::forward<CF1>(m_functor1); }
92 
93  constexpr decltype(auto) functor2() const & { return m_functor2; }
94  constexpr decltype(auto) functor2() const && { return std::forward<CF2>(m_functor2); }
95 
96  private:
97 
98  CF1 m_functor1;
99  CF2 m_functor2;
100 
101  };
102 
103 
107  template<typename F1, typename F2>
109 
110 
111  // UnaryFunctorTraits for functor_composition
112  template<typename F1, typename F2>
114  {
115  private:
116 
119 
120  public:
121 
122  static constexpr bool preserves_triangle = UnaryFunctorTraits1::preserves_triangle and UnaryFunctorTraits2::preserves_triangle;
123  static constexpr bool preserves_hermitian = UnaryFunctorTraits1::preserves_hermitian and UnaryFunctorTraits2::preserves_hermitian;
124 
125  template<typename UnaryOp, typename XprType>
126  static constexpr auto get_constant(const Eigen::CwiseUnaryOp<UnaryOp, XprType>& arg)
127  {
130  else
131  return values::operation {arg.functor(), constant_coefficient {arg.nestedExpression()}};
132  }
133 
134  template<typename Arg>
135  static constexpr auto get_constant_diagonal(const Arg& arg)
136  {
137  return values::operation {arg.functor(), constant_diagonal_coefficient {arg.nestedExpression()}};
138  }
139 
140  };
141 
142 } // namespace OpenKalman::Eigen3
143 
144 
145 namespace Eigen::internal
146 {
147  template<typename F1, typename F2>
148  struct functor_traits<OpenKalman::Eigen3::functor_composition<F1, F2>>
149  {
150  enum
151  {
152  Cost = int{functor_traits<std::decay_t<F1>>::Cost} + int{functor_traits<std::decay_t<F2>>::Cost},
153  PacketAccess = functor_traits<std::decay_t<F1>>::PacketAccess and functor_traits<std::decay_t<F2>>::PacketAccess,
154  };
155  };
156 
157 } // namespace Eigen::internal
158 
159 
160 #endif //OPENKALMAN_EIGEN_FUNCTOR_COMPOSITION_HPP
An operation involving some number of values.
Definition: operation.hpp:69
Definition: eigen-forward-declarations.hpp:41
The constant associated with T, assuming T is a constant_matrix.
Definition: constant_coefficient.hpp:36
The root namespace for OpenKalman.
Definition: basics.hpp:34
The constant associated with T, assuming T is a constant_diagonal_matrix.
Definition: constant_diagonal_coefficient.hpp:32
Definition: eigen-forward-declarations.hpp:22
constexpr bool fixed
T is a values::value that is determinable at compile time.
Definition: fixed.hpp:60
Compose two Eigen functors F1 and F2.
Definition: functor_composition.hpp:29
Definition: ConstantAdapter.hpp:21