OpenKalman
PartialReduxExpr.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_PARTIALREDUXEXPR_HPP
17 #define OPENKALMAN_EIGEN_PARTIALREDUXEXPR_HPP
18 
19 #include <type_traits>
20 #include "basics/basics.hpp"
21 
23 {
24 #ifdef __cpp_concepts
25  template<typename Dim, typename OtherDim>
26  concept at_least_square = (std::decay_t<Dim>::value >= std::decay_t<OtherDim>::value);
27 #else
28  template<typename Dim, typename OtherDim, typename = void>
29  struct at_least_square_impl : std::false_type {};
30 
31  template<typename Dim, typename OtherDim>
32  struct at_least_square_impl<Dim, OtherDim, std::enable_if_t<
33  values::fixed<Dim> and values::fixed<OtherDim>>>
34  : std::bool_constant<std::decay_t<Dim>::value >= std::decay_t<OtherDim>::value> {};
35 
36  template<typename Dim, typename OtherDim>
37  constexpr bool at_least_square = at_least_square_impl<Dim, OtherDim>::value;
38 #endif
39 
40 
41  template<typename MemberOp, std::size_t direction, typename XprType, typename Factor, typename DirDim, typename Func>
42  constexpr auto get_constant_redux(const XprType& xpr, const Factor& factor, const DirDim& dir_dim, Func&& func)
43  {
44  auto dim = internal::most_fixed_pattern(dir_dim, get_index_dimension_of<direction>(xpr));
45 
46  if constexpr (Eigen3::eigen_MatrixWrapper<XprType> or Eigen3::eigen_ArrayWrapper<XprType> or
47  internal::fixed_size_adapter<XprType> or Eigen3::eigen_wrapper<XprType>)
48  {
49  return get_constant_redux<MemberOp, direction>(nested_object(xpr), factor, dim, std::forward<Func>(func));
50  }
51  else if constexpr (Eigen3::eigen_CwiseUnaryOp<XprType> or Eigen3::eigen_CwiseUnaryView<XprType>)
52  {
53  auto new_func = Eigen3::functor_composition {std::forward<Func>(func), xpr.functor()};
54  return get_constant_redux<MemberOp, direction>(xpr.nestedExpression(), factor, dim, std::move(new_func));
55  }
56  else if constexpr (Eigen3::eigen_Replicate<XprType>)
57  {
59  const auto& n_xpr = xpr.nestedExpression();
60  auto n_dim = get_index_dimension_of<direction>(n_xpr);
61 
62  auto f = [](const auto& dim, const auto& n_dim) {
63  if constexpr (F::value != stdex::dynamic_extent) return F{};
64  else return values::operation(std::divides<std::size_t>{}, dim, n_dim);
65  }(dim, n_dim);
66 
67  auto new_dim = [](const auto& dim, const auto& n_dim) {
68  if constexpr (values::fixed<decltype(dim)> and F::value != stdex::dynamic_extent and
69  not values::fixed<decltype(n_dim)>)
70  return values::operation(std::divides<std::size_t>{}, dim, F{});
71  else
72  return n_dim;
73  }(dim, n_dim);
74 
75  auto new_f = values::operation(std::multiplies<std::size_t>{}, factor, f);
76  return get_constant_redux<MemberOp, direction>(n_xpr, new_f, new_dim, std::forward<Func>(func));
77  }
78  else
79  {
80  if constexpr (constant_matrix<XprType>)
81  {
82  auto c = values::operation(std::forward<Func>(func), constant_value {xpr});
84  }
85  else if constexpr (constant_diagonal_matrix<XprType>)
86  {
87  constexpr bool als = at_least_square<decltype(dim), decltype(get_index_dimension_of<direction == 1 ? 0 : 1>(xpr))>;
88  auto c = values::operation(std::forward<Func>(func), constant_diagonal_value {xpr});
89  return Eigen3::ReduxTraits<MemberOp, direction>::template get_constant_diagonal<als>(c, factor, dim);
90  }
91  else
92  {
93  return std::monostate {};
94  }
95  }
96  }
97 
98 }
99 
100 
101 namespace OpenKalman::interface
102 {
103 
104  // ------------------------- //
105  // object_traits //
106  // ------------------------- //
107 
108  template<typename MatrixType, typename MemberOp, int Direction>
109  struct object_traits<Eigen::PartialReduxExpr<MatrixType, MemberOp, Direction>>
110  : Eigen3::object_traits_base<Eigen::PartialReduxExpr<MatrixType, MemberOp, Direction>>
111  {
112  private:
113 
115 
116  public:
117 
118  template<typename Arg>
119  static decltype(auto) nested_object(Arg&& arg)
120  {
121  return std::forward<Arg>(arg).nestedExpression();
122  }
123 
124 
125  // If a partial redux expression needs to be partially evaluated, it's probably faster to do a full evaluation.
126  // Thus, we omit the conversion function.
127 
128  template<typename Arg>
129  static constexpr auto get_constant(const Arg& arg)
130  {
131  // colwise (acting on columns) is Eigen::Vertical and rowwise (acting on rows) is Eigen::Horizontal
132  constexpr std::size_t direction = Direction == Eigen::Horizontal ? 1 : 0;
133  const auto& x = arg.nestedExpression();
134  auto dim = get_index_dimension_of<direction>(x);
135  std::integral_constant<std::size_t, 1> f;
136  return OpenKalman::Eigen3::detail::get_constant_redux<MemberOp, direction>(x, f, dim, stdex::identity{});
137  }
138 
139  };
140 
141 }
142 
143 #endif
Definition: language-features.hpp:228
Definition: basics.hpp:41
Definition: eigen-comma-initializers.hpp:20
constexpr bool value
T is a fixed or dynamic value that is reducible to a number.
Definition: value.hpp:45
Definition: eigen-forward-declarations.hpp:97
Definition: object_traits.hpp:38
Trait object providing get and set routines.
Definition: eigen-forward-declarations.hpp:502
Definition: redux.hpp:26
Definition: PartialReduxExpr.hpp:29
constexpr auto constant_value(T &&t)
The constant value associated with a constant_object or constant_diagonal_object. ...
Definition: constant_value.hpp:37
The replication factor for Eigen::Replicate in a given direction.
Definition: eigen-forward-declarations.hpp:310
constexpr bool fixed
T is a value that is determinable at compile time.
Definition: fixed.hpp:66
Compose two Eigen functors F1 and F2.
Definition: functor_composition.hpp:29
Basic definitions for OpenKalman as a whole.
decltype(auto) constexpr nested_object(Arg &&arg)
Retrieve a nested object of Arg, if it exists.
Definition: nested_object.hpp:35
constexpr auto operation(Operation &&op, Args &&...args)
A potentially constant-evaluated operation involving some number of values.
Definition: operation.hpp:98