17 #ifndef OPENKALMAN_COVARIANCEIMPL_HPP 18 #define OPENKALMAN_COVARIANCEIMPL_HPP 35 template<
typename Derived,
typename NestedMatrix>
37 template<
typename Derived,
typename NestedMatrix>
42 #ifndef __cpp_concepts 43 static_assert(covariance<Derived>);
44 static_assert(covariance_nestable<NestedMatrix>);
54 using typename Base::CholeskyNestedMatrix;
56 using Base::cholesky_nested_matrix;
57 using Base::synchronization_direction;
58 using Base::synchronize_forward;
59 using Base::synchronize_reverse;
60 using Base::mark_nested_matrix_changed;
61 using Base::mark_cholesky_nested_matrix_changed;
62 using Base::mark_synchronized;
69 using Base::operator=;
79 template<std::invocable<NestedMatrix&> F1, std::invocable<CholeskyNestedMatrix&> F2>
81 template<
typename F1,
typename F2, std::enable_if_t<
82 std::is_invocable_v<F1, NestedMatrix&> and std::is_invocable_v<F2, CholeskyNestedMatrix&>,
int> = 0>
84 auto covariance_op(
const F1& f1,
const F2& f2)
const &
86 using Derived2 = decltype(to_dense_object<Derived>(f1(
nested_object())));
87 using R = equivalent_self_contained_t<Derived2>;
88 if (synchronization_direction() >= 0)
91 if constexpr (not case1or2<Derived, decltype(f1(
nested_object()))>)
93 if (r.synchronization_direction() > 0 and synchronization_direction() <= 0)
95 r.cholesky_nested_matrix() =
96 to_covariance_nestable<decltype(r.cholesky_nested_matrix())>(f2(cholesky_nested_matrix()));
97 r.mark_synchronized();
104 return R {f2(cholesky_nested_matrix())};
110 #ifdef __cpp_concepts 111 template<std::invocable<NestedMatrix&> F1, std::invocable<CholeskyNestedMatrix&> F2>
113 template<
typename F1,
typename F2, std::enable_if_t<
114 std::is_invocable_v<F1, NestedMatrix&> and std::is_invocable_v<F2, CholeskyNestedMatrix&>,
int> = 0>
118 using Derived2 = decltype(to_dense_object<Derived>(f1(std::move(*this).nested_object())));
119 using R = equivalent_self_contained_t<Derived2>;
120 if (synchronization_direction() >= 0)
122 R r {f1(std::move(*this).nested_object())};
123 if constexpr (not case1or2<Derived, decltype(f1(std::move(*this).nested_object()))>)
125 if (r.synchronization_direction() > 0 and synchronization_direction() <= 0)
127 r.cholesky_nested_matrix() =
128 to_covariance_nestable<decltype(r.cholesky_nested_matrix())>(f2(std::move(*this).cholesky_nested_matrix()));
129 r.mark_synchronized();
136 return R {f2(std::move(*this).cholesky_nested_matrix())};
142 #ifdef __cpp_concepts 143 template<std::invocable<NestedMatrix&> F> requires std::invocable<F, CholeskyNestedMatrix&>
145 template<
typename F, std::enable_if_t<
146 std::is_invocable_v<F, NestedMatrix&> and std::is_invocable_v<F, CholeskyNestedMatrix&>,
int> = 0>
150 return covariance_op(f, f);
155 #ifdef __cpp_concepts 156 template<std::invocable<NestedMatrix&> F> requires std::invocable<F, CholeskyNestedMatrix&>
158 template<
typename F, std::enable_if_t<
159 std::is_invocable_v<F, NestedMatrix&> and std::is_invocable_v<F, CholeskyNestedMatrix&>,
int> = 0>
163 return std::move(*this).covariance_op(f, f);
168 template<
bool direct_nested>
169 decltype(
auto) get_nested_matrix_impl() &
171 if constexpr (direct_nested)
173 if (synchronization_direction() < 0) synchronize_reverse();
178 if (synchronization_direction() > 0) synchronize_forward();
179 return cholesky_nested_matrix();
184 template<
bool direct_nested>
185 decltype(
auto) get_nested_matrix_impl()
const &
187 if constexpr (direct_nested)
189 if (synchronization_direction() < 0) synchronize_reverse();
194 if (synchronization_direction() > 0) synchronize_forward();
195 return cholesky_nested_matrix();
200 template<
bool direct_nested>
201 decltype(
auto) get_nested_matrix_impl() &&
203 if constexpr (direct_nested)
205 if (synchronization_direction() < 0) std::move(*this).synchronize_reverse();
206 return std::move(*this).nested_object();
210 if (synchronization_direction() > 0) std::move(*this).synchronize_forward();
211 return std::move(*this).cholesky_nested_matrix();
216 template<
bool direct_nested>
217 decltype(
auto) get_nested_matrix_impl()
const &&
219 if constexpr (direct_nested)
221 if (synchronization_direction() < 0) std::move(*this).synchronize_reverse();
222 return std::move(*this).nested_object();
226 if (synchronization_direction() > 0) std::move(*this).synchronize_forward();
227 return std::move(*this).cholesky_nested_matrix();
238 return this->get_nested_matrix_impl<hermitian_matrix<NestedMatrix>>();
245 return this->get_nested_matrix_impl<hermitian_matrix<NestedMatrix>>();
252 return std::move(*this).template get_nested_matrix_impl<hermitian_matrix<NestedMatrix>>();
259 return std::move(*this).template get_nested_matrix_impl<hermitian_matrix<NestedMatrix>>();
268 return this->get_nested_matrix_impl<triangular_matrix<NestedMatrix>>();
275 return this->get_nested_matrix_impl<triangular_matrix<NestedMatrix>>();
282 return std::move(*this).template get_nested_matrix_impl<triangular_matrix<NestedMatrix>>();
289 return std::move(*this).template get_nested_matrix_impl<triangular_matrix<NestedMatrix>>();
298 if constexpr (triangular_covariance<Derived> and not triangular_matrix<NestedMatrix>)
300 if (synchronization_direction() > 0)
309 else if constexpr (self_adjoint_covariance<Derived> and not hermitian_matrix<NestedMatrix>)
311 if (synchronization_direction() > 0)
323 if (synchronization_direction() < 0)
325 if constexpr (triangular_covariance<Derived>)
349 #ifdef __cpp_concepts 350 auto operator() (std::size_t i, std::size_t j)
351 requires writable_by_component<NestedMatrix, 2> and element_gettable<NestedMatrix, 2>
353 template<
typename T = NestedMatrix, std::enable_if_t<writable_by_component<T, 2> and element_gettable<T, 2>,
int> = 0>
357 return Base::operator()(i, j);
362 #ifdef __cpp_concepts 363 auto operator() (std::size_t i, std::size_t j)
const requires element_gettable<NestedMatrix, 2>
365 template<
typename T = NestedMatrix, std::enable_if_t<element_gettable<T, 2>,
int> = 0>
369 return Base::operator()(i, j);
378 #ifdef __cpp_concepts 379 auto operator[] (std::size_t i) requires writable_by_component<NestedMatrix, 1> and element_gettable<NestedMatrix, 1>
381 template<
typename T = NestedMatrix, std::enable_if_t<writable_by_component<T, 1> and element_gettable<T, 1>,
int> = 0>
385 return Base::operator[](i);
390 #ifdef __cpp_concepts 391 auto operator[] (std::size_t i)
const requires element_gettable<NestedMatrix, 1>
393 template<
typename T = NestedMatrix, std::enable_if_t<element_gettable<T, 1>,
int> = 0>
397 return Base::operator[](i);
402 #ifdef __cpp_concepts 403 auto operator() (std::size_t i) requires writable_by_component<NestedMatrix, 1> and element_gettable<NestedMatrix, 1>
405 template<
typename T = NestedMatrix, std::enable_if_t<writable_by_component<T, 1> and element_gettable<T, 1>,
int> = 0>
409 return Base::operator[](i);
414 #ifdef __cpp_concepts 416 requires element_gettable<NestedMatrix, 1>
418 template<
typename T = NestedMatrix, std::enable_if_t<element_gettable<T, 1>,
int> = 0>
422 return Base::operator[](i);
429 #ifdef __cpp_concepts 430 void set_component(
const Scalar s,
const std::size_t i,
const std::size_t j) requires writable_by_component<NestedMatrix, 2>
432 template<
typename T = NestedMatrix, std::enable_if_t<writable_by_component<T, 2>,
int> = 0>
443 #ifdef __cpp_concepts 444 void set_component(
const Scalar s,
const std::size_t i) requires writable_by_component<NestedMatrix, 1>
446 template<
typename T = NestedMatrix, std::enable_if_t<writable_by_component<T, 1>,
int> = 0>
459 #endif //OPENKALMAN_COVARIANCEIMPL_HPP auto covariance_op(const F1 &f1, const F2 &f2) const &&
Definition: CovarianceImpl.hpp:116
Definition: CovarianceImpl.hpp:39
Arg && set_component(Arg &&arg, const scalar_type_of_t< Arg > &s, const Indices &indices)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: set_component.hpp:51
typename scalar_type_of< T >::type scalar_type_of_t
helper template for scalar_type_of.
Definition: scalar_type_of.hpp:54
void set_component(const Scalar s, const std::size_t i)
Set an element of the cholesky nested matrix.
Definition: CovarianceImpl.hpp:447
auto covariance_op(const F &f) const &
Definition: CovarianceImpl.hpp:148
void set_component(const Scalar s, const std::size_t i, const std::size_t j)
Set an element of the cholesky nested matrix.
Definition: CovarianceImpl.hpp:433
auto operator()(std::size_t i, std::size_t j)
Get or set element (i, j) of the covariance matrix.
Definition: CovarianceImpl.hpp:354
Definition: CovarianceBase1.hpp:34
constexpr auto determinant(Arg &&arg)
Take the determinant of a matrix.
Definition: determinant.hpp:44
auto covariance_op(const F &f) const &&
Definition: CovarianceImpl.hpp:161
decltype(auto) get_self_adjoint_nested_matrix() &
Definition: CovarianceImpl.hpp:236
scalar_type_of_t< NestedMatrix > Scalar
Scalar type for this matrix.
Definition: CovarianceImpl.hpp:47
decltype(auto) get_triangular_nested_matrix() &
Definition: CovarianceImpl.hpp:266
decltype(auto) constexpr nested_object(Arg &&arg)
Retrieve a nested object of Arg, if it exists.
Definition: nested_object.hpp:34
Definition: basics.hpp:48
auto operator[](std::size_t i)
Get or set element i of the covariance matrix, if it is a vector.
Definition: CovarianceImpl.hpp:382
auto determinant() const
Definition: CovarianceImpl.hpp:296