15 #ifndef OPENKALMAN_MEAN_HPP 16 #define OPENKALMAN_MEAN_HPP 28 template<fixed_pattern RowCoefficients, typed_matrix_nestable NestedMatrix> requires
29 (coordinates::dimension_of_v<RowCoefficients> == index_dimension_of_v<NestedMatrix, 0>) and
30 (not std::is_rvalue_reference_v<NestedMatrix>)
32 template<
typename RowCoefficients,
typename NestedMatrix>
34 struct Mean : oin::TypedMatrixBase<
35 Mean<RowCoefficients, NestedMatrix>, NestedMatrix, RowCoefficients, Dimensions<index_dimension_of_v<NestedMatrix, 1>>>
38 #ifndef __cpp_concepts 39 static_assert(fixed_pattern<RowCoefficients>);
40 static_assert(typed_matrix_nestable<NestedMatrix>);
41 static_assert(coordinates::dimension_of_v<RowCoefficients> == index_dimension_of_v<NestedMatrix, 0>);
42 static_assert(not std::is_rvalue_reference_v<NestedMatrix>);
49 using ColumnCoefficients = Dimensions<index_dimension_of_v<NestedMatrix, 1>>;
53 using Base = oin::TypedMatrixBase<Mean, NestedMatrix, RowCoefficients, ColumnCoefficients>;
62 template<mean Arg> requires
63 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
64 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
66 std::constructible_from<NestedMatrix, decltype(nested_object(std::declval<Arg&&>()))>
68 template<
typename Arg, std::enable_if_t<mean<Arg> 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<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>
89 Mean(Arg&& arg) : Base {from_euclidean<RowCoefficients>(
nested_object(std::forward<Arg>(arg)))} {}
94 template<typed_matrix Arg> requires (not euclidean_transformed<Arg>) and (not mean<Arg>) and
95 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
96 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
97 requires(Arg&& arg) { NestedMatrix {wrap_angles<RowCoefficients>(
nested_object(std::forward<Arg>(arg)))}; }
99 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and not eucl
idean_transformed<Arg> and not mean<Arg> and
100 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
101 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients>,
int> = 0>
107 #ifdef __cpp_concepts 108 template<typed_matrix_nestable Arg> requires (index_dimension_of_v<Arg, 0> == index_dimension_of_v<NestedMatrix, 0>) and
109 (index_dimension_of_v<Arg, 1> == index_dimension_of_v<NestedMatrix, 1>) and
110 requires(Arg&& arg) { NestedMatrix {wrap_angles<RowCoefficients>(std::declval<Arg>())}; }
112 template<
typename Arg, std::enable_if_t<typed_matrix_nestable<Arg> and
113 (index_dimension_of<Arg, 0>::value == index_dimension_of<NestedMatrix, 0>::value) and
114 (index_dimension_of<Arg, 1>::value == index_dimension_of<NestedMatrix, 1>::value) and
115 std::is_constructible_v<NestedMatrix, decltype(wrap_angles<RowCoefficients>(std::declval<Arg>()))>,
int> = 0>
117 explicit Mean(Arg&& arg) : Base {wrap_angles<RowCoefficients>(std::forward<Arg>(arg))} {}
121 #ifdef __cpp_concepts 122 template<std::convertible_to<const Scalar> ... Args> requires (
sizeof...(Args) > 0) and
123 requires(Args ... args) { NestedMatrix {wrap_angles<RowCoefficients>(
124 make_dense_object_from<NestedMatrix>(
static_cast<const Scalar>(args)...))}; }
126 template<
typename ... Args, std::enable_if_t<std::conjunction_v<std::is_convertible<Args, const Scalar>...> and
129 std::is_constructible_v<NestedMatrix, decltype(wrap_angles<RowCoefficients>(std::declval<NestedMatrix>()))>,
133 : Base {wrap_angles<RowCoefficients>(make_dense_object_from<NestedMatrix>(
static_cast<const Scalar>(args)...))} {}
139 #ifdef __cpp_concepts 140 template<mean Arg> requires (not std::derived_from<std::decay_t<Arg>,
Mean>) and
141 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
144 template<
typename Arg, std::enable_if_t<mean<Arg> and (not std::is_base_of_v<Mean, std::decay_t<Arg>>) and
145 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
146 std::is_assignable_v<std::add_lvalue_reference_t<NestedMatrix>, nested_
object_of_t<Arg&&>>,
int> = 0>
150 if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
161 #ifdef __cpp_concepts 162 template<eucl
idean_transformed Arg> requires
163 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
164 std::assignable_from<std::add_lvalue_reference_t<NestedMatrix>, decltype(from_euclidean<RowCoefficients>(std::declval<
nested_object_of_t<Arg>>()))>
166 template<
typename Arg, std::enable_if_t<eucl
idean_transformed<Arg> and
167 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
168 std::is_assignable_v<std::add_lvalue_reference_t<NestedMatrix>, decltype(from_eucl
idean<RowCoefficients>(std::declval<nested_
object_of_t<Arg>>()))>,
int> = 0>
172 if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
174 Base::operator=(from_euclidean<RowCoefficients>(
nested_object(std::forward<Arg>(other))));
184 #ifdef __cpp_concepts 185 template<typed_matrix Arg> requires (not mean<Arg>) and (not euclidean_transformed<Arg>) and
186 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and has_untyped_index<Arg, 1> and
187 std::assignable_from<std::add_lvalue_reference_t<NestedMatrix>, decltype(wrap_angles<RowCoefficients>(std::declval<
nested_object_of_t<Arg>>()))>
189 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and
190 (not mean<Arg>) and (not eucl
idean_transformed<Arg>) and
191 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and has_untyped_index<Arg, 1> and
192 std::is_assignable_v<std::add_lvalue_reference_t<NestedMatrix>, decltype(wrap_angles<RowCoefficients>(std::declval<nested_
object_of_t<Arg>>()))>,
int> = 0>
196 if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
198 Base::operator=(wrap_angles<RowCoefficients>(
nested_object(std::forward<Arg>(other))));
205 #ifdef __cpp_concepts 206 template<typed_matrix_nestable Arg> requires std::assignable_from<std::add_lvalue_reference_t<NestedMatrix>, Arg&&>
208 template<
typename Arg, std::enable_if_t<typed_matrix_nestable<Arg> and
209 std::is_assignable_v<std::add_lvalue_reference_t<NestedMatrix>, Arg&&>,
int> = 0>
213 if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
215 Base::operator=(wrap_angles<RowCoefficients>(std::forward<Arg>(arg)));
224 if constexpr(coordinates::euclidean_pattern<RowCoefficients>)
233 #ifdef __cpp_concepts 234 template<typed_matrix Arg> requires
235 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
236 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
237 (not euclidean_transformed<Arg>)
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> and
242 (not eucl
idean_transformed<Arg>),
int> = 0>
246 if constexpr(coordinates::euclidean_pattern<RowCoefficients>)
256 #ifdef __cpp_concepts 257 template<distribution Arg> requires (compares_with<
typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>)
259 template<
typename Arg, std::enable_if_t<distribution<Arg> and
260 (compares_with<
typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>),
int> = 0>
264 apply_columnwise([&arg](
auto& col){
265 if constexpr(coordinates::euclidean_pattern<RowCoefficients>)
266 col += arg().nested_object();
268 col = wrap_angles<RowCoefficients>(col + arg().nested_object());
277 if constexpr(coordinates::euclidean_pattern<RowCoefficients>)
286 #ifdef __cpp_concepts 287 template<typed_matrix Arg> requires
288 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients>and
289 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients>and
290 (not euclidean_transformed<Arg>)
292 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and
293 compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients>and
294 compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients>and
295 (not eucl
idean_transformed<Arg>),
int> = 0>
299 if constexpr(coordinates::euclidean_pattern<RowCoefficients>)
309 #ifdef __cpp_concepts 310 template<distribution Arg> requires (compares_with<
typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>)
312 template<
typename Arg, std::enable_if_t<distribution<Arg> and
313 (compares_with<
typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>),
int> = 0>
317 apply_columnwise([&arg](
auto& col){
318 if constexpr(coordinates::euclidean_pattern<RowCoefficients>)
319 col -= arg().nested_object();
321 col = wrap_angles<RowCoefficients>(col - arg().nested_object());
328 #ifdef __cpp_concepts 329 template<std::convertible_to<Scalar> S>
331 template<
typename S, std::enable_if_t<std::is_convertible_v<S, Scalar>,
int> = 0>
335 if constexpr(coordinates::euclidean_pattern<RowCoefficients>)
344 #ifdef __cpp_concepts 345 template<std::convertible_to<Scalar> S>
347 template<
typename S, std::enable_if_t<std::is_convertible_v<S, Scalar>,
int> = 0>
351 if constexpr(coordinates::euclidean_pattern<RowCoefficients>)
360 template<
typename C = RowCoefficients,
typename Arg>
361 static auto make(Arg&& arg)
374 #ifdef __cpp_concepts 375 template<typed_matrix_nestable V>
377 template<
typename V, std::enable_if_t<typed_matrix_nestable<V>,
int> = 0>
383 #if defined(__cpp_concepts) and OPENKALMAN_CPP_FEATURE_CONCEPTS_2 385 template<typed_matrix V> requires (not euclidean_transformed<V>)
387 template<
typename V, std::enable_if_t<typed_matrix<V> and not eucl
idean_transformed<V>,
int> = 0>
394 #if defined(__cpp_concepts) and OPENKALMAN_CPP_FEATURE_CONCEPTS_2 396 template<eucl
idean_transformed V>
398 template<
typename V, std::enable_if_t<eucl
idean_transformed<V>,
int> = 0>
413 #ifdef __cpp_concepts 414 template<fixed_pattern StaticDescriptor, typed_matrix_nestable M> requires
415 (coordinates::dimension_of_v<StaticDescriptor> == index_dimension_of_v<M, 0>)
417 template<
typename StaticDescriptor,
typename M, std::enable_if_t<fixed_pattern<StaticDescriptor> and
418 typed_matrix_nestable<M> and (coordinates::dimension_of_v<StaticDescriptor> == index_dimension_of<M, 0>::value),
int> = 0>
422 constexpr
auto rows = index_dimension_of_v<M, 0>;
423 using Coeffs = std::conditional_t<std::is_void_v<StaticDescriptor>, Dimensions<rows>, StaticDescriptor>;
424 auto&& b = wrap_angles<Coeffs>(std::forward<M>(m));
using B = decltype(b);
433 #ifdef __cpp_concepts 434 template<typed_matrix_nestable M>
436 template<
typename M, std::enable_if_t<typed_matrix_nestable<M>,
int> = 0>
440 using Coeffs = Dimensions<index_dimension_of_v<M, 0>>;
441 return make_mean<Coeffs>(std::forward<M>(m));
450 #ifdef __cpp_concepts 451 template<typed_matrix Arg> requires has_untyped_index<Arg, 1>
453 template<
typename Arg, std::enable_if_t<typed_matrix<Arg> and has_untyped_index<Arg, 1>,
int> = 0>
458 if constexpr(euclidean_transformed<Arg>)
459 return make_mean<C>(
nested_object(from_euclidean<C>(std::forward<Arg>(arg))));
472 #ifdef __cpp_concepts 473 template<fixed_pattern StaticDescriptor, typed_matrix_nestable M> requires
474 (index_dimension_of_v<M, 0> == coordinates::dimension_of_v<StaticDescriptor>)
476 template<
typename StaticDescriptor,
typename M, std::enable_if_t<
477 fixed_pattern<StaticDescriptor> and typed_matrix_nestable<M> and
492 #ifdef __cpp_concepts 493 template<typed_matrix_nestable M>
495 template<
typename M, std::enable_if_t<typed_matrix_nestable<M>,
int> = 0>
499 return make_mean<Dimensions<index_dimension_of_v<M, 0>>, M>();
509 template<
typename Coeffs,
typename NestedMatrix>
514 template<
typename Arg>
517 template<
typename Arg,
typename N>
520 if constexpr (values::fixed<N>)
522 if constexpr (n == 0_uz)
return arg.my_dimension;
525 else if constexpr (uniform_static_vector_space_descriptor<NestedMatrix> and compares_with<Coeffs, uniform_static_vector_space_descriptor_component_of<NestedMatrix>>)
527 return arg.my_dimension;
531 if (n == 0)
return DynamicDescriptor<scalar_type> {arg.my_dimension};
537 template<
typename Arg>
544 template<
typename Arg>
545 static constexpr
auto get_constant(
const Arg& arg)
551 template<
typename Arg>
552 static constexpr
auto get_constant_diagonal(
const Arg& arg)
554 if constexpr (coordinates::euclidean_pattern<Coeffs>)
557 return std::monostate {};
561 template<Applicability b>
562 static constexpr
bool one_dimensional = OpenKalman::one_dimensional<NestedMatrix, b>;
565 template<Applicability b>
566 static constexpr
bool is_square = OpenKalman::square_shaped<NestedMatrix, b>;
569 template<TriangleType t>
570 static constexpr
bool is_triangular = coordinates::euclidean_pattern<Coeffs> and triangular_matrix<NestedMatrix, t>;
573 static constexpr
bool is_triangular_adapter =
false;
576 static constexpr
bool is_hermitian = coordinates::euclidean_pattern<Coeffs> and hermitian_matrix<NestedMatrix>;
579 #ifdef __cpp_lib_concepts 580 template<
typename Arg,
typename...I> requires element_gettable<nested_object_of_t<Arg&&>,
sizeof...(I)>
584 static constexpr decltype(
auto)
get(Arg&& arg, I...i)
590 #ifdef __cpp_lib_concepts 591 template<
typename Arg,
typename I,
typename...Is> requires writable_by_component<nested_object_of_t<Arg&>, 1 +
sizeof...(Is)>
597 if constexpr(wrapped_mean<Arg>)
599 const auto get_coeff = [&arg, is...] (
const std::size_t row) {
605 coordinates::set_wrapped_component<Coeffs>(Coeffs{}, i, s, set_coeff, get_coeff);
617 #ifdef __cpp_lib_concepts 618 template<
typename Arg> requires raw_data_defined_for<NestedMatrix>
620 template<
typename Arg, std::enable_if_t<raw_data_defined_for<NestedMatrix>,
int> = 0>
622 static constexpr
auto *
const 626 static constexpr
Layout layout = layout_of_v<NestedMatrix>;
636 #endif //OPENKALMAN_MEAN_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
Definition: indexible_object_traits.hpp:36
Mean(Args ... args)
Construct from a list of coefficients.
Definition: Mean.hpp:132
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
A set of one or more column vectors, each representing a statistical mean.
Definition: forward-class-declarations.hpp:477
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 Mean &other)
Increment from another mean.
Definition: Mean.hpp:222
auto make_mean(M &&m)
Make a Mean from a typed_matrix_nestable, specifying the row fixed_pattern.
Definition: Mean.hpp:420
constexpr bool value
T is numerical value or is reducible to a numerical value.
Definition: value.hpp:31
auto & operator=(Arg &&arg)
Assign from a compatible typed_matrix_nestable.
Definition: Mean.hpp:211
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
Mean(Arg &&arg)
Construct from a compatible mean.
Definition: Mean.hpp:73
auto & operator+=(Arg &&other)
Increment from another typed matrix.
Definition: Mean.hpp:244
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
The constant associated with T, assuming T is a constant_diagonal_matrix.
Definition: constant_diagonal_coefficient.hpp:32
auto & operator*=(const S s)
Multiply by a scale factor.
Definition: Mean.hpp:333
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
auto & operator-=(const Mean &other)
Decrement from another mean and wrap result.
Definition: Mean.hpp:275
constexpr bool element_gettable
Specifies that a type has components addressable by N indices.
Definition: element_gettable.hpp:33
auto & operator-=(Arg &&other)
Decrement from another typed matrix and wrap result.
Definition: Mean.hpp:297
auto & operator/=(const S s)
Divide by a scale factor.
Definition: Mean.hpp:349
auto & operator+=(const Arg &arg)
Add a stochastic value to each column of the mean, based on a distribution.
Definition: Mean.hpp:262
The dimension of an index for a matrix, expression, or array.
Definition: index_dimension_of.hpp:34
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
Mean(V &&) -> Mean< Dimensions< index_dimension_of_v< V, 0 >>, passable_t< V >>
Deduce template parameters from a typed_matrix_nestable, assuming untyped coordinates::pattern.
scalar_type_of_t< MeanNestedMatrix > Scalar
Scalar type for this matrix.
Definition: Mean.hpp:45
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
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 mean.
Definition: Mean.hpp:148
auto & operator-=(const Arg &arg)
Subtract a stochastic value to each column of the mean, based on a distribution.
Definition: Mean.hpp:315