16 #ifndef OPENKALMAN_DIAGONALADAPTER_HPP 17 #define OPENKALMAN_DIAGONALADAPTER_HPP 23 template<vector<0, Applicability::permitted> NestedObject>
25 template<
typename NestedObject>
30 #ifndef __cpp_concepts 31 static_assert(vector<NestedObject, 0, Applicability::permitted>);
38 static constexpr
auto dim = index_dimension_of_v<NestedObject, 0>;
40 #ifndef __cpp_concepts 41 template<
typename T,
typename =
void>
42 struct is_constructible_from_diagonal : std::false_type {};
45 struct is_constructible_from_diagonal<T, std::void_t<decltype(NestedObject {diagonal_of(std::declval<T>())})>>
58 constexpr
DiagonalAdapter() requires std::default_initializable<NestedObject> and (not has_dynamic_dimensions<NestedObject>)
60 template<
typename T = NestedObject, std::enable_if_t<
61 std::is_default_constructible_v<T> and (not has_dynamic_dimensions<NestedObject>),
int> = 0>
71 template<vector_space_descriptors_may_match_with<NestedObject> Arg> requires
72 (not std::is_base_of_v<
DiagonalAdapter, std::decay_t<Arg>>) and std::constructible_from<NestedObject, Arg&&>
74 template<
typename Arg, std::enable_if_t<vector_space_descriptors_may_match_with<Arg, NestedObject> and
75 (not std::is_base_of_v<DiagonalAdapter, std::decay_t<Arg>>) and std::is_constructible_v<NestedObject, Arg&&>,
int> = 0>
80 #ifndef __cpp_concepts 83 template<
typename Arg,
typename =
void>
84 struct constants_match : std::true_type {};
86 template<
typename Arg>
87 struct constants_match<Arg, std::enable_if_t<
88 constant_coefficient<NestedObject>::value != constant_diagonal_coefficient<Arg>::value>>
97 template<diagonal_matrix Arg> requires (not std::is_base_of_v<
DiagonalAdapter, std::decay_t<Arg>>) and
98 vector_space_descriptors_may_match_with<NestedObject, decltype(diagonal_of(std::declval<Arg>()))> and
99 (not constant_matrix<NestedObject> or constant_diagonal_matrix<Arg>) and
101 std::assignable_from<std::add_lvalue_reference_t<NestedObject>, decltype(
diagonal_of(std::declval<Arg>()))>
103 template<
typename Arg, std::enable_if_t<
105 vector_space_descriptors_may_match_with<NestedObject, decltype(diagonal_of(std::declval<Arg>()))> and
107 std::is_assignable<std::add_lvalue_reference_t<NestedObject>, decltype(
diagonal_of(std::declval<Arg>()))>
::value,
int> = 0>
111 using Arg_diag = decltype(
diagonal_of(std::declval<Arg>()));
113 if constexpr (not vector_space_descriptors_match_with<NestedObject, Arg_diag>)
115 throw std::invalid_argument {
"Argument to DiagonalAdapter assignment operator has non-matching vector space descriptors."};
117 if constexpr (constant_matrix<NestedObject>)
121 throw std::invalid_argument {
"Argument to constant_diagonal DiagonalAdapter assignment operator has non-matching constant value."};
131 #ifdef __cpp_concepts 132 template<diagonal_matrix Arg>
133 requires (dynamic_dimension<Arg, 0> or dynamic_dimension<NestedObject, 0> or index_dimension_of_v<Arg, 0> == dim)
135 template<
typename Arg, std::enable_if_t<diagonal_matrix<Arg> and
136 (dynamic_dimension<Arg, 0> or dynamic_dimension<NestedObject, 0> or index_dimension_of<Arg, 0>::value == dim),
int> = 0>
138 auto& operator+=(Arg&& arg)
140 if constexpr (dynamic_dimension<NestedObject, 0>)
141 assert(get_vector_space_descriptor<0>(this->
nested_object()) == get_vector_space_descriptor<0>(arg));
148 #ifdef __cpp_concepts 149 template<diagonal_matrix Arg>
150 requires (dynamic_dimension<Arg, 0> or dynamic_dimension<NestedObject, 0> or index_dimension_of_v<Arg, 0> == dim)
152 template<
typename Arg, std::enable_if_t<diagonal_matrix<Arg> and
153 (dynamic_dimension<Arg, 0> or dynamic_dimension<NestedObject, 0> or index_dimension_of<Arg, 0>::value == dim),
int> = 0>
155 auto& operator-=(Arg&& arg)
157 if constexpr (dynamic_dimension<NestedObject, 0>)
158 assert(get_vector_space_descriptor<0>(this->
nested_object()) == get_vector_space_descriptor<0>(arg));
165 #ifdef __cpp_concepts 166 template<std::convertible_to<Scalar> S>
168 template<
typename S, std::enable_if_t<std::is_convertible_v<S, Scalar>,
int> = 0>
170 auto& operator*=(
const S s)
177 #ifdef __cpp_concepts 178 template<std::convertible_to<Scalar> S>
180 template<
typename S, std::enable_if_t<std::is_convertible_v<S, Scalar>,
int> = 0>
182 auto& operator/=(
const S s)
189 #ifdef __cpp_concepts 190 template<
typename Arg> requires (index_dimension_of_v<Arg, 0> == dim)
196 static_assert(index_dimension_of_v<Arg, 0> == dim);
202 #ifdef __cpp_concepts 203 template<
typename Arg> requires std::same_as<std::decay_t<Arg>,
DiagonalAdapter>
204 friend decltype(
auto) operator-(Arg&& arg)
209 decltype(
auto) operator-()
const&
214 decltype(
auto) operator-()
const&&
221 #ifdef __cpp_concepts 222 template<
typename Arg, std::convertible_to<const scalar_type_of_t<Arg>> S> requires std::same_as<std::decay_t<Arg>,
DiagonalAdapter>
224 template<
typename Arg,
typename S, std::enable_if_t<
225 std::is_same_v<std::decay_t<Arg>,
DiagonalAdapter> and std::is_convertible_v<S, const scalar_type_of_t<Arg>>>>
227 friend decltype(
auto) operator*(Arg&& arg, S s)
233 #ifdef __cpp_concepts 234 template<
typename Arg, std::convertible_to<const scalar_type_of_t<Arg>> S> requires std::same_as<std::decay_t<Arg>,
DiagonalAdapter>
236 template<
typename Arg,
typename S, std::enable_if_t<
237 std::is_same_v<std::decay_t<Arg>,
DiagonalAdapter> and std::is_convertible_v<S, const scalar_type_of_t<Arg>>>>
239 friend decltype(
auto) operator*(S s, Arg&& arg)
245 #ifdef __cpp_concepts 246 template<
typename Arg, std::convertible_to<const scalar_type_of_t<Arg>> S> requires std::same_as<std::decay_t<Arg>,
DiagonalAdapter>
248 template<
typename Arg,
typename S, std::enable_if_t<
249 std::is_same_v<std::decay_t<Arg>,
DiagonalAdapter> and std::is_convertible_v<S, const scalar_type_of_t<Arg>>>>
251 friend decltype(
auto) operator/(Arg&& arg, S s)
266 #ifdef __cpp_concepts 267 template<indexible Arg>
269 template<
typename Arg, std::enable_if_t<indexible<Arg>,
int> = 0>
280 template<
typename NestedObject>
286 template<
typename Arg>
287 static constexpr
auto count_indices(
const Arg& arg) {
return std::integral_constant<std::size_t, 2>{}; }
290 template<
typename Arg,
typename N>
293 return OpenKalman::get_vector_space_descriptor<0>(std::forward<Arg>(arg).
nested_object());
297 template<
typename Arg>
305 template<
typename Arg>
306 static constexpr
auto get_constant_diagonal(
const Arg& arg)
312 template<Applicability b>
313 static constexpr
bool one_dimensional = OpenKalman::one_dimensional<NestedObject, b>;
316 template<Applicability b>
317 static constexpr
bool is_square =
true;
320 template<TriangleType t>
321 static constexpr
bool is_triangular =
true;
324 static constexpr
bool is_writable =
false;
327 #ifdef __cpp_lib_concepts 328 template<
typename Arg> requires OpenKalman::one_dimensional<nested_object_of_t<Arg&>> and directly_accessible<nested_object_of_t<Arg&>>
330 template<typename Arg, std::enable_if_t<one_dimensional<typename nested_object_of<Arg&>::type> and
331 directly_accessible<typename nested_object_of<Arg&>::type>,
int> = 0>
333 static constexpr
auto *
const 334 raw_data(Arg& arg) {
return internal::raw_data(
nested_object(arg)); }
337 static constexpr
Layout layout = OpenKalman::one_dimensional<NestedObject> ? layout_of_v<NestedObject> :
Layout::none;
347 #endif //OPENKALMAN_DIAGONALADAPTER_HPP 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
constexpr NestedObject & nested_object() &
Get the nested object.
Definition: AdapterBase.hpp:97
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
No storage layout (e.g., if the elements are calculated rather than stored).
typename scalar_type_of< T >::type scalar_type_of_t
helper template for scalar_type_of.
Definition: scalar_type_of.hpp:54
constexpr bool value
T is numerical value or is reducible to a numerical value.
Definition: value.hpp:31
decltype(auto) constexpr to_diagonal(Arg &&arg)
Convert an indexible object into a diagonal matrix.
Definition: to_diagonal.hpp:32
Definition: AdapterBase.hpp:36
constexpr auto to_number(Arg arg)
Convert any values::value to a values::number.
Definition: to_number.hpp:34
The constant associated with T, assuming T is a constant_matrix.
Definition: constant_coefficient.hpp:36
The root namespace for OpenKalman.
Definition: basics.hpp:34
The constant associated with T, assuming T is a constant_diagonal_matrix.
Definition: constant_diagonal_coefficient.hpp:32
constexpr bool vector_space_descriptors_match(const Ts &...ts)
Return true if every set of coordinates::pattern of a set of objects match.
Definition: vector_space_descriptors_match.hpp:62
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
constexpr auto & operator=(Arg &&arg)
Assign from another diagonal_matrix.
Definition: DiagonalAdapter.hpp:109
Layout
The layout format of a multidimensional array.
Definition: global-definitions.hpp:47
constexpr DiagonalAdapter()
Default constructor.
Definition: DiagonalAdapter.hpp:62
constexpr bool fixed
T is a values::value that is determinable at compile time.
Definition: fixed.hpp:60
constexpr DiagonalAdapter(Arg &&arg)
Construct from a vector, matrix, or other tensor reflecting the diagonal.
Definition: DiagonalAdapter.hpp:77
An adapter for creating a diagonal matrix or tensor.
Definition: DiagonalAdapter.hpp:27
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