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>);
40 using Scalar = scalar_type_of_t<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
58 (
compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients>) and
59 (
compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients>) and
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 stdex::constructible_from<NestedMatrix, decltype(nested_
object(std::declval<Arg&&>()))>,
int> = 0>
73 template<typed_matrix Arg> requires (not euclidean_transformed<Arg>) and
74 (
compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients>) and
75 (
compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients>) 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 stdex::constructible_from<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 stdex::constructible_from<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>
354 using C = vector_space_descriptor_of_t<Arg, 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>
408 static const bool is_specialized =
true;
410 using scalar_type = scalar_type_of_t<NestedMatrix>;
412 template<
typename Arg>
415 template<
typename Arg,
typename N>
418 if constexpr (values::fixed<N>)
420 if constexpr (n == 0_uz)
return arg.my_dimension;
423 else if constexpr (coordinates::uniform_pattern<Coeffs>)
425 return coordinates::uniform_pattern_component_of_t<Coeffs>;
429 if (n == 0)
return DynamicDescriptor<scalar_type> {arg.my_dimension};
435 template<
typename Arg>
442 template<
typename Arg>
443 static constexpr
auto get_constant(
const Arg& arg)
445 if constexpr (coordinates::euclidean_pattern<Coeffs>)
448 return std::monostate {};
452 template<
typename Arg>
453 static constexpr
auto get_constant_diagonal(
const Arg& arg)
455 if constexpr (coordinates::euclidean_pattern<Coeffs>)
456 return constant_diagonal_value {arg.nestedExpression()};
458 return std::monostate {};
462 template<applicability b>
463 static constexpr
bool one_dimensional = OpenKalman::one_dimensional<NestedMatrix, b>;
466 template<applicability b>
467 static constexpr
bool is_square = OpenKalman::square_shaped<NestedMatrix, b>;
470 template<triangle_type t>
471 static constexpr
bool triangle_type_value = coordinates::euclidean_pattern<Coeffs> and triangular_matrix<NestedMatrix, t>;
474 static constexpr
bool is_triangular_adapter =
false;
477 static constexpr
bool is_hermitian = coordinates::euclidean_pattern<Coeffs> and hermitian_matrix<NestedMatrix>;
480 #ifdef __cpp_lib_concepts 481 template<
typename Arg,
typename...I> requires element_gettable<nested_object_of_t<Arg&&>,
sizeof...(I)>
485 static constexpr decltype(
auto)
486 get(Arg&& arg, I...i)
492 #ifdef __cpp_lib_concepts 493 template<
typename Arg,
typename I,
typename...Is> requires writable_by_component<nested_object_of_t<Arg&>, 1 +
sizeof...(Is)>
495 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>
497 static constexpr
void 498 set(Arg& arg,
const scalar_type_of_t<Arg>& s, I i, Is...is)
507 #ifdef __cpp_lib_concepts 508 template<
typename Arg> requires raw_data_defined_for<NestedMatrix> and coordinates::euclidean_pattern<Coeffs>
510 template<
typename Arg, std::enable_if_t<raw_data_defined_for<NestedMatrix> and coordinates::eucl
idean_pattern<Coeffs>,
int> = 0>
512 static constexpr
auto *
const 516 static constexpr data_layout layout = coordinates::euclidean_pattern<Coeffs> ? layout_of_v<NestedMatrix> :
data_layout::none;
EuclideanMean(Arg &&arg)
Construct from a compatible Euclidean-transformed matrix.
Definition: EuclideanMean.hpp:68
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: EuclideanMean.hpp:194
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
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
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=(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:34
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:42
auto make_euclidean_mean(M &&arg)
Make a EuclideanMean from a typed_matrix_nestable, specifying the row coefficients.
Definition: EuclideanMean.hpp:320
Definition: object_traits.hpp:38
constexpr auto stat_dimension_of_v
Helper template for coordinates::stat_dimension_of.
Definition: stat_dimension_of.hpp:56
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
auto & operator-=(const Arg &arg)
Subtract a stochastic value to each column of the matrix, based on a distribution.
Definition: EuclideanMean.hpp:251
constexpr auto constant_value(T &&t)
The constant value associated with a constant_object or constant_diagonal_object. ...
Definition: constant_value.hpp:37
decltype(auto) constexpr nested_object(Arg &&arg)
Retrieve a nested object of Arg, if it exists.
Definition: nested_object.hpp:35
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
constexpr bool compares_with
Compares two coordinates::pattern objects.
Definition: compares_with.hpp:475
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