OpenKalman
set_triangle.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) 2022-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 
17 #ifndef OPENKALMAN_SET_TRIANGLE_HPP
18 #define OPENKALMAN_SET_TRIANGLE_HPP
19 
20 namespace OpenKalman::internal
21 {
33 #ifdef __cpp_concepts
34  template<TriangleType t, indexible A, indexible B> requires
35  (t != TriangleType::any) and (index_count_v<A> == dynamic_size or index_count_v<A> <= 2) and
36  (t != TriangleType::lower or dimension_size_of_index_is<A, 0, index_dimension_of_v<B, 0>, Applicability::permitted>) and
37  (t != TriangleType::upper or dimension_size_of_index_is<A, 1, index_dimension_of_v<B, 1>, Applicability::permitted>) and
38  (not (diagonal_matrix<A> or (triangular_matrix<A> and not triangular_matrix<A, t>)) or t == TriangleType::diagonal or diagonal_matrix<B>)
39 #else
40  template<TriangleType t, typename A, typename B, std::enable_if_t<indexible<A> and indexible<B> and
41  (t != TriangleType::any) and (index_count<A>::value == dynamic_size or index_count<A>::value <= 2) and
42  (t != TriangleType::lower or dimension_size_of_index_is<A, 0, index_dimension_of<B, 0>::value, Applicability::permitted>) and
43  (t != TriangleType::upper or dimension_size_of_index_is<A, 1, index_dimension_of<B, 1>::value, Applicability::permitted>) and
44  (not (diagonal_matrix<A> or (triangular_matrix<A> and not triangular_matrix<A, t>)) or t == TriangleType::diagonal or diagonal_matrix<B>), int> = 0>
45 #endif
46  constexpr A&&
47  set_triangle(A&& a, B&& b)
48  {
49  if constexpr (interface::set_triangle_defined_for<A, t, A&&, B&&>)
50  {
51  interface::library_interface<std::decay_t<A>>::template set_triangle<t>(std::forward<A>(a), std::forward<B>(b));
52  }
53  else if constexpr (interface::set_triangle_defined_for<A, t, A&&, decltype(to_native_matrix<A>(std::declval<B&&>()))>)
54  {
55  interface::library_interface<std::decay_t<A>>::template set_triangle<t>(std::forward<A>(a), to_native_matrix<A>(std::forward<B>(b)));
56  }
57  else if constexpr (triangular_adapter<A>)
58  {
59  set_triangle<t>(nested_object(a), std::forward<B>(b));
60  }
61  else if constexpr (hermitian_adapter<A>)
62  {
63  if constexpr ((t == TriangleType::lower and hermitian_adapter<A, HermitianAdapterType::upper>) or
64  (t == TriangleType::upper and hermitian_adapter<A, HermitianAdapterType::lower>))
65  set_triangle<t>(nested_object(a), adjoint(std::forward<B>(b)));
66  else
67  set_triangle<t>(nested_object(a), std::forward<B>(b));
68  }
69  else if constexpr (diagonal_adapter<A, 0>)
70  {
71  assign(nested_object(a), diagonal_of(std::forward<B>(b)));
72  }
73  else if constexpr (diagonal_adapter<A, 1>)
74  {
75  assign(nested_object(a), transpose(diagonal_of(std::forward<B>(b))));
76  }
77  else if constexpr (t == TriangleType::upper)
78  {
79  for (int i = 0; i < get_index_dimension_of<0>(a); i++)
80  for (int j = i; j < get_index_dimension_of<1>(a); j++)
81  set_component(a, get_component(b, i, i), i, i);
82  }
83  else if constexpr (t == TriangleType::lower)
84  {
85  for (int i = 0; i < get_index_dimension_of<0>(a); i++)
86  for (int j = 0; j < i; j++)
87  set_component(a, get_component(b, i, i), i, i);
88  }
89  else // t == TriangleType::diagonal
90  {
91  for (int i = 0; i < get_index_dimension_of<0>(a); i++) set_component(a, get_component(b, i, i), i, i);
92  }
93  return std::forward<A>(a);
94  }
95 
96 
102 #ifdef __cpp_concepts
103  template<indexible A, vector_space_descriptors_may_match_with<A> B> requires (triangular_matrix<A> or triangular_matrix<B>) and
104  (triangle_type_of_v<A, B> != TriangleType::any or triangle_type_of_v<A> == TriangleType::any or triangle_type_of_v<B> == TriangleType::any)
105  constexpr vector_space_descriptors_may_match_with<A> decltype(auto)
106 #else
107  template<typename A, typename B, std::enable_if_t<indexible<A> and vector_space_descriptors_may_match_with<B, A> and
108  (triangular_matrix<A> or triangular_matrix<B>) and
109  (triangle_type_of<A, B>::value != TriangleType::any or triangle_type_of<A>::value == TriangleType::any or
110  triangle_type_of<B>::value == TriangleType::any), int> = 0>
111  constexpr decltype(auto)
112 #endif
113  set_triangle(A&& a, B&& b)
114  {
115  constexpr auto t =
116  diagonal_matrix<A> or diagonal_matrix<B> ? TriangleType::diagonal :
117  triangle_type_of_v<A, B> != TriangleType::any ? triangle_type_of_v<A, B> :
118  triangle_type_of_v<A> == TriangleType::any ? triangle_type_of_v<B> : triangle_type_of_v<A>;
119  return set_triangle<t>(std::forward<A>(a), std::forward<B>(b));
120  }
121 
122 } // namespace OpenKalman::internal
123 
124 #endif //OPENKALMAN_SET_TRIANGLE_HPP
constexpr bool dimension_size_of_index_is
Specifies that a given index of T has a specified size.
Definition: dimension_size_of_index_is.hpp:44
TriangleType
The type of a triangular matrix.
Definition: global-definitions.hpp:60
constexpr bool diagonal_matrix
Specifies that a type is a diagonal matrix or tensor.
Definition: diagonal_matrix.hpp:32
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
Lower, upper, or diagonal matrix.
An upper-right triangular matrix.
constexpr bool triangular_matrix
Specifies that a type is a triangular matrix (upper, lower, or diagonal).
Definition: triangular_matrix.hpp:37
decltype(auto) constexpr transpose(Arg &&arg)
Take the transpose of a matrix.
Definition: transpose.hpp:58
The concept, trait, or restraint is permitted, but whether it applies is not necessarily known at com...
decltype(auto) constexpr diagonal_of(Arg &&arg)
Extract a column vector (or column slice for rank>2 tensors) comprising the diagonal elements...
Definition: diagonal_of.hpp:33
Applicability
The applicability of a concept, trait, or restraint.
Definition: global-definitions.hpp:93
decltype(auto) constexpr adjoint(Arg &&arg)
Take the adjoint of a matrix.
Definition: adjoint.hpp:33
A diagonal matrix (both a lower-left and an upper-right triangular matrix).
constexpr To && assign(To &&a, From &&b)
Assign a writable object from an indexible object.
Definition: assign.hpp:51
decltype(auto) constexpr get_component(Arg &&arg, const Indices &indices)
Get a component of an object at a particular set of indices.
Definition: get_component.hpp:54
constexpr std::size_t dynamic_size
A constant indicating that a size or index is dynamic.
Definition: global-definitions.hpp:33
decltype(auto) constexpr nested_object(Arg &&arg)
Retrieve a nested object of Arg, if it exists.
Definition: nested_object.hpp:34
A lower-left triangular matrix.
Definition: basics.hpp:48