OpenKalman
Diagonal.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-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_TRAITS_DIAGONAL_HPP
17 #define OPENKALMAN_EIGEN_TRAITS_DIAGONAL_HPP
18 
19 #include <type_traits>
20 
21 
22 namespace OpenKalman::interface
23 {
24  template<typename MatrixType, int DiagIndex>
25  struct object_traits<Eigen::Diagonal<MatrixType, DiagIndex>>
26  : Eigen3::object_traits_base<Eigen::Diagonal<MatrixType, DiagIndex>>
27  {
28  private:
29 
30  using Xpr = Eigen::Diagonal<MatrixType, DiagIndex>;
32 
33  public:
34 
35  template<typename Arg>
36  static decltype(auto) nested_object(Arg&& arg)
37  {
38  return std::forward<Arg>(arg).nestedExpression();
39  }
40 
41 
42  template<typename Arg>
43  static constexpr auto get_constant(const Arg& arg)
44  {
45  using Scalar = scalar_type_of_t<MatrixType>;
46 
47  if constexpr (constant_diagonal_matrix<MatrixType> and DiagIndex == 0)
48  {
49  return constant_diagonal_value{arg.nestedExpression()};
50  }
51  else if constexpr (zero<MatrixType> or (constant_diagonal_matrix<MatrixType> and DiagIndex != Eigen::DynamicIndex and
52  ((DiagIndex < 0 and (dynamic_dimension<MatrixType, 0> or DiagIndex > -int(index_dimension_of_v<MatrixType, 0>))) or
53  (DiagIndex > 0 and (dynamic_dimension<MatrixType, 1> or DiagIndex < int(index_dimension_of_v<MatrixType, 1>))))))
54  {
55  if constexpr (DiagIndex < 0 and dynamic_dimension<MatrixType, 0>)
56  {
57  if (DiagIndex <= -arg.nestedExpression().rows()) throw std::out_of_range{"DiagIndex in Eigen::Diagonal is too low for MatrixType."};
58  }
59  else if constexpr (DiagIndex > 0 and dynamic_dimension<MatrixType, 1>)
60  {
61  if (DiagIndex >= arg.nestedExpression().cols()) throw std::out_of_range{"DiagIndex in Eigen::Diagonal is too high for MatrixType."};
62  }
63 
65  }
66  else if constexpr (constant_diagonal_matrix<MatrixType> and DiagIndex == Eigen::DynamicIndex)
67  {
68  if (arg.index() == 0) return static_cast<Scalar>(constant_diagonal_value{arg.nestedExpression()});
69  else if (arg.index() > -arg.nestedExpression().rows() and arg.index() < arg.nestedExpression().cols()) return Scalar(0);
70  else throw std::out_of_range {"Dynamic index for Eigen::Diagonal is out of range."};
71  }
72  else if constexpr (constant_matrix<MatrixType>>)
73  {
74  return constant_value{arg.nestedExpression()};
75  }
76  else
77  {
78  return std::monostate{};
79  }
80  }
81 
82 
83  template<applicability b>
84  static constexpr bool one_dimensional = dimension_size_of_index_is<Xpr, 0, 1, b>;
85 
86 
87  template<applicability b>
88  static constexpr bool is_square = one_dimensional<b>;
89 
90  };
91 
92 }
93 
94 #endif
constexpr bool one_dimensional
Specifies that a type is one-dimensional in every index.
Definition: one_dimensional.hpp:56
Definition: basics.hpp:41
Definition: fixed_value.hpp:41
Definition: eigen-comma-initializers.hpp:20
Definition: object_traits.hpp:38
Trait object providing get and set routines.
Definition: eigen-forward-declarations.hpp:502
constexpr auto constant_value(T &&t)
The constant value associated with a constant_object or constant_diagonal_object. ...
Definition: constant_value.hpp:37
decltype(auto) constexpr nested_object(Arg &&arg)
Retrieve a nested object of Arg, if it exists.
Definition: nested_object.hpp:35