11 #ifndef OPENKALMAN_COVARIANCE_HPP 12 #define OPENKALMAN_COVARIANCE_HPP 24 template<fixed_pattern StaticDescriptor, covariance_nestable NestedMatrix> requires
25 (coordinates::dimension_of_v<StaticDescriptor> == index_dimension_of_v<NestedMatrix, 0>) and
26 (not std::is_rvalue_reference_v<NestedMatrix>) and values::number<scalar_type_of_t<NestedMatrix>>
28 template<
typename StaticDescriptor,
typename NestedMatrix>
33 #ifndef __cpp_concepts 34 static_assert(fixed_pattern<StaticDescriptor>);
35 static_assert(covariance_nestable<NestedMatrix>);
36 static_assert(coordinates::dimension_of_v<StaticDescriptor> == index_dimension_of_v<NestedMatrix, 0>);
37 static_assert(not std::is_rvalue_reference_v<NestedMatrix>);
46 using typename Base::CholeskyNestedMatrix;
48 using Base::cholesky_nested_matrix;
49 using Base::synchronization_direction;
50 using Base::synchronize_forward;
51 using Base::synchronize_reverse;
52 using Base::mark_nested_matrix_changed;
53 using Base::mark_cholesky_nested_matrix_changed;
54 using Base::mark_synchronized;
58 static constexpr
auto dim = index_dimension_of_v<NestedMatrix, 0>;
62 triangle_type_of_v<typename MatrixTraits<std::decay_t<NestedMatrix>>::template TriangularAdapterFrom<>>;
65 using NestedSelfAdjoint = std::conditional_t<hermitian_matrix<NestedMatrix>, NestedMatrix,
66 typename MatrixTraits<std::decay_t<NestedMatrix>>::template SelfAdjointMatrixFrom<storage_triangle>>;
70 template<
typename C = StaticDescriptor,
typename Arg>
71 static auto make(Arg&& arg)
81 template<triangular_covariance M> requires (not diagonal_matrix<M> or identity_matrix<M> or zero<M>) and
84 template<
typename M, std::enable_if_t<triangular_covariance<M> and
85 (not diagonal_matrix<M> or
identity_matrix<M> or zero<M>) and
86 (hermitian_matrix<nested_
object_of_t<M>> == hermitian_matrix<NestedMatrix>),
int> = 0>
98 Covariance() requires std::default_initializable<Base>
100 template<
typename T = Base, std::enable_if_t<std::is_default_constructible_v<T>,
int> = 0>
109 #ifdef __cpp_concepts 110 template<self_adjo
int_covariance M> requires (not std::derived_from<std::decay_t<M>, Covariance>) and
111 requires(M&& m) {
Base {std::forward<M>(m)}; }
113 template<
typename M, std::enable_if_t<self_adjo
int_covariance<M> and
114 (not std::is_base_of_v<Covariance, std::decay_t<M>>) and std::is_constructible_v<Base, M&&>,
int> = 0>
122 #ifdef __cpp_concepts 123 template<covariance_nestable M> requires requires(M&& m) {
Base {std::forward<M>(m)}; }
125 template<
typename M, std::enable_if_t<covariance_nestable<M> and std::is_constructible_v<Base, M&&>,
int> = 0>
136 #ifdef __cpp_concepts 137 template<typed_matrix M> requires (square_shaped<M> or (diagonal_matrix<NestedMatrix> and vector<M>)) and
138 compares_with<vector_space_descriptor_of_t<M, 0>, StaticDescriptor> and
139 requires(M&& m) {
Base {oin::to_covariance_nestable<NestedSelfAdjoint>(std::forward<M>(m))}; }
141 template<
typename M, std::enable_if_t<typed_matrix<M> and
142 (square_shaped<M> or (diagonal_matrix<NestedMatrix> and vector<M>)) and
143 compares_with<vector_space_descriptor_of_t<M, 0>, StaticDescriptor> and
144 std::is_constructible_v<Base,
145 decltype(oin::to_covariance_nestable<NestedSelfAdjo
int>(std::declval<M&&>()))>,
int> = 0>
148 :
Base {oin::to_covariance_nestable<NestedSelfAdjoint>(std::forward<M>(m))} {}
157 #ifdef __cpp_concepts 158 template<typed_matrix_nestable M> requires (not covariance_nestable<M>) and
159 (square_shaped<M> or (diagonal_matrix<NestedMatrix> and vector<M>)) and
160 requires(M&& m) {
Base {oin::to_covariance_nestable<NestedSelfAdjoint>(std::forward<M>(m))};
163 template<
typename M, std::enable_if_t<typed_matrix_nestable<M> and (not covariance_nestable<M>) and
164 (square_shaped<M> or (diagonal_matrix<NestedMatrix> and vector<M>)) and
165 std::is_constructible_v<Base,
166 decltype(oin::to_covariance_nestable<NestedSelfAdjo
int>(std::declval<M&&>()))>,
int> = 0>
169 :
Base {oin::to_covariance_nestable<NestedSelfAdjoint>(std::forward<M>(m))} {}
179 #ifdef __cpp_concepts 180 template<std::convertible_to<const Scalar> ... Args> requires (
sizeof...(Args) > 0) and
181 requires(Args ... args) {
Base {make_dense_object_from<NestedSelfAdjoint>(
static_cast<const Scalar>(args)...)};
184 template<
typename ... Args, std::enable_if_t<(std::is_convertible_v<Args, const Scalar> and ...) and
185 ((diagonal_matrix<NestedMatrix> and
sizeof...(Args) == dim) or
186 (
sizeof...(Args) == dim * dim)) and std::is_constructible_v<Base, NestedSelfAdjoint&&>,
int> = 0>
189 :
Base {make_dense_object_from<NestedSelfAdjoint>(
static_cast<const Scalar>(args)...)} {}
197 #ifdef __cpp_concepts 198 template<self_adjo
int_covariance Arg>
199 requires (not std::derived_from<std::decay_t<Arg>, Covariance>) and
200 compares_with<vector_space_descriptor_of_t<Arg, 0>, StaticDescriptor> and
203 template<
typename Arg, std::enable_if_t<(not std::is_base_of_v<Covariance, std::decay_t<Arg>>) and
204 (self_adjo
int_covariance<Arg> and compares_with<vector_space_descriptor_of_t<Arg, 0>, StaticDescriptor>and
205 std::is_assignable_v<std::add_lvalue_reference_t<NestedMatrix>, nested_
object_of_t<Arg&&>>,
int> = 0>
207 auto& operator=(Arg&& arg)
209 if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
211 Base::operator=(std::forward<Arg>(arg));
221 #ifdef __cpp_concepts 222 template<typed_matrix Arg> requires square_shaped<Arg> and
223 compares_with<vector_space_descriptor_of_t<Arg, 0>, StaticDescriptor>and
224 std::assignable_from<std::add_lvalue_reference_t<NestedMatrix>, NestedSelfAdjoint>
226 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and square_shaped<Arg> and
227 compares_with<vector_space_descriptor_of_t<Arg, 0>, StaticDescriptor>and
228 std::assignable_from<std::add_lvalue_reference_t<NestedMatrix>, NestedSelfAdjo
int>,
int> = 0>
230 auto& operator=(Arg&& other)
232 if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
234 Base::operator=(oin::to_covariance_nestable<NestedSelfAdjoint>(std::forward<Arg>(other)));
241 #ifdef __cpp_concepts 242 template<covariance_nestable Arg> requires std::assignable_from<std::add_lvalue_reference_t<NestedMatrix>, Arg&&>
244 template<
typename Arg, std::enable_if_t<(covariance_nestable<Arg>) and
245 std::assignable_from<std::add_lvalue_reference_t<NestedMatrix>, Arg&&>,
int> = 0>
247 auto& operator=(Arg&& other)
249 if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
251 Base::operator=(std::forward<Arg>(other));
261 #ifdef __cpp_concepts 262 template<typed_matrix_nestable Arg> requires (not covariance_nestable<Arg>) and square_shaped<Arg> and
263 std::assignable_from<std::add_lvalue_reference_t<NestedMatrix>, NestedSelfAdjoint>
265 template<
typename Arg, std::enable_if_t<typed_matrix_nestable<Arg> and (not covariance_nestable<Arg>) and
266 square_shaped<Arg> and std::is_assignable_v<std::add_lvalue_reference_t<NestedMatrix>, NestedSelfAdjo
int>,
int> = 0>
268 auto& operator=(Arg&& other)
270 if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
272 Base::operator=(oin::to_covariance_nestable<NestedSelfAdjoint>(std::forward<Arg>(other)));
282 #ifdef __cpp_concepts 283 template<
typename Arg> requires (not std::is_const_v<std::remove_reference_t<NestedMatrix>>) and
284 (self_adjoint_covariance<Arg> or (typed_matrix<Arg> and square_shaped<Arg>)) and
285 coordinates::compares_with<vector_space_descriptor_of_t<Arg, 0>, StaticDescriptor>
287 template<
typename Arg, std::enable_if_t<(not std::is_const_v<std::remove_reference_t<NestedMatrix>>) and
288 (self_adjo
int_covariance<Arg> or (typed_matrix<Arg> and square_shaped<Arg>)) and
289 compares_with<vector_space_descriptor_of_t<Arg, 0>, StaticDescriptor>,
int> = 0>
291 auto& operator+=(Arg&& arg)
293 if constexpr(hermitian_matrix<NestedMatrix>)
295 nested_object() += oin::to_covariance_nestable<NestedMatrix>(std::forward<Arg>(arg));
296 mark_nested_matrix_changed();
300 if (synchronization_direction() >= 0)
302 if constexpr(triangular_matrix<NestedMatrix, TriangleType::upper>)
306 nested_object(), oin::to_covariance_nestable<NestedMatrix>(std::forward<Arg>(arg))));
311 nested_object(), oin::to_covariance_nestable<NestedMatrix>(std::forward<Arg>(arg))));
314 if (synchronization_direction() <= 0)
316 cholesky_nested_matrix() += oin::to_covariance_nestable<NestedSelfAdjoint>(
317 std::forward<Arg>(arg));
327 #ifdef __cpp_concepts 328 auto& operator+=(
const Covariance& arg) requires (not std::is_const_v<std::remove_reference_t<NestedMatrix>>)
330 template<
typename T = NestedMatrix, std::enable_if_t<(not std::is_const_v<std::remove_reference_t<T>>),
int> = 0>
331 auto& operator+=(
const Covariance& arg)
334 return operator+=<
const Covariance&>(arg);
338 #ifdef __cpp_concepts 339 template<
typename Arg> requires (not std::is_const_v<std::remove_reference_t<NestedMatrix>>) and
340 (self_adjoint_covariance<Arg> or (typed_matrix<Arg> and square_shaped<Arg>)) and
341 coordinates::compares_with<vector_space_descriptor_of_t<Arg, 0>, StaticDescriptor>
343 template<
typename Arg, std::enable_if_t<(not std::is_const_v<std::remove_reference_t<NestedMatrix>>) and
344 (self_adjo
int_covariance<Arg> or (typed_matrix<Arg> and square_shaped<Arg>)) and
345 compares_with<vector_space_descriptor_of_t<Arg, 0>, StaticDescriptor>,
int> = 0>
347 auto& operator-=(
const Arg& arg)
349 if constexpr(hermitian_matrix<NestedMatrix>)
351 nested_object() -= oin::to_covariance_nestable<NestedMatrix>(arg);
352 mark_nested_matrix_changed();
356 if (synchronization_direction() >= 0)
358 using TLowerType =
typename MatrixTraits<std::decay_t<NestedMatrix>>::template TriangularAdapterFrom<TriangleType::lower>;
359 const auto U = oin::to_covariance_nestable<TLowerType>(arg);
362 if (synchronization_direction() <= 0)
364 cholesky_nested_matrix() -= oin::to_covariance_nestable<NestedSelfAdjoint>(arg);
374 #ifdef __cpp_concepts 375 auto& operator-=(
const Covariance& arg) requires (not std::is_const_v<std::remove_reference_t<NestedMatrix>>)
377 template<
typename T = NestedMatrix, std::enable_if_t<(not std::is_const_v<std::remove_reference_t<T>>),
int> = 0>
378 auto& operator-=(
const Covariance& arg)
381 return operator-=<
const Covariance&>(arg);
385 #ifdef __cpp_concepts 386 template<std::convertible_to<Scalar> S> requires (not std::is_const_v<std::remove_reference_t<NestedMatrix>>)
388 template<
typename S, std::enable_if_t<std::is_convertible_v<S, Scalar> and
389 (not std::is_const_v<std::remove_reference_t<NestedMatrix>>),
int> = 0>
391 auto& operator*=(
const S s)
393 if constexpr(hermitian_matrix<NestedMatrix>)
396 mark_nested_matrix_changed();
400 if (synchronization_direction() >= 0)
nested_object() *= square_root(static_cast<const Scalar>(s));
401 if (synchronization_direction() <= 0) cholesky_nested_matrix() *=
static_cast<const Scalar>(s);
405 if (synchronization_direction() >= 0)
407 using TLowerType =
typename MatrixTraits<std::decay_t<NestedMatrix>>::template TriangularAdapterFrom<TriangleType::lower>;
408 const auto U = oin::to_covariance_nestable<TLowerType>(*this);
412 if (synchronization_direction() <= 0)
414 cholesky_nested_matrix() *=
static_cast<const Scalar>(s);
420 if (synchronization_direction() <= 0)
422 cholesky_nested_matrix() =
make_zero(cholesky_nested_matrix());
430 #ifdef __cpp_concepts 431 template<std::convertible_to<Scalar> S> requires (not std::is_const_v<std::remove_reference_t<NestedMatrix>>)
433 template<
typename S, std::enable_if_t<std::is_convertible_v<S, Scalar> and
434 (not std::is_const_v<std::remove_reference_t<NestedMatrix>>),
int> = 0>
436 auto& operator/=(
const S s)
438 if constexpr(hermitian_matrix<NestedMatrix>)
441 mark_nested_matrix_changed();
445 if (synchronization_direction() >= 0)
nested_object() /= square_root(static_cast<const Scalar>(s));
446 if (synchronization_direction() <= 0) cholesky_nested_matrix() /=
static_cast<const Scalar>(s);
450 if (synchronization_direction() >= 0)
452 using TLowerType =
typename MatrixTraits<std::decay_t<NestedMatrix>>::template TriangularAdapterFrom<TriangleType::lower>;
453 const auto u = oin::to_covariance_nestable<TLowerType>(*this);
455 OpenKalman::rank_update(
nested_object(), u, 1 / static_cast<const Scalar>(s));
457 if (synchronization_direction() <= 0)
459 cholesky_nested_matrix() /=
static_cast<const Scalar>(s);
464 throw std::runtime_error(
"Covariance operator/=: divide by zero");
471 #ifdef __cpp_concepts 472 template<std::convertible_to<Scalar> S> requires (not std::is_const_v<std::remove_reference_t<NestedMatrix>>)
474 template<
typename S, std::enable_if_t<std::is_convertible_v<S, Scalar> and
475 (not std::is_const_v<std::remove_reference_t<NestedMatrix>>),
int> = 0>
477 auto&
scale(
const S s)
479 if constexpr(hermitian_matrix<NestedMatrix>)
482 mark_nested_matrix_changed();
487 if (synchronization_direction() <= 0) cholesky_nested_matrix() *=
static_cast<const Scalar>(s) * s;
494 #ifdef __cpp_concepts 495 template<std::convertible_to<Scalar> S> requires (not std::is_const_v<std::remove_reference_t<NestedMatrix>>)
497 template<
typename S, std::enable_if_t<std::is_convertible_v<S, Scalar> and
498 (not std::is_const_v<std::remove_reference_t<NestedMatrix>>),
int> = 0>
502 if constexpr(hermitian_matrix<NestedMatrix>)
505 mark_nested_matrix_changed();
510 if (synchronization_direction() <= 0) cholesky_nested_matrix() /=
static_cast<const Scalar>(s) * s;
528 if constexpr ((not diagonal_matrix<NestedMatrix>) or identity_matrix<NestedMatrix> or zero<NestedMatrix>)
534 static_assert(diagonal_matrix<NestedMatrix>);
542 auto square_root()
const &
544 if constexpr ((not diagonal_matrix<NestedMatrix>) or identity_matrix<NestedMatrix> or zero<NestedMatrix>)
550 static_assert(diagonal_matrix<NestedMatrix>);
558 auto square_root() &&
560 if constexpr ((not diagonal_matrix<NestedMatrix>) or identity_matrix<NestedMatrix> or zero<NestedMatrix>)
566 static_assert(diagonal_matrix<NestedMatrix>);
567 auto n = cholesky_factor<storage_triangle>(std::move(*this).nested_object());
574 auto square_root()
const &&
576 if constexpr ((not diagonal_matrix<NestedMatrix>) or identity_matrix<NestedMatrix> or zero<NestedMatrix>)
582 static_assert(diagonal_matrix<NestedMatrix>);
583 auto n = cholesky_factor<storage_triangle>(std::move(*this).nested_object());
592 #ifdef __cpp_concepts 593 template<typed_matrix U> requires compares_with<vector_space_descriptor_of_t<U, 0>, StaticDescriptor>and
594 (not std::is_const_v<std::remove_reference_t<NestedMatrix>>)
596 template<
typename U, std::enable_if_t<typed_matrix<U> and
597 compares_with<vector_space_descriptor_of_t<U, 0>, StaticDescriptor>and
598 (not std::is_const_v<std::remove_reference_t<NestedMatrix>>),
int> = 0>
600 auto& rank_update(
const U& u,
const Scalar alpha = 1) &
602 if (synchronization_direction() < 0) Base::synchronize_reverse();
603 if constexpr (one_dimensional<NestedMatrix>)
611 mark_nested_matrix_changed();
619 #ifdef __cpp_concepts 620 template<typed_matrix U> requires coordinates::compares_with<vector_space_descriptor_of_t<U, 0>, StaticDescriptor>
622 template<
typename U, std::enable_if_t<typed_matrix<U> and
623 compares_with<vector_space_descriptor_of_t<U, 0>, StaticDescriptor>,
int> = 0>
625 auto rank_update(
const U& u,
const Scalar alpha = 1) &&
627 if (synchronization_direction() < 0) synchronize_reverse();
628 if constexpr (one_dimensional<NestedMatrix>)
630 std::tuple d_tup {Dimensions<1>{}, Dimensions<1>{}};
641 #ifdef __cpp_concepts 642 template<
typename,
typename>
644 template<
typename,
typename,
typename>
649 template<
typename,
typename>
653 template<
typename,
typename>
657 #ifdef __cpp_concepts 658 template<fixed_pattern C, covariance_nestable N> requires
659 (coordinates::dimension_of_v<C> == index_dimension_of_v<N, 0>) and (not std::is_rvalue_reference_v<N>)
661 template<
typename,
typename>
663 friend struct Covariance;
666 #ifdef __cpp_concepts 667 template<fixed_pattern C, covariance_nestable N> requires
668 (coordinates::dimension_of_v<C> == index_dimension_of_v<N, 0>) and (not std::is_rvalue_reference_v<N>)
670 template<
typename,
typename>
684 #ifdef __cpp_concepts 685 template<covariance_nestable M>
687 template<
typename M, std::enable_if_t<covariance_nestable<M>,
int> = 0>
695 #ifdef __cpp_concepts 696 template<typed_matrix M> requires square_shaped<M>
698 template<
typename M, std::enable_if_t<typed_matrix<M> and square_shaped<M>,
int> = 0>
702 typename MatrixTraits<std::decay_t<nested_object_of_t<M>>>::template SelfAdjointMatrixFrom<>>;
708 #ifdef __cpp_concepts 709 template<typed_matrix_nestable M> requires (not covariance_nestable<M>) and square_shaped<M>
711 template<
typename M, std::enable_if_t<
712 typed_matrix_nestable<M> and (not covariance_nestable<M>) and square_shaped<M>,
int> = 0>
715 Dimensions<index_dimension_of_v<M, 0>>,
typename MatrixTraits<std::decay_t<M>>::template SelfAdjointMatrixFrom<>>;
727 #ifdef __cpp_concepts 728 template<fixed_pattern StaticDescriptor, covariance_nestable Arg> requires
729 (coordinates::dimension_of_v<StaticDescriptor> == index_dimension_of_v<Arg, 0>)
731 template<
typename StaticDescriptor,
typename Arg, std::enable_if_t<fixed_pattern<StaticDescriptor> and
732 covariance_nestable<Arg> and (coordinates::dimension_of_v<StaticDescriptor> == index_dimension_of<Arg, 0>::value),
int> = 0>
747 #ifdef __cpp_concepts 748 template<fixed_pattern StaticDescriptor, TriangleType triangle_type, covariance_nestable Arg> requires
749 (coordinates::dimension_of_v<StaticDescriptor> == index_dimension_of_v<Arg, 0>) and
754 template<
typename StaticDescriptor,
TriangleType triangle_type,
typename Arg, std::enable_if_t<
755 fixed_pattern<StaticDescriptor> and covariance_nestable<Arg> and
774 #ifdef __cpp_concepts 775 template<covariance_nestable Arg>
777 template<
typename Arg, std::enable_if_t<covariance_nestable<Arg>,
int> = 0>
782 using C = Dimensions<index_dimension_of_v<Arg, 0>>;
783 return make_covariance<C>(std::forward<Arg>(arg));
794 #ifdef __cpp_concepts 795 template<fixed_pattern StaticDescriptor, TriangleType triangle_type, typed_matrix_nestable Arg> requires
796 (not covariance_nestable<Arg>) and
798 (coordinates::dimension_of_v<StaticDescriptor> == index_dimension_of_v<Arg, 0>) and (coordinates::dimension_of_v<StaticDescriptor> == index_dimension_of_v<Arg, 1>)
800 template<
typename StaticDescriptor,
TriangleType triangle_type,
typename Arg, std::enable_if_t<
801 fixed_pattern<StaticDescriptor> and typed_matrix_nestable<Arg> and (not covariance_nestable<Arg>) and
809 using T =
typename MatrixTraits<std::decay_t<Arg>>::template TriangularAdapterFrom<triangle_type>;
820 #ifdef __cpp_concepts 821 template<fixed_pattern StaticDescriptor, typed_matrix_nestable Arg> requires (not covariance_nestable<Arg>) and
822 (coordinates::dimension_of_v<StaticDescriptor> == index_dimension_of_v<Arg, 0>) and (coordinates::dimension_of_v<StaticDescriptor> == index_dimension_of_v<Arg, 1>)
824 template<
typename StaticDescriptor,
typename Arg, std::enable_if_t<
825 fixed_pattern<StaticDescriptor> and typed_matrix_nestable<Arg> and (not covariance_nestable<Arg>) and
832 using SA =
typename MatrixTraits<std::decay_t<Arg>>::template SelfAdjointMatrixFrom<>;
833 return make_covariance<StaticDescriptor, SA>(oin::to_covariance_nestable<SA>(std::forward<Arg>(arg)));
843 #ifdef __cpp_concepts 844 template<TriangleType triangle_type, typed_matrix_nestable Arg> requires (not covariance_nestable<Arg>) and
847 template<TriangleType triangle_type,
typename Arg, std::enable_if_t<typed_matrix_nestable<Arg> and
848 (not covariance_nestable<Arg>) and
849 (triangle_type == TriangleType::lower or triangle_type == TriangleType::upper) and square_shaped<Arg>,
int> = 0>
854 using C = Dimensions<index_dimension_of_v<Arg, 0>>;
855 return make_covariance<C, triangle_type>(std::forward<Arg>(arg));
864 #ifdef __cpp_concepts 865 template<typed_matrix_nestable Arg> requires (not covariance_nestable<Arg>) and square_shaped<Arg>
867 template<
typename Arg, std::enable_if_t<typed_matrix_nestable<Arg> and (not covariance_nestable<Arg>) and
868 square_shaped<Arg>,
int> = 0>
873 using C = Dimensions<index_dimension_of_v<Arg, 0>>;
874 return make_covariance<C>(std::forward<Arg>(arg));
882 #ifdef __cpp_concepts 883 template<fixed_pattern StaticDescriptor,
typename Arg> requires
884 (covariance_nestable<Arg> or typed_matrix_nestable<Arg>) and square_shaped<Arg>
886 template<
typename StaticDescriptor,
typename Arg, std::enable_if_t<
887 (covariance_nestable<Arg> or typed_matrix_nestable<Arg>) and square_shaped<Arg>,
int> = 0>
892 constexpr
TriangleType triangle_type = triangle_type_of_v<typename MatrixTraits<std::decay_t<Arg>>::template TriangularAdapterFrom<>>;
893 using B = std::conditional_t<diagonal_matrix<Arg>,
894 typename MatrixTraits<std::decay_t<Arg>>::template DiagonalMatrixFrom<>,
895 std::conditional_t<triangular_matrix<Arg>,
896 typename MatrixTraits<std::decay_t<Arg>>::template TriangularAdapterFrom<triangle_type>,
897 typename MatrixTraits<std::decay_t<Arg>>::template SelfAdjointMatrixFrom<triangle_type>>>;
906 #ifdef __cpp_concepts 907 template<fixed_pattern StaticDescriptor, TriangleType triangle_type, typed_matrix_nestable Arg> requires
910 template<
typename StaticDescriptor,
TriangleType triangle_type,
typename Arg,
911 std::enable_if_t<fixed_pattern<StaticDescriptor> and typed_matrix_nestable<Arg> and square_shaped<Arg>,
int> = 0>
917 typename MatrixTraits<std::decay_t<Arg>>::template DiagonalMatrixFrom<>,
918 typename MatrixTraits<std::decay_t<Arg>>::template TriangularAdapterFrom<triangle_type>>;
928 #ifdef __cpp_concepts 929 template<
typename Arg> requires (covariance_nestable<Arg> or typed_matrix_nestable<Arg>) and square_shaped<Arg>
931 template<
typename Arg, std::enable_if_t<(covariance_nestable<Arg> or typed_matrix_nestable<Arg>) and
932 square_shaped<Arg>,
int> = 0>
937 using C = Dimensions<index_dimension_of_v<Arg, 0>>;
938 return make_covariance<C, Arg>();
946 #ifdef __cpp_concepts 947 template<TriangleType triangle_type, typed_matrix_nestable Arg> requires square_shaped<Arg>
949 template<TriangleType triangle_type,
typename Arg, std::enable_if_t<typed_matrix_nestable<Arg> and
950 square_shaped<Arg>,
int> = 0>
955 using C = Dimensions<index_dimension_of_v<Arg, 0>>;
956 return make_covariance<C, triangle_type, Arg>();
964 #ifdef __cpp_concepts 965 template<self_adjo
int_covariance Arg>
967 template<
typename Arg, std::enable_if_t<self_adjo
int_covariance<Arg>,
int> = 0>
981 #ifdef __cpp_concepts 982 template<self_adjo
int_covariance T>
984 template<
typename T, std::enable_if_t<self_adjo
int_covariance<T>,
int> = 0>
991 return make_covariance<C, B>();
999 #ifdef __cpp_concepts 1000 template<typed_matrix Arg> requires square_shaped<Arg>
1002 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and square_shaped<Arg>,
int> = 0>
1008 return make_covariance<C>(
nested_object(std::forward<Arg>(arg)));
1016 #ifdef __cpp_concepts 1017 template<TriangleType triangle_type, typed_matrix Arg> requires
1020 template<TriangleType triangle_type,
typename Arg, std::enable_if_t<typed_matrix<Arg> and
1021 (triangle_type == TriangleType::lower or triangle_type == TriangleType::upper) and square_shaped<Arg>,
int> = 0>
1027 return make_covariance<C, triangle_type>(
nested_object(std::forward<Arg>(arg)));
1035 #ifdef __cpp_concepts 1036 template<TriangleType triangle_type, typed_matrix Arg> requires square_shaped<Arg>
1038 template<TriangleType triangle_type,
typename Arg, std::enable_if_t<typed_matrix<Arg> and
1039 square_shaped<Arg>,
int> = 0>
1046 return make_covariance<C, triangle_type, B>();
1054 #ifdef __cpp_concepts 1055 template<typed_matrix Arg> requires square_shaped<Arg>
1057 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and square_shaped<Arg>,
int> = 0>
1064 return make_covariance<C, B>();
1074 template<
typename Coeffs,
typename NestedMatrix>
1079 template<
typename Arg>
1080 static constexpr
auto count_indices(
const Arg& arg) {
return std::integral_constant<std::size_t, 2>{}; }
1082 template<
typename Arg,
typename N>
1085 return std::forward<Arg>(arg).my_dimension;
1089 template<
typename Arg>
1092 if constexpr (hermitian_matrix<NestedMatrix>)
1099 template<
typename Arg>
1100 static constexpr
auto get_constant(
const Arg& arg)
1102 if constexpr (hermitian_matrix<NestedMatrix>)
1105 return std::monostate {};
1109 template<
typename Arg>
1110 static constexpr
auto get_constant_diagonal(
const Arg& arg)
1116 template<Applicability b>
1117 static constexpr
bool one_dimensional = OpenKalman::one_dimensional<NestedMatrix, b>;
1120 template<Applicability b>
1121 static constexpr
bool is_square =
true;
1124 template<TriangleType t>
1125 static constexpr
bool is_triangular = triangular_matrix<NestedMatrix, TriangleType::diagonal>;
1128 static constexpr
bool is_triangular_adapter =
false;
1131 static constexpr
bool is_hermitian =
true;
1134 #ifdef __cpp_lib_concepts 1135 template<
typename Arg,
typename...I> requires
1138 template<
typename Arg,
typename...I, std::enable_if_t<
1141 static constexpr
auto get(Arg&& arg, I...i)
1143 return std::forward<Arg>(arg)(i...);
1147 #ifdef __cpp_lib_concepts 1148 template<
typename Arg,
typename...I> requires
1151 template<
typename Arg,
typename...I, std::enable_if_t<
1156 arg.set_component(s, i...);
1162 #ifdef __cpp_lib_concepts 1163 template<
typename Arg> requires raw_data_defined_for<NestedMatrix>
1165 template<
typename Arg, std::enable_if_t<raw_data_defined_for<NestedMatrix>,
int> = 0>
1167 static constexpr
auto *
const 1168 raw_data(Arg& arg) {
return internal::raw_data(
nested_object(arg)); }
1171 static constexpr
Layout layout = layout_of_v<NestedMatrix>;
1180 #endif //OPENKALMAN_COVARIANCE_HPP decltype(auto) constexpr concatenate_vertical(V &&v, Vs &&... vs)
Concatenate one or more typed matrices objects vertically.
Definition: typed-matrix-overloads.hpp:270
constexpr auto count_indices(const T &t)
Get the number of indices available to address the components of an indexible object.
Definition: count_indices.hpp:33
typename nested_object_of< T >::type nested_object_of_t
Helper type for nested_object_of.
Definition: nested_object_of.hpp:66
constexpr bool one_dimensional
Specifies that a type is one-dimensional in every index.
Definition: one_dimensional.hpp:83
TriangleType
The type of a triangular matrix.
Definition: global-definitions.hpp:60
Definition: indexible_object_traits.hpp:36
Definition: CovarianceImpl.hpp:39
Covariance(Args ... args)
Construct from a row-major list of Scalar coefficients forming a self-adjoint matrix.
Definition: Covariance.hpp:188
typename scalar_type_of< T >::type scalar_type_of_t
helper template for scalar_type_of.
Definition: scalar_type_of.hpp:54
Covariance(M &&m)
Construct from another non-square-root covariance.
Definition: Covariance.hpp:116
decltype(auto) constexpr QR_decomposition(A &&a)
Perform a QR decomposition of matrix A=Q[U,0], U is a upper-triangular matrix, and Q is orthogonal...
Definition: QR_decomposition.hpp:33
constexpr bool number
T is a numerical type.
Definition: number.hpp:33
decltype(auto) constexpr concatenate_horizontal(V &&v, Vs &&... vs)
Concatenate one or more matrix objects vertically.
Definition: typed-matrix-overloads.hpp:308
An upper-right triangular matrix.
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: CovarianceBase3Impl.hpp:35
The constant associated with T, assuming T is a constant_matrix.
Definition: constant_coefficient.hpp:36
The upper or lower triangle Cholesky factor (square root) of a covariance matrix. ...
Definition: forward-class-declarations.hpp:559
The root namespace for OpenKalman.
Definition: basics.hpp:34
An interface to various routines from the linear algebra library associated with indexible object T...
Definition: library_interface.hpp:37
The constant associated with T, assuming T is a constant_diagonal_matrix.
Definition: constant_diagonal_coefficient.hpp:32
scalar_type_of_t< NestedMatrix > Scalar
Scalar type for this matrix.
Definition: Covariance.hpp:41
decltype(auto) constexpr adjoint(Arg &&arg)
Take the adjoint of a matrix.
Definition: adjoint.hpp:33
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
decltype(auto) get_self_adjoint_nested_matrix() &
Definition: CovarianceImpl.hpp:236
Layout
The layout format of a multidimensional array.
Definition: global-definitions.hpp:47
decltype(auto) constexpr LQ_decomposition(A &&a)
Perform an LQ decomposition of matrix A=[L,0]Q, L is a lower-triangular matrix, and Q is orthogonal...
Definition: LQ_decomposition.hpp:33
A self-adjoint Covariance matrix.
Definition: Covariance.hpp:30
A diagonal matrix (both a lower-left and an upper-right triangular matrix).
auto make_covariance(Arg &&arg)
Make a Covariance from a covariance_nestable, specifying the fixed_pattern.
Definition: Covariance.hpp:735
The dimension of an index for a matrix, expression, or array.
Definition: index_dimension_of.hpp:34
scalar_type_of_t< NestedMatrix > Scalar
Scalar type for this matrix.
Definition: CovarianceImpl.hpp:47
Covariance()
Default constructor.
Definition: Covariance.hpp:101
constexpr auto make_zero(Descriptors &&descriptors)
Make a zero associated with a particular library.
Definition: make_zero.hpp:36
Covariance(M &&m)
Construct from a covariance_nestable.
Definition: Covariance.hpp:127
decltype(auto) get_triangular_nested_matrix() &
Definition: CovarianceImpl.hpp:266
auto inverse_scale(M &&m, const S s)
Scale a covariance by the inverse of a scalar factor.
Definition: covariance-arithmetic.hpp:543
auto scale(M &&m, const S s)
Scale a covariance by a factor.
Definition: covariance-arithmetic.hpp:518
decltype(auto) constexpr nested_object(Arg &&arg)
Retrieve a nested object of Arg, if it exists.
Definition: nested_object.hpp:34
decltype(auto) constexpr trace(Arg &&arg)
Take the trace of a matrix.
Definition: trace.hpp:35
A lower-left triangular matrix.
Definition: basics.hpp:48
constexpr bool hermitian_matrix
Specifies that a type is a hermitian matrix (assuming it is square_shaped).
Definition: hermitian_matrix.hpp:50
constexpr auto get_vector_space_descriptor(const T &t, const N &n)
Get the coordinates::pattern object for index N of indexible object T.
Definition: get_vector_space_descriptor.hpp:56