OpenKalman
eigen-comma-initializers.hpp
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-2021 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 
17 #ifndef OPENKALMAN_EIGEN_COMMA_INITIALIZERS_HPP
18 #define OPENKALMAN_EIGEN_COMMA_INITIALIZERS_HPP
19 
20 namespace Eigen
21 {
25  template<typename Derived, typename XprType>
26  struct MeanCommaInitializer : CommaInitializer<XprType>
27  {
28  using Base = CommaInitializer<XprType>;
31  using Base::Base;
32 
33  template<typename S, std::enable_if_t<std::is_convertible_v<S, Scalar>, int> = 0>
34  MeanCommaInitializer(XprType& xpr, const S& s) : Base {xpr, static_cast<const Scalar&>(s)} {}
35 
36  template<typename OtherDerived>
37  MeanCommaInitializer(XprType& xpr, const DenseBase<OtherDerived>& other)
38  : Base {xpr, other} {}
39 
40  ~MeanCommaInitializer()
41  {
42  this->m_xpr = OpenKalman::wrap_angles<StaticDescriptor>(Base::finished());
43  }
44 
45  auto& finished()
46  {
47  this->m_xpr = OpenKalman::wrap_angles<StaticDescriptor>(Base::finished());
48  return this->m_xpr;
49  }
50  };
51 
52 
56  template<typename XprType>
58  {
60  static constexpr auto layout = OpenKalman::layout_of_v<XprType>;
61  static constexpr auto dim = OpenKalman::index_dimension_of_v<XprType, 0>;
63  Scalar, std::tuple<OpenKalman::Dimensions<dim>, OpenKalman::Axis>>;
64  using Nested = CommaInitializer<NestedMatrix>;
65 
66  NestedMatrix matrix;
67  Nested comma_initializer;
68  XprType& diag;
69 
70 #ifdef __cpp_concepts
71  template<std::convertible_to<Scalar> S>
72 #else
73  template<typename S, std::enable_if_t<std::is_convertible_v<S, Scalar>, int> = 0>
74 #endif
75  DiagonalCommaInitializer(XprType& xpr, const S& s)
76  : matrix {}, comma_initializer {matrix, static_cast<const Scalar&>(s)}, diag {xpr} {}
77 
78  template<typename OtherDerived>
79  DiagonalCommaInitializer(XprType& xpr, const DenseBase<OtherDerived>& other)
80  : matrix {}, comma_initializer {matrix, other}, diag {xpr} {}
81 
82  DiagonalCommaInitializer(const DiagonalCommaInitializer& o)
83  : matrix {o.matrix}, comma_initializer {o.comma_initializer}, diag {o.diag} {}
84 
85  DiagonalCommaInitializer(DiagonalCommaInitializer&& o)
86  : matrix {std::move(o.matrix)},
87  comma_initializer {std::move(o.comma_initializer)}, diag {std::move(o.diag)} {}
88 
89 #ifdef __cpp_concepts
90  template<std::convertible_to<Scalar> S>
91 #else
92  template<typename S, std::enable_if_t<std::is_convertible_v<S, Scalar>, int> = 0>
93 #endif
94  auto& operator,(const S& s)
95  {
96  comma_initializer, static_cast<const Scalar&>(s);
97  return *this;
98  }
99 
100  template<typename OtherDerived>
101  auto& operator,(const DenseBase<OtherDerived>& other)
102  {
103  comma_initializer, other;
104  return *this;
105  }
106 
107  ~DiagonalCommaInitializer()
108  {
109  diag = OpenKalman::DiagonalAdapter<NestedMatrix>(comma_initializer.finished());
110  }
111 
112  auto& finished()
113  {
114  diag = OpenKalman::DiagonalAdapter<NestedMatrix>(comma_initializer.finished());
115  return diag;
116  }
117  };
118 
119 
123  template<typename CovarianceType>
125  {
128  static constexpr auto layout = OpenKalman::layout_of_v<CovNest>;
129  using NestedMatrix = std::conditional_t<OpenKalman::diagonal_matrix<CovNest>,
132  using Nested = CommaInitializer<NestedMatrix>;
133 
134  NestedMatrix matrix;
135  Nested comma_initializer;
136  CovarianceType& cov;
137 
138  template<typename S, std::enable_if_t<std::is_convertible_v<S, Scalar>, int> = 0>
139  CovarianceCommaInitializer(CovarianceType& xpr, const S& s)
140  : matrix {}, comma_initializer {matrix, static_cast<const Scalar&>(s)}, cov {xpr} {}
141 
142  template<typename OtherDerived>
143  CovarianceCommaInitializer(CovarianceType& xpr, const DenseBase<OtherDerived>& other)
144  : matrix {}, comma_initializer {matrix, other}, cov {xpr} {}
145 
146  CovarianceCommaInitializer(const CovarianceCommaInitializer& o)
147  : matrix {o.matrix}, comma_initializer {o.comma_initializer}, cov {o.cov} {}
148 
149  CovarianceCommaInitializer(CovarianceCommaInitializer&& o)
150  : matrix {std::move(o.matrix)},
151  comma_initializer {std::move(o.comma_initializer)}, cov {std::move(o.cov)} {}
152 
153  template<typename S, std::enable_if_t<std::is_convertible_v<S, Scalar>, int> = 0>
154  auto& operator,(const S& s)
155  {
156  comma_initializer, static_cast<const Scalar&>(s);
157  return *this;
158  }
159 
160  template<typename OtherDerived>
161  auto& operator,(const DenseBase<OtherDerived>& other)
162  {
163  comma_initializer, other;
164  return *this;
165  }
166 
167  ~CovarianceCommaInitializer()
168  {
169  using namespace OpenKalman;
170 
171  if constexpr (diagonal_matrix<CovNest>)
172  {
173  cov = CovarianceType {std::move(comma_initializer).finished()};
174  }
175  else if constexpr (triangular_covariance<CovarianceType>)
176  {
177  using T = std::conditional_t<triangular_matrix<CovNest>, CovNest, decltype(cholesky_factor(std::declval<CovNest>()))>;
178  auto b = OpenKalman::internal::to_covariance_nestable<T>(std::move(comma_initializer).finished());
179  cov = OpenKalman::internal::to_covariance_nestable<CovNest>(std::move(b));
180  }
181  else
182  {
183  using SA = std::conditional_t<hermitian_matrix<CovNest>, CovNest, decltype(cholesky_square(std::declval<CovNest>()))>;
184  auto b = OpenKalman::internal::to_covariance_nestable<SA>(std::move(comma_initializer).finished());
185  cov = OpenKalman::internal::to_covariance_nestable<CovNest>(std::move(b));
186  }
187  }
188 
189  auto& finished()
190  {
191  using namespace OpenKalman;
192 
193  if constexpr (diagonal_matrix<CovNest>)
194  {
195  cov = CovarianceType {comma_initializer.finished()};
196  }
197  else if constexpr (triangular_covariance<CovarianceType>)
198  {
199  using T = std::conditional_t<triangular_matrix<CovNest>, CovNest, decltype(cholesky_factor(std::declval<CovNest>()))>;
200  auto b = OpenKalman::internal::to_covariance_nestable<T>(comma_initializer.finished());
201  cov = OpenKalman::internal::to_covariance_nestable<CovNest>(std::move(b));
202  }
203  else
204  {
205  using SA = std::conditional_t<hermitian_matrix<CovNest>, CovNest, decltype(cholesky_square(std::declval<CovNest>()))>;
206  auto b = OpenKalman::internal::to_covariance_nestable<SA>(comma_initializer.finished());
207  cov = OpenKalman::internal::to_covariance_nestable<CovNest>(std::move(b));
208  }
209  return cov;
210  }
211  };
212 
213 } // namespace Eigen
214 
215 
216 #endif //OPENKALMAN_EIGEN_COMMA_INITIALIZERS_HPP
typename nested_object_of< T >::type nested_object_of_t
Helper type for nested_object_of.
Definition: nested_object_of.hpp:66
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
Alternative version of Eigen::CommaInitializer for Mean.
Definition: eigen-comma-initializers.hpp:26
decltype(auto) constexpr cholesky_square(A &&a)
Take the Cholesky square of a triangular_matrix.
Definition: cholesky_square.hpp:33
The root namespace for OpenKalman.
Definition: basics.hpp:34
typename vector_space_descriptor_of< T, N >::type vector_space_descriptor_of_t
helper template for vector_space_descriptor_of.
Definition: vector_space_descriptor_of.hpp:56
std::decay_t< decltype(make_dense_object< T, layout, S >(std::declval< D >()))> dense_writable_matrix_t
An alias for a dense, writable matrix, patterned on parameter T.
Definition: dense_writable_matrix_t.hpp:38
Version of Eigen::CommaInitializer for diagonal versions of HermitianAdapter and TriangularAdapter.
Definition: eigen-comma-initializers.hpp:57
Alternative version of Eigen::CommaInitializer for Covariance and SquareRootCovariance.
Definition: eigen-comma-initializers.hpp:124
An adapter for creating a diagonal matrix or tensor.
Definition: DiagonalAdapter.hpp:27
decltype(auto) constexpr cholesky_factor(A &&a)
Take the Cholesky factor of a matrix.
Definition: cholesky_factor.hpp:38