11 #ifndef OPENKALMAN_MATRIX_HPP 12 #define OPENKALMAN_MATRIX_HPP 25 template<fixed_pattern RowCoefficients, fixed_pattern ColumnCoefficients, typed_matrix_nestable NestedMatrix>
26 requires (coordinates::dimension_of_v<RowCoefficients> == index_dimension_of_v<NestedMatrix, 0>) and
27 (coordinates::dimension_of_v<ColumnCoefficients> == index_dimension_of_v<NestedMatrix, 1>) and
28 (not std::is_rvalue_reference_v<NestedMatrix>) and
29 (dynamic_pattern<RowCoefficients> == dynamic_dimension<NestedMatrix, 0>) and
30 (dynamic_pattern<ColumnCoefficients> == dynamic_dimension<NestedMatrix, 1>)
32 template<
typename RowCoefficients,
typename ColumnCoefficients,
typename NestedMatrix>
34 struct Matrix : oin::TypedMatrixBase<Matrix<RowCoefficients, ColumnCoefficients, NestedMatrix>, NestedMatrix,
35 RowCoefficients, ColumnCoefficients>
38 #ifndef __cpp_concepts 39 static_assert(fixed_pattern<RowCoefficients>);
40 static_assert(fixed_pattern<ColumnCoefficients>);
41 static_assert(typed_matrix_nestable<NestedMatrix>);
42 static_assert(coordinates::dimension_of_v<RowCoefficients> == index_dimension_of_v<NestedMatrix, 0>);
43 static_assert(coordinates::dimension_of_v<ColumnCoefficients> == index_dimension_of_v<NestedMatrix, 1>);
44 static_assert(not std::is_rvalue_reference_v<NestedMatrix>);
45 static_assert(dynamic_pattern<RowCoefficients> == dynamic_dimension<NestedMatrix, 0>);
46 static_assert(dynamic_pattern<ColumnCoefficients> == dynamic_dimension<NestedMatrix, 1>);
49 using Scalar = scalar_type_of_t<NestedMatrix>;
53 using Base = oin::TypedMatrixBase<Matrix, NestedMatrix, RowCoefficients, ColumnCoefficients>;
62 template<typed_matrix Arg> requires (not std::derived_from<std::decay_t<Arg>,
Matrix>) and
64 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
65 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
69 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and not std::is_base_of_v<Matrix, std::decay_t<Arg>> and
70 not eucl
idean_transformed<Arg> and
71 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
72 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
73 stdex::constructible_from<NestedMatrix, decltype(nested_
object(std::declval<Arg&&>()))>,
int> = 0>
80 template<eucl
idean_transformed Arg> requires
81 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
82 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
83 requires(Arg&& arg) { NestedMatrix {from_euclidean<RowCoefficients>(
nested_object(std::forward<Arg>(arg)))}; }
85 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and eucl
idean_transformed<Arg> and
86 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
87 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
88 stdex::constructible_from<NestedMatrix,
89 decltype(from_eucl
idean<RowCoefficients>(nested_
object(std::declval<Arg&&>())))>,
int> = 0>
92 : Base {from_euclidean<RowCoefficients>(
nested_object(std::forward<Arg>(arg)))} {}
97 template<typed_matrix_nestable Arg> requires (index_dimension_of_v<Arg, 0> == index_dimension_of_v<NestedMatrix, 0>) and
98 (index_dimension_of_v<Arg, 1> == index_dimension_of_v<NestedMatrix, 1>) and
99 std::constructible_from<NestedMatrix, Arg&&>
101 template<
typename Arg, std::enable_if_t<typed_matrix_nestable<Arg> and
102 (index_dimension_of<Arg, 0>::value == index_dimension_of<NestedMatrix, 0>::value) and
103 (index_dimension_of<Arg, 1>::value == index_dimension_of<NestedMatrix, 1>::value) and
104 stdex::constructible_from<NestedMatrix, Arg&&>,
int> = 0>
106 explicit Matrix(Arg&& arg) : Base {std::forward<Arg>(arg)} {}
110 #ifdef __cpp_concepts 111 template<covariance Arg> requires
112 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
113 compares_with<vector_space_descriptor_of_t<Arg, 0>, ColumnCoefficients> and
114 requires(Arg&& arg) { NestedMatrix {
to_dense_object(std::forward<Arg>(arg))}; }
116 template<
typename Arg, std::enable_if_t<covariance<Arg> and
117 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
118 compares_with<vector_space_descriptor_of_t<Arg, 0>, ColumnCoefficients> and
119 stdex::constructible_from<NestedMatrix, dense_writable_matrix_t<Arg>>,
int> = 0>
125 #ifdef __cpp_concepts 126 template<typed_matrix Arg> requires (not euclidean_transformed<Arg>) and
127 (not std::derived_from<std::decay_t<Arg>,
Matrix>) and
128 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
129 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
132 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and (not eucl
idean_transformed<Arg>) and
133 (not std::is_base_of_v<Matrix, std::decay_t<Arg>>) and
134 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
135 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
136 std::is_assignable_v<std::add_lvalue_reference_t<NestedMatrix>, nested_
object_of_t<Arg&&>>,
int> = 0>
140 if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
149 #ifdef __cpp_concepts 150 template<eucl
idean_transformed Arg> requires
151 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
152 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
153 std::assignable_from<std::add_lvalue_reference_t<NestedMatrix>, decltype(from_euclidean<RowCoefficients>(std::declval<
nested_object_of_t<Arg>>()))>
155 template<
typename Arg, std::enable_if_t<eucl
idean_transformed<Arg> and
156 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
157 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
158 std::is_assignable_v<std::add_lvalue_reference_t<NestedMatrix>, decltype(from_eucl
idean<RowCoefficients>(std::declval<nested_
object_of_t<Arg>>()))>,
163 if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
165 Base::operator=(from_euclidean<RowCoefficients>(
nested_object(std::forward<Arg>(other))));
172 #ifdef __cpp_concepts 173 template<typed_matrix_nestable Arg> requires std::assignable_from<std::add_lvalue_reference_t<NestedMatrix>, Arg&&>
175 template<
typename Arg, std::enable_if_t<typed_matrix_nestable<Arg> and
176 std::is_assignable_v<std::add_lvalue_reference_t<NestedMatrix>, Arg&&>,
int> = 0>
180 if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
182 Base::operator=(std::forward<Arg>(arg));
196 #ifdef __cpp_concepts 197 template<typed_matrix Arg> requires
198 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
199 coordinates::compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients>
201 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and
202 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients>and
203 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients>,
int> = 0>
213 #ifdef __cpp_concepts 214 template<distribution Arg> requires (coordinates::euclidean_pattern<ColumnCoefficients>) and
215 (
compares_with<
typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>)
217 template<
typename Arg, std::enable_if_t<distribution<Arg> and (coordinates::eucl
idean_pattern<ColumnCoefficients>) and
218 (compares_with<
typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>),
int> = 0>
222 apply_columnwise([&arg](
auto& col) { col += arg().nested_object(); }, this->
nested_object());
236 #ifdef __cpp_concepts 237 template<typed_matrix Arg> requires
238 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients>and
239 coordinates::compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients>
241 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and
242 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients>and
243 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients>,
int> = 0>
253 #ifdef __cpp_concepts 254 template<distribution Arg> requires (coordinates::euclidean_pattern<ColumnCoefficients>) and
255 (
compares_with<
typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>)
257 template<
typename Arg, std::enable_if_t<distribution<Arg> and (coordinates::eucl
idean_pattern<ColumnCoefficients>) and
258 (compares_with<
typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>),
int> = 0>
262 apply_columnwise([&arg](
auto& col){ col -= arg().nested_object(); }, this->
nested_object());
268 template<
typename CR = RowCoefficients,
typename CC = ColumnCoefficients,
typename Arg>
269 static auto make(Arg&& arg)
282 #ifdef __cpp_concepts 283 template<typed_matrix_nestable M>
285 template<
typename M, std::enable_if_t<typed_matrix_nestable<M>,
int> = 0>
290 #ifdef __cpp_concepts 293 template<
typename M, std::enable_if_t<typed_matrix_nestable<M>,
int> = 0>
295 explicit Matrix(M&&,
const Cs&...) ->
Matrix<Cs..., passable_t<M>>;
299 #ifdef __cpp_concepts 300 template<typed_matrix V> requires (not euclidean_transformed<V>)
302 template<
typename V, std::enable_if_t<typed_matrix<V> and not eucl
idean_transformed<V>,
int> = 0>
305 vector_space_descriptor_of_t<V, 0>,
306 vector_space_descriptor_of_t<V, 1>,
307 passable_t<nested_object_of_t<V>>>;
311 #if defined(__cpp_concepts) and OPENKALMAN_CPP_FEATURE_CONCEPTS_2 313 template<eucl
idean_transformed V> requires has_untyped_index<V, 1>
315 template<
typename V, std::enable_if_t<eucl
idean_transformed<V> and has_untyped_index<V, 1>,
int> = 0>
318 vector_space_descriptor_of_t<V, 0>,
319 vector_space_descriptor_of_t<V, 1>,
325 #ifdef __cpp_concepts 326 template<covariance V>
328 template<
typename V, std::enable_if_t<covariance<V>,
int> = 0>
331 vector_space_descriptor_of_t<V, 0>,
332 vector_space_descriptor_of_t<V, 0>,
342 template<
typename RowCoeffs,
typename ColCoeffs,
typename NestedMatrix>
345 using scalar_type = scalar_type_of_t<NestedMatrix>;
347 template<
typename Arg>
350 template<
typename Arg,
typename N>
353 if constexpr (values::fixed<N>)
354 return std::get<N>(std::forward<Arg>(arg).my_dimensions);
355 else if constexpr (compares_with<RowCoeffs, ColCoeffs>)
356 return std::get<0>(std::forward<Arg>(arg).my_dimensions);
359 [](
const auto&...ds, N n){
return std::array {DynamicDescriptor<scalar_type>{ds}...}[n]; },
360 arg.my_dimensions, n);
364 template<
typename Arg>
371 template<
typename Arg>
372 static constexpr
auto get_constant(
const Arg& arg)
378 template<
typename Arg>
379 static constexpr
auto get_constant_diagonal(
const Arg& arg)
381 if constexpr (coordinates::euclidean_pattern<RowCoeffs> and coordinates::euclidean_pattern<ColCoeffs>)
382 return constant_diagonal_value {arg.nestedExpression()};
384 return std::monostate {};
388 template<applicability b>
389 static constexpr
bool one_dimensional = OpenKalman::one_dimensional<NestedMatrix, b>;
392 template<applicability b>
393 static constexpr
bool is_square = OpenKalman::square_shaped<NestedMatrix, b>;
396 template<triangle_type t>
397 static constexpr
bool triangle_type_value = compares_with<RowCoeffs, ColCoeffs>and triangular_matrix<NestedMatrix, t>;
400 static constexpr
bool is_triangular_adapter =
false;
403 static constexpr
bool is_hermitian = compares_with<RowCoeffs, ColCoeffs>and hermitian_matrix<NestedMatrix>;
406 #ifdef __cpp_lib_concepts 407 template<
typename Arg,
typename...I> requires element_gettable<nested_object_of_t<Arg&&>,
sizeof...(I)>
411 static constexpr decltype(
auto)
get(Arg&& arg, I...i)
417 #ifdef __cpp_lib_concepts 418 template<
typename Arg,
typename I,
typename...Is> requires writable_by_component<nested_object_of_t<Arg&>, 1 +
sizeof...(Is)>
420 template<
typename Arg,
typename I,
typename...Is, std::enable_if_t<writable_by_component<
typename nested_object_of<Arg&>::type, 1 +
sizeof...(Is)>,
int> = 0>
422 static constexpr
void set(Arg& arg,
const scalar_type_of_t<Arg>& s, I i, Is...is)
431 #ifdef __cpp_lib_concepts 432 template<
typename Arg> requires raw_data_defined_for<NestedMatrix>
434 template<
typename Arg, std::enable_if_t<raw_data_defined_for<NestedMatrix>,
int> = 0>
436 static constexpr
auto *
const 437 raw_data(Arg& arg) {
return internal::raw_data(
nested_object(arg)); }
440 static constexpr data_layout layout = layout_of_v<NestedMatrix>;
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:58
constexpr bool one_dimensional
Specifies that a type is one-dimensional in every index.
Definition: one_dimensional.hpp:56
auto & operator+=(Arg &&other)
Increment from another typed matrix.
Definition: Matrix.hpp:205
Matrix(Arg &&arg)
Construct from a compatible typed_matrix.
Definition: Matrix.hpp:75
auto & operator-=(Arg &&other)
Decrement from another typed matrix.
Definition: Matrix.hpp:245
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
auto & operator+=(const Arg &arg)
Add a stochastic value to each column of the matrix, based on a distribution.
Definition: Matrix.hpp:220
auto & operator+=(const Matrix &other)
Increment from another Matrix.
Definition: Matrix.hpp:189
constexpr auto count_indices(const T &)
Get the number of indices necessary to address all the components of an indexible object...
Definition: count_indices.hpp:51
constexpr bool pattern
An object describing the set of coordinates associated with a tensor index.
Definition: pattern.hpp:31
auto & operator=(Arg &&arg)
Assign from a compatible typed_matrix_nestable.
Definition: Matrix.hpp:178
decltype(auto) constexpr get_pattern_collection(T &&t)
Get the coordinates::pattern_collection associated with indexible object T.
Definition: get_pattern_collection.hpp:59
auto & operator-=(const Matrix &other)
Decrement from another Matrix.
Definition: Matrix.hpp:228
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
decltype(auto) constexpr apply(F &&f, T &&t)
A generalization of std::apply.
Definition: apply.hpp:49
A wrapper type's nested object type, if it exists.
Definition: nested_object_of.hpp:34
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:49
auto & operator-=(const Arg &arg)
Subtract a stochastic value to each column of the matrix, based on a distribution.
Definition: Matrix.hpp:260
An interface to various routines from the linear algebra library associated with indexible object T...
Definition: library_interface.hpp:42
Definition: object_traits.hpp:38
constexpr auto constant_value(T &&t)
The constant value associated with a constant_object or constant_diagonal_object. ...
Definition: constant_value.hpp:37
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
Basic definitions for OpenKalman as a whole.
decltype(auto) constexpr nested_object(Arg &&arg)
Retrieve a nested object of Arg, if it exists.
Definition: nested_object.hpp:35
constexpr bool compares_with
Compares two coordinates::pattern objects.
Definition: compares_with.hpp:475
Definition: basics.hpp:48
A matrix with typed rows and columns.
Definition: forward-class-declarations.hpp:292
constexpr std::size_t size_of_v
Helper for collections::size_of.
Definition: size_of.hpp:60
auto & operator=(Arg &&other)
Assign from a compatible typed_matrix.
Definition: Matrix.hpp:138