11 #ifndef OPENKALMAN_MATRIX_HPP 12 #define OPENKALMAN_MATRIX_HPP 23 template<fixed_pattern RowCoefficients, fixed_pattern ColumnCoefficients, typed_matrix_nestable NestedMatrix>
24 requires (coordinates::dimension_of_v<RowCoefficients> == index_dimension_of_v<NestedMatrix, 0>) and
25 (coordinates::dimension_of_v<ColumnCoefficients> == index_dimension_of_v<NestedMatrix, 1>) and
26 (not std::is_rvalue_reference_v<NestedMatrix>) and
27 (dynamic_pattern<RowCoefficients> == dynamic_dimension<NestedMatrix, 0>) and
28 (dynamic_pattern<ColumnCoefficients> == dynamic_dimension<NestedMatrix, 1>)
30 template<
typename RowCoefficients,
typename ColumnCoefficients,
typename NestedMatrix>
32 struct Matrix : oin::TypedMatrixBase<Matrix<RowCoefficients, ColumnCoefficients, NestedMatrix>, NestedMatrix,
33 RowCoefficients, ColumnCoefficients>
36 #ifndef __cpp_concepts 37 static_assert(fixed_pattern<RowCoefficients>);
38 static_assert(fixed_pattern<ColumnCoefficients>);
39 static_assert(typed_matrix_nestable<NestedMatrix>);
40 static_assert(coordinates::dimension_of_v<RowCoefficients> == index_dimension_of_v<NestedMatrix, 0>);
41 static_assert(coordinates::dimension_of_v<ColumnCoefficients> == index_dimension_of_v<NestedMatrix, 1>);
42 static_assert(not std::is_rvalue_reference_v<NestedMatrix>);
43 static_assert(dynamic_pattern<RowCoefficients> == dynamic_dimension<NestedMatrix, 0>);
44 static_assert(dynamic_pattern<ColumnCoefficients> == dynamic_dimension<NestedMatrix, 1>);
51 using Base = oin::TypedMatrixBase<Matrix, NestedMatrix, RowCoefficients, ColumnCoefficients>;
60 template<typed_matrix Arg> requires (not std::derived_from<std::decay_t<Arg>,
Matrix>) and
67 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and not std::is_base_of_v<Matrix, std::decay_t<Arg>> and
68 not eucl
idean_transformed<Arg> and
69 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
70 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
71 std::is_constructible_v<NestedMatrix, decltype(nested_
object(std::declval<Arg&&>()))>,
int> = 0>
78 template<eucl
idean_transformed Arg> requires
79 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
80 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
81 requires(Arg&& arg) { NestedMatrix {from_euclidean<RowCoefficients>(
nested_object(std::forward<Arg>(arg)))}; }
83 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and eucl
idean_transformed<Arg> and
84 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
85 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
86 std::is_constructible_v<NestedMatrix,
87 decltype(from_eucl
idean<RowCoefficients>(nested_
object(std::declval<Arg&&>())))>,
int> = 0>
90 : Base {from_euclidean<RowCoefficients>(
nested_object(std::forward<Arg>(arg)))} {}
95 template<typed_matrix_nestable Arg> requires (index_dimension_of_v<Arg, 0> == index_dimension_of_v<NestedMatrix, 0>) and
96 (index_dimension_of_v<Arg, 1> == index_dimension_of_v<NestedMatrix, 1>) and
97 std::constructible_from<NestedMatrix, Arg&&>
99 template<
typename Arg, std::enable_if_t<typed_matrix_nestable<Arg> and
100 (index_dimension_of<Arg, 0>::value == index_dimension_of<NestedMatrix, 0>::value) and
101 (index_dimension_of<Arg, 1>::value == index_dimension_of<NestedMatrix, 1>::value) and
102 std::is_constructible_v<NestedMatrix, Arg&&>,
int> = 0>
104 explicit Matrix(Arg&& arg) : Base {std::forward<Arg>(arg)} {}
108 #ifdef __cpp_concepts 109 template<covariance Arg> requires
110 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
111 compares_with<vector_space_descriptor_of_t<Arg, 0>, ColumnCoefficients> and
112 requires(Arg&& arg) { NestedMatrix {
to_dense_object(std::forward<Arg>(arg))}; }
114 template<
typename Arg, std::enable_if_t<covariance<Arg> and
115 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
116 compares_with<vector_space_descriptor_of_t<Arg, 0>, ColumnCoefficients> and
117 std::is_constructible_v<NestedMatrix, dense_writable_matrix_t<Arg>>,
int> = 0>
123 #ifdef __cpp_concepts 124 template<typed_matrix Arg> requires (not euclidean_transformed<Arg>) and
125 (not std::derived_from<std::decay_t<Arg>,
Matrix>) and
126 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
127 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
130 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and (not eucl
idean_transformed<Arg>) and
131 (not std::is_base_of_v<Matrix, std::decay_t<Arg>>) and
132 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
133 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
134 std::is_assignable_v<std::add_lvalue_reference_t<NestedMatrix>, nested_
object_of_t<Arg&&>>,
int> = 0>
138 if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
147 #ifdef __cpp_concepts 148 template<eucl
idean_transformed Arg> requires
149 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
150 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
151 std::assignable_from<std::add_lvalue_reference_t<NestedMatrix>, decltype(from_euclidean<RowCoefficients>(std::declval<
nested_object_of_t<Arg>>()))>
153 template<
typename Arg, std::enable_if_t<eucl
idean_transformed<Arg> and
154 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
155 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
156 std::is_assignable_v<std::add_lvalue_reference_t<NestedMatrix>, decltype(from_eucl
idean<RowCoefficients>(std::declval<nested_
object_of_t<Arg>>()))>,
161 if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
163 Base::operator=(from_euclidean<RowCoefficients>(
nested_object(std::forward<Arg>(other))));
170 #ifdef __cpp_concepts 171 template<typed_matrix_nestable Arg> requires std::assignable_from<std::add_lvalue_reference_t<NestedMatrix>, Arg&&>
173 template<
typename Arg, std::enable_if_t<typed_matrix_nestable<Arg> and
174 std::is_assignable_v<std::add_lvalue_reference_t<NestedMatrix>, Arg&&>,
int> = 0>
178 if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
180 Base::operator=(std::forward<Arg>(arg));
194 #ifdef __cpp_concepts 195 template<typed_matrix Arg> requires
196 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
197 coordinates::compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients>
199 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and
200 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients>and
201 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients>,
int> = 0>
211 #ifdef __cpp_concepts 212 template<distribution Arg> requires (coordinates::euclidean_pattern<ColumnCoefficients>) and
213 (compares_with<
typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>)
215 template<
typename Arg, std::enable_if_t<distribution<Arg> and (coordinates::eucl
idean_pattern<ColumnCoefficients>) and
216 (compares_with<
typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>),
int> = 0>
220 apply_columnwise([&arg](
auto& col) { col += arg().nested_object(); }, this->
nested_object());
234 #ifdef __cpp_concepts 235 template<typed_matrix Arg> requires
236 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients>and
237 coordinates::compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients>
239 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and
240 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients>and
241 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients>,
int> = 0>
251 #ifdef __cpp_concepts 252 template<distribution Arg> requires (coordinates::euclidean_pattern<ColumnCoefficients>) and
253 (compares_with<
typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>)
255 template<
typename Arg, std::enable_if_t<distribution<Arg> and (coordinates::eucl
idean_pattern<ColumnCoefficients>) and
256 (compares_with<
typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>),
int> = 0>
260 apply_columnwise([&arg](
auto& col){ col -= arg().nested_object(); }, this->
nested_object());
266 template<
typename CR = RowCoefficients,
typename CC = ColumnCoefficients,
typename Arg>
267 static auto make(Arg&& arg)
280 #ifdef __cpp_concepts 281 template<typed_matrix_nestable M>
283 template<
typename M, std::enable_if_t<typed_matrix_nestable<M>,
int> = 0>
288 #ifdef __cpp_concepts 291 template<
typename M, std::enable_if_t<typed_matrix_nestable<M>,
int> = 0>
293 explicit Matrix(M&&,
const Cs&...) ->
Matrix<Cs..., passable_t<M>>;
297 #ifdef __cpp_concepts 298 template<typed_matrix V> requires (not euclidean_transformed<V>)
300 template<
typename V, std::enable_if_t<typed_matrix<V> and not eucl
idean_transformed<V>,
int> = 0>
305 passable_t<nested_object_of_t<V>>>;
309 #if defined(__cpp_concepts) and OPENKALMAN_CPP_FEATURE_CONCEPTS_2 311 template<eucl
idean_transformed V> requires has_untyped_index<V, 1>
313 template<
typename V, std::enable_if_t<eucl
idean_transformed<V> and has_untyped_index<V, 1>,
int> = 0>
316 vector_space_descriptor_of_t<V, 0>,
317 vector_space_descriptor_of_t<V, 1>,
323 #ifdef __cpp_concepts 324 template<covariance V>
326 template<
typename V, std::enable_if_t<covariance<V>,
int> = 0>
329 vector_space_descriptor_of_t<V, 0>,
330 vector_space_descriptor_of_t<V, 0>,
340 template<
typename RowCoeffs,
typename ColCoeffs,
typename NestedMatrix>
345 template<
typename Arg>
346 static constexpr
auto count_indices(
const Arg& arg) {
return std::tuple_size_v<decltype(arg.my_dimensions)>; }
348 template<
typename Arg,
typename N>
351 if constexpr (values::fixed<N>)
352 return std::get<N>(std::forward<Arg>(arg).my_dimensions);
353 else if constexpr (compares_with<RowCoeffs, ColCoeffs>)
354 return std::get<0>(std::forward<Arg>(arg).my_dimensions);
357 [](
const auto&...ds, N n){
return std::array {DynamicDescriptor<scalar_type>{ds}...}[n]; },
358 arg.my_dimensions, n);
362 template<
typename Arg>
369 template<
typename Arg>
370 static constexpr
auto get_constant(
const Arg& arg)
376 template<
typename Arg>
377 static constexpr
auto get_constant_diagonal(
const Arg& arg)
379 if constexpr (coordinates::euclidean_pattern<RowCoeffs> and coordinates::euclidean_pattern<ColCoeffs>)
382 return std::monostate {};
386 template<Applicability b>
387 static constexpr
bool one_dimensional = OpenKalman::one_dimensional<NestedMatrix, b>;
390 template<Applicability b>
391 static constexpr
bool is_square = OpenKalman::square_shaped<NestedMatrix, b>;
394 template<TriangleType t>
395 static constexpr
bool is_triangular = compares_with<RowCoeffs, ColCoeffs>and triangular_matrix<NestedMatrix, t>;
398 static constexpr
bool is_triangular_adapter =
false;
401 static constexpr
bool is_hermitian = compares_with<RowCoeffs, ColCoeffs>and hermitian_matrix<NestedMatrix>;
404 #ifdef __cpp_lib_concepts 405 template<
typename Arg,
typename...I> requires element_gettable<nested_object_of_t<Arg&&>,
sizeof...(I)>
409 static constexpr decltype(
auto)
get(Arg&& arg, I...i)
415 #ifdef __cpp_lib_concepts 416 template<
typename Arg,
typename I,
typename...Is> requires writable_by_component<nested_object_of_t<Arg&>, 1 +
sizeof...(Is)>
429 #ifdef __cpp_lib_concepts 430 template<
typename Arg> requires raw_data_defined_for<NestedMatrix>
432 template<
typename Arg, std::enable_if_t<raw_data_defined_for<NestedMatrix>,
int> = 0>
434 static constexpr
auto *
const 435 raw_data(Arg& arg) {
return internal::raw_data(
nested_object(arg)); }
438 static constexpr
Layout layout = layout_of_v<NestedMatrix>;
447 #endif //OPENKALMAN_MATRIX_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
decltype(auto) constexpr from_euclidean(Arg &&arg, const V &v)
Project the Euclidean vector space associated with index 0 to coordinates::pattern v after applying d...
Definition: from_euclidean.hpp:35
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
auto & operator+=(Arg &&other)
Increment from another typed matrix.
Definition: Matrix.hpp:203
Matrix(Arg &&arg)
Construct from a compatible typed_matrix.
Definition: Matrix.hpp:73
Definition: indexible_object_traits.hpp:36
auto & operator-=(Arg &&other)
Decrement from another typed matrix.
Definition: Matrix.hpp:243
constexpr bool euclidean_transformed
Specifies that T is a Euclidean mean that actually has coefficients that are transformed to Euclidean...
Definition: object-types.hpp:87
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
auto & operator+=(const Arg &arg)
Add a stochastic value to each column of the matrix, based on a distribution.
Definition: Matrix.hpp:218
typename scalar_type_of< T >::type scalar_type_of_t
helper template for scalar_type_of.
Definition: scalar_type_of.hpp:54
auto & operator+=(const Matrix &other)
Increment from another Matrix.
Definition: Matrix.hpp:187
auto & operator=(Arg &&arg)
Assign from a compatible typed_matrix_nestable.
Definition: Matrix.hpp:176
Definition: tuple_reverse.hpp:103
auto & operator-=(const Matrix &other)
Decrement from another Matrix.
Definition: Matrix.hpp:226
decltype(auto) constexpr to_dense_object(Arg &&arg)
Convert the argument to a dense, writable matrix of a particular scalar type.
Definition: to_dense_object.hpp:37
A wrapper type's nested object type, if it exists.
Definition: nested_object_of.hpp:33
The constant associated with T, assuming T is a constant_matrix.
Definition: constant_coefficient.hpp:36
Matrix(M &&) -> Matrix< Dimensions< index_dimension_of_v< M, 0 >>, Dimensions< index_dimension_of_v< M, 1 >>, passable_t< M >>
Deduce parameter types from a typed_matrix_nestable.
constexpr bool typed_matrix_nestable
Specifies a type that is nestable in a general typed matrix (e.g., matrix, mean, or euclidean_mean) ...
Definition: object-types.hpp:253
The root namespace for OpenKalman.
Definition: basics.hpp:34
scalar_type_of_t< CrossCovarianceMatrix > Scalar
Scalar type for this matrix.
Definition: Matrix.hpp:47
auto & operator-=(const Arg &arg)
Subtract a stochastic value to each column of the matrix, based on a distribution.
Definition: Matrix.hpp:258
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
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
Layout
The layout format of a multidimensional array.
Definition: global-definitions.hpp:47
constexpr bool element_gettable
Specifies that a type has components addressable by N indices.
Definition: element_gettable.hpp:33
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
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
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
A matrix with typed rows and columns.
Definition: forward-class-declarations.hpp:448
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
constexpr bool writable_by_component
Specifies that a type has components that can be set with Indices (an std::ranges::input_range) of ty...
Definition: writable_by_component.hpp:36
auto & operator=(Arg &&other)
Assign from a compatible typed_matrix.
Definition: Matrix.hpp:136