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 indexible_object_traits<Eigen::Diagonal<MatrixType, DiagIndex>>
26  : Eigen3::indexible_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_coefficient{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 
64  return values::Fixed<Scalar, 0>{};
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_coefficient{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_coefficient{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 } // namespace OpenKalman::interface
93 
94 #endif //OPENKALMAN_EIGEN_TRAITS_DIAGONAL_HPP
constexpr bool one_dimensional
Specifies that a type is one-dimensional in every index.
Definition: one_dimensional.hpp:83
Definition: indexible_object_traits.hpp:36
Definition: basics.hpp:41
Trait object providing get and set routines.
Definition: eigen-forward-declarations.hpp:502
typename scalar_type_of< T >::type scalar_type_of_t
helper template for scalar_type_of.
Definition: scalar_type_of.hpp:54
Definition: eigen-comma-initializers.hpp:20
The constant associated with T, assuming T is a constant_matrix.
Definition: constant_coefficient.hpp:36
The constant associated with T, assuming T is a constant_diagonal_matrix.
Definition: constant_diagonal_coefficient.hpp:32
Definition: Fixed.hpp:36
decltype(auto) constexpr nested_object(Arg &&arg)
Retrieve a nested object of Arg, if it exists.
Definition: nested_object.hpp:34