11 #ifndef OPENKALMAN_EUCLIDEANMEAN_HPP 12 #define OPENKALMAN_EUCLIDEANMEAN_HPP 23 template<fixed_pattern RowCoefficients, typed_matrix_nestable NestedMatrix> requires
24 (coordinates::stat_dimension_of_v<RowCoefficients> == index_dimension_of_v<NestedMatrix, 0>) and
25 (not std::is_rvalue_reference_v<NestedMatrix>)
27 template<
typename RowCoefficients,
typename NestedMatrix>
29 struct EuclideanMean : oin::TypedMatrixBase<EuclideanMean<RowCoefficients, NestedMatrix>, NestedMatrix,
30 RowCoefficients, Dimensions<index_dimension_of_v<NestedMatrix, 1>>>
33 #ifndef __cpp_concepts 34 static_assert(fixed_pattern<RowCoefficients>);
35 static_assert(typed_matrix_nestable<NestedMatrix>);
36 static_assert(coordinates::stat_dimension_of_v<RowCoefficients> == index_dimension_of_v<NestedMatrix, 0>);
37 static_assert(not std::is_rvalue_reference_v<NestedMatrix>);
44 using ColumnCoefficients = Dimensions<index_dimension_of_v<NestedMatrix, 1>>;
48 using Base = oin::TypedMatrixBase<EuclideanMean, NestedMatrix, RowCoefficients, ColumnCoefficients>;
57 template<eucl
idean_transformed Arg> requires
63 template<
typename Arg, std::enable_if_t<eucl
idean_transformed<Arg> 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
66 std::is_constructible_v<NestedMatrix, decltype(nested_
object(std::declval<Arg&&>()))>,
int> = 0>
73 template<typed_matrix Arg> requires (not euclidean_transformed<Arg>) and
76 requires(Arg&& arg) { NestedMatrix {to_euclidean<RowCoefficients>(
nested_object(std::forward<Arg>(arg)))}; }
78 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and (not eucl
idean_transformed<Arg>) and
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 std::is_constructible_v<NestedMatrix,
82 decltype(to_eucl
idean<RowCoefficients>(nested_
object(std::declval<Arg&&>())))>,
int> = 0>
85 : Base {to_euclidean<RowCoefficients>(
nested_object(std::forward<Arg>(arg)))} {}
90 template<typed_matrix_nestable Arg> requires (index_dimension_of_v<Arg, 0> == index_dimension_of_v<NestedMatrix, 0>) and
91 (index_dimension_of_v<Arg, 1> == index_dimension_of_v<NestedMatrix, 1>) and
92 std::constructible_from<NestedMatrix, Arg&&>
94 template<
typename Arg, std::enable_if_t<typed_matrix_nestable<Arg> and
95 (index_dimension_of<Arg, 0>::value == index_dimension_of<NestedMatrix, 0>::value) and
96 (index_dimension_of<Arg, 1>::value == index_dimension_of<NestedMatrix, 1>::value) and
97 std::is_constructible_v<NestedMatrix, Arg&&>,
int> = 0>
106 #ifdef __cpp_concepts 107 template<typed_matrix Arg> requires (not std::derived_from<std::decay_t<Arg>,
EuclideanMean>) and
108 (euclidean_transformed<Arg> or coordinates::euclidean_pattern<RowCoefficients>) and
109 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
112 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and
113 (not std::is_base_of_v<Eucl
ideanMean, std::decay_t<Arg>>) and
114 (eucl
idean_transformed<Arg> or coordinates::eucl
idean_pattern<RowCoefficients>) and
115 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
116 has_untyped_index<Arg, 1> and std::is_assignable_v<std::add_lvalue_reference_t<NestedMatrix>, nested_
object_of_t<Arg&&>>,
int> = 0>
120 if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
132 #ifdef __cpp_concepts 133 template<typed_matrix Arg> requires (not std::derived_from<std::decay_t<Arg>,
EuclideanMean>) and
134 (not euclidean_transformed<Arg> and fixed_pattern<RowCoefficients>) and
135 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
138 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and
139 (not std::is_base_of_v<Eucl
ideanMean, std::decay_t<Arg>>) and
140 (not eucl
idean_transformed<Arg> and fixed_pattern<RowCoefficients>) and
141 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
142 has_untyped_index<Arg, 1> and std::is_assignable_v<std::add_lvalue_reference_t<NestedMatrix>, nested_
object_of_t<Arg&&>>,
int> = 0>
146 if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
148 Base::operator=(to_euclidean<RowCoefficients>(
nested_object(std::forward<Arg>(other))));
157 #ifdef __cpp_concepts 158 template<typed_matrix_nestable Arg> requires std::assignable_from<std::add_lvalue_reference_t<NestedMatrix>, Arg&&>
160 template<
typename Arg, std::enable_if_t<typed_matrix_nestable<Arg> and std::is_assignable_v<std::add_lvalue_reference_t<NestedMatrix>, Arg&&>,
int> = 0>
164 if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
166 Base::operator=(std::forward<Arg>(arg));
183 #ifdef __cpp_concepts 184 template<typed_matrix Arg> requires
185 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
186 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
187 (coordinates::euclidean_pattern<RowCoefficients> or euclidean_transformed<Arg>)
189 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and
190 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
191 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
192 (coordinates::eucl
idean_pattern<RowCoefficients> or eucl
idean_transformed<Arg>),
int> = 0>
202 #ifdef __cpp_concepts 203 template<distribution Arg> requires coordinates::euclidean_pattern<RowCoefficients> and
204 (compares_with<
typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>)
206 template<
typename Arg, std::enable_if_t<distribution<Arg> and coordinates::eucl
idean_pattern<RowCoefficients> and
207 (compares_with<
typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>),
int> = 0>
211 apply_columnwise([&arg](
auto& col){ col += arg().nested_object(); }, this->
nested_object());
225 #ifdef __cpp_concepts 226 template<typed_matrix Arg> requires
227 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
228 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
229 (coordinates::euclidean_pattern<RowCoefficients> or euclidean_transformed<Arg>)
231 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and
232 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients>and
233 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients>and
234 (coordinates::eucl
idean_pattern<RowCoefficients> or eucl
idean_transformed<Arg>),
int> = 0>
244 #ifdef __cpp_concepts 245 template<distribution Arg> requires coordinates::euclidean_pattern<RowCoefficients> and
246 (compares_with<
typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>)
248 template<
typename Arg, std::enable_if_t<distribution<Arg> and coordinates::eucl
idean_pattern<RowCoefficients> and
249 (compares_with<
typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>),
int> = 0>
253 apply_columnwise([&arg](
auto& col){ col -= arg().nested_object(); }, this->
nested_object());
259 template<
typename C = RowCoefficients,
typename Arg>
260 static auto make(Arg&& arg)
273 #if defined(__cpp_concepts) and OPENKALMAN_CPP_FEATURE_CONCEPTS_2 275 template<typed_matrix V> requires (not euclidean_transformed<V>) and has_untyped_index<V, 1> and
278 template<
typename V, std::enable_if_t<typed_matrix<V> and not eucl
idean_transformed<V> and has_untyped_index<V, 1> and
279 coordinates::stat_dimension_of_v<vector_space_descriptor_of_t<V, 0>> == index_dimension_of_v<V, 0>,
int> = 0>
287 #ifdef __cpp_concepts 288 template<eucl
idean_transformed V>
290 template<
typename V, std::enable_if_t<typed_matrix<V> and eucl
idean_transformed<V>,
int> = 0>
296 #ifdef __cpp_concepts 297 template<typed_matrix_nestable V>
299 template<
typename V, std::enable_if_t<typed_matrix_nestable<V>,
int> = 0>
313 #ifdef __cpp_concepts 314 template<fixed_pattern StaticDescriptor, typed_matrix_nestable M> requires
315 (coordinates::stat_dimension_of_v<StaticDescriptor> == index_dimension_of_v<M, 0>)
317 template<
typename StaticDescriptor,
typename M, std::enable_if_t<fixed_pattern<StaticDescriptor> and
318 typed_matrix_nestable<M> and (coordinates::stat_dimension_of_v<StaticDescriptor> == index_dimension_of<M, 0>::value),
int> = 0>
330 #ifdef __cpp_concepts 331 template<typed_matrix_nestable M>
333 template<
typename M, std::enable_if_t<typed_matrix_nestable<M>,
int> = 0>
337 using Coeffs = Dimensions<index_dimension_of_v<M, 0>>;
338 return make_mean<Coeffs>(std::forward<M>(m));
347 #ifdef __cpp_concepts 348 template<typed_matrix Arg> requires has_untyped_index<Arg, 1>
350 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and has_untyped_index<Arg, 1>,
int> = 0>
355 if constexpr(euclidean_transformed<Arg>)
356 return make_euclidean_mean<C>(
nested_object(std::forward<Arg>(arg)));
358 return make_euclidean_mean<C>(
nested_object(to_euclidean<C>(std::forward<Arg>(arg))));
369 #ifdef __cpp_concepts 370 template<fixed_pattern StaticDescriptor, typed_matrix_nestable M> requires
371 (coordinates::stat_dimension_of_v<StaticDescriptor> == index_dimension_of_v<M, 0>)
373 template<
typename StaticDescriptor,
typename M, std::enable_if_t<fixed_pattern<StaticDescriptor> and
374 typed_matrix_nestable<M> and (coordinates::stat_dimension_of_v<StaticDescriptor> == index_dimension_of<M, 0>::value),
int> = 0>
388 #ifdef __cpp_concepts 389 template<typed_matrix_nestable M>
391 template<
typename M, std::enable_if_t<typed_matrix_nestable<M>,
int> = 0>
395 return make_euclidean_mean<Dimensions<index_dimension_of_v<M, 0>>, M>();
405 template<
typename Coeffs,
typename NestedMatrix>
410 template<
typename Arg>
413 template<
typename Arg,
typename N>
416 if constexpr (values::fixed<N>)
418 if constexpr (n == 0_uz)
return arg.my_dimension;
421 else if constexpr (uniform_static_vector_space_descriptor<NestedMatrix> and compares_with<Coeffs, uniform_static_vector_space_descriptor_component_of<NestedMatrix>>)
423 return arg.my_dimension;
427 if (n == 0)
return DynamicDescriptor<scalar_type> {arg.my_dimension};
433 template<
typename Arg>
440 template<
typename Arg>
441 static constexpr
auto get_constant(
const Arg& arg)
443 if constexpr (coordinates::euclidean_pattern<Coeffs>)
446 return std::monostate {};
450 template<
typename Arg>
451 static constexpr
auto get_constant_diagonal(
const Arg& arg)
453 if constexpr (coordinates::euclidean_pattern<Coeffs>)
456 return std::monostate {};
460 template<Applicability b>
461 static constexpr
bool one_dimensional = OpenKalman::one_dimensional<NestedMatrix, b>;
464 template<Applicability b>
465 static constexpr
bool is_square = OpenKalman::square_shaped<NestedMatrix, b>;
468 template<TriangleType t>
469 static constexpr
bool is_triangular = coordinates::euclidean_pattern<Coeffs> and triangular_matrix<NestedMatrix, t>;
472 static constexpr
bool is_triangular_adapter =
false;
475 static constexpr
bool is_hermitian = coordinates::euclidean_pattern<Coeffs> and hermitian_matrix<NestedMatrix>;
478 #ifdef __cpp_lib_concepts 479 template<
typename Arg,
typename...I> requires element_gettable<nested_object_of_t<Arg&&>,
sizeof...(I)>
483 static constexpr decltype(
auto)
484 get(Arg&& arg, I...i)
490 #ifdef __cpp_lib_concepts 491 template<
typename Arg,
typename I,
typename...Is> requires writable_by_component<nested_object_of_t<Arg&>, 1 +
sizeof...(Is)>
495 static constexpr
void 505 #ifdef __cpp_lib_concepts 506 template<
typename Arg> requires raw_data_defined_for<NestedMatrix> and coordinates::euclidean_pattern<Coeffs>
508 template<
typename Arg, std::enable_if_t<raw_data_defined_for<NestedMatrix> and coordinates::eucl
idean_pattern<Coeffs>,
int> = 0>
510 static constexpr
auto *
const 514 static constexpr
Layout layout = coordinates::euclidean_pattern<Coeffs> ? layout_of_v<NestedMatrix> :
Layout::none;
524 #endif //OPENKALMAN_EUCLIDEANMEAN_HPP EuclideanMean(Arg &&arg)
Construct from a compatible Euclidean-transformed matrix.
Definition: EuclideanMean.hpp:68
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
Definition: indexible_object_traits.hpp:36
auto & operator+=(Arg &&other)
Increment from another typed matrix.
Definition: EuclideanMean.hpp:194
No storage layout (e.g., if the elements are calculated rather than stored).
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
typename scalar_type_of< T >::type scalar_type_of_t
helper template for scalar_type_of.
Definition: scalar_type_of.hpp:54
scalar_type_of_t< OutputEuclideanMeanMatrix > Scalar
Scalar type for this matrix.
Definition: EuclideanMean.hpp:40
auto & operator-=(const EuclideanMean &other)
Decrement from another EuclideanMean.
Definition: EuclideanMean.hpp:217
Definition: tuple_reverse.hpp:103
auto & operator=(Arg &&arg)
Assign from a compatible typed_matrix_nestable.
Definition: EuclideanMean.hpp:162
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
auto & operator-=(Arg &&other)
Decrement from another typed matrix.
Definition: EuclideanMean.hpp:236
Similar to a Mean, but the coefficients are transformed into Euclidean space, based on their type...
Definition: EuclideanMean.hpp:29
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
auto make_euclidean_mean(M &&arg)
Make a EuclideanMean from a typed_matrix_nestable, specifying the row coefficients.
Definition: EuclideanMean.hpp:320
The constant associated with T, assuming T is a constant_diagonal_matrix.
Definition: constant_diagonal_coefficient.hpp:32
decltype(auto) constexpr to_euclidean(Arg &&arg)
Project the vector space associated with index 0 to a Euclidean space for applying directional statis...
Definition: to_euclidean.hpp:38
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
auto & operator-=(const Arg &arg)
Subtract a stochastic value to each column of the matrix, based on a distribution.
Definition: EuclideanMean.hpp:251
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
auto & operator=(Arg &&other)
Assign from a compatible typed_matrix.
Definition: EuclideanMean.hpp:118
auto & operator+=(const EuclideanMean &other)
Increment from another EuclideanMean.
Definition: EuclideanMean.hpp:175
Definition: basics.hpp:48
auto & operator+=(const Arg &arg)
Add a stochastic value to each column of the matrix, based on a distribution.
Definition: EuclideanMean.hpp:209
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