OpenKalman
EuclideanMean.hpp
1 /* This file is part of OpenKalman, a header-only C++ library for
2  * Kalman filters and other recursive filters.
3  *
4  * Copyright (c) 2019-2021 Christopher Lee Ogden <ogden@gatech.edu>
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
9  */
10 
11 #ifndef OPENKALMAN_EUCLIDEANMEAN_HPP
12 #define OPENKALMAN_EUCLIDEANMEAN_HPP
13 
14 namespace OpenKalman
15 {
16  namespace oin = OpenKalman::internal;
17 
18  // --------------- //
19  // EuclideanMean //
20  // --------------- //
21 
22 #ifdef __cpp_concepts
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>)
26 #else
27  template<typename RowCoefficients, typename NestedMatrix>
28 #endif
29  struct EuclideanMean : oin::TypedMatrixBase<EuclideanMean<RowCoefficients, NestedMatrix>, NestedMatrix,
30  RowCoefficients, Dimensions<index_dimension_of_v<NestedMatrix, 1>>>
31  {
32 
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>);
38 #endif
39 
41 
42  protected:
43 
44  using ColumnCoefficients = Dimensions<index_dimension_of_v<NestedMatrix, 1>>;
45 
46  private:
47 
48  using Base = oin::TypedMatrixBase<EuclideanMean, NestedMatrix, RowCoefficients, ColumnCoefficients>;
49 
50  public:
51 
52  using Base::Base;
53 
54 
56 #ifdef __cpp_concepts
57  template<euclidean_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
60  //requires(Arg&& arg) { NestedMatrix {nested_object(std::forward<Arg>(arg))}; } // \todo doesn't work in GCC 10
61  std::constructible_from<NestedMatrix, decltype(nested_object(std::declval<Arg&&>()))>
62 #else
63  template<typename Arg, std::enable_if_t<euclidean_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>
67 #endif
68  EuclideanMean(Arg&& arg) : Base {nested_object(std::forward<Arg>(arg))} {}
69 
70 
72 #ifdef __cpp_concepts
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)))}; }
77 #else
78  template<typename Arg, std::enable_if_t<typed_matrix<Arg> and (not euclidean_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_euclidean<RowCoefficients>(nested_object(std::declval<Arg&&>())))>, int> = 0>
83 #endif
84  EuclideanMean(Arg&& arg)
85  : Base {to_euclidean<RowCoefficients>(nested_object(std::forward<Arg>(arg)))} {}
86 
87 
89 #ifdef __cpp_concepts
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&&>
93 #else
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>
98 #endif
99  EuclideanMean(Arg&& arg) : Base {std::forward<Arg>(arg)} {}
100 
101 
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
110  has_untyped_index<Arg, 1> and std::assignable_from<std::add_lvalue_reference_t<NestedMatrix>, nested_object_of_t<Arg&&>>
111 #else
112  template<typename Arg, std::enable_if_t<typed_matrix<Arg> and
113  (not std::is_base_of_v<EuclideanMean, std::decay_t<Arg>>) and
114  (euclidean_transformed<Arg> or coordinates::euclidean_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>
117 #endif
118  auto& operator=(Arg&& other)
119  {
120  if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
121  {
122  Base::operator=(nested_object(std::forward<Arg>(other)));
123  }
124  return *this;
125  }
126 
127 
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
136  has_untyped_index<Arg, 1> and std::assignable_from<std::add_lvalue_reference_t<NestedMatrix>, nested_object_of_t<Arg&&>>
137 #else
138  template<typename Arg, std::enable_if_t<typed_matrix<Arg> and
139  (not std::is_base_of_v<EuclideanMean, std::decay_t<Arg>>) and
140  (not euclidean_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>
143 #endif
144  auto& operator=(Arg&& other)
145  {
146  if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
147  {
148  Base::operator=(to_euclidean<RowCoefficients>(nested_object(std::forward<Arg>(other))));
149  }
150  return *this;
151  }
152 
153 
157 #ifdef __cpp_concepts
158  template<typed_matrix_nestable Arg> requires std::assignable_from<std::add_lvalue_reference_t<NestedMatrix>, Arg&&>
159 #else
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>
161 #endif
162  auto& operator=(Arg&& arg)
163  {
164  if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
165  {
166  Base::operator=(std::forward<Arg>(arg));
167  }
168  return *this;
169  }
170 
171 
175  auto& operator+=(const EuclideanMean& other)
176  {
177  this->nested_object() += other.nested_object();
178  return *this;
179  }
180 
181 
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>)
188 #else
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::euclidean_pattern<RowCoefficients> or euclidean_transformed<Arg>), int> = 0>
193 #endif
194  auto& operator+=(Arg&& other)
195  {
196  this->nested_object() += nested_object(std::forward<Arg>(other));
197  return *this;
198  }
199 
200 
202 #ifdef __cpp_concepts
203  template<distribution Arg> requires coordinates::euclidean_pattern<RowCoefficients> and
204  (compares_with<typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>)
205 #else
206  template<typename Arg, std::enable_if_t<distribution<Arg> and coordinates::euclidean_pattern<RowCoefficients> and
207  (compares_with<typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>), int> = 0>
208 #endif
209  auto& operator+=(const Arg& arg)
210  {
211  apply_columnwise([&arg](auto& col){ col += arg().nested_object(); }, this->nested_object());
212  return *this;
213  }
214 
215 
217  auto& operator-=(const EuclideanMean& other)
218  {
219  this->nested_object() -= other.nested_object();
220  return *this;
221  }
222 
223 
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>)
230 #else
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::euclidean_pattern<RowCoefficients> or euclidean_transformed<Arg>), int> = 0>
235 #endif
236  auto& operator-=(Arg&& other)
237  {
238  this->nested_object() -= nested_object(std::forward<Arg>(other));
239  return *this;
240  }
241 
242 
244 #ifdef __cpp_concepts
245  template<distribution Arg> requires coordinates::euclidean_pattern<RowCoefficients> and
246  (compares_with<typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>)
247 #else
248  template<typename Arg, std::enable_if_t<distribution<Arg> and coordinates::euclidean_pattern<RowCoefficients> and
249  (compares_with<typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>), int> = 0>
250 #endif
251  auto& operator-=(const Arg& arg)
252  {
253  apply_columnwise([&arg](auto& col){ col -= arg().nested_object(); }, this->nested_object());
254  return *this;
255  }
256 
257  protected:
258 
259  template<typename C = RowCoefficients, typename Arg>
260  static auto make(Arg&& arg)
261  {
262  return EuclideanMean<C, std::decay_t<Arg>>(std::forward<Arg>(arg));
263  }
264 
265  };
266 
267 
268  // ------------------ //
269  // Deduction guides //
270  // ------------------ //
271 
273 #if defined(__cpp_concepts) and OPENKALMAN_CPP_FEATURE_CONCEPTS_2
274  // \todo Unlike SFINAE version, this incorrectly matches V==EuclideanMean in both GCC 10.1.0 and clang 10.0.0:
275  template<typed_matrix V> requires (not euclidean_transformed<V>) and has_untyped_index<V, 1> and
276  (coordinates::stat_dimension_of_v<vector_space_descriptor_of_t<V, 0>> == index_dimension_of_v<V, 0>)
277 #else
278  template<typename V, std::enable_if_t<typed_matrix<V> and not euclidean_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>
280 #endif
281  EuclideanMean(V&&)
282  -> EuclideanMean<vector_space_descriptor_of_t<V, 0>, std::remove_reference_t<
283  decltype(to_euclidean<vector_space_descriptor_of_t<V, 0>>(nested_object(std::declval<V&&>())))>>;
284 
285 
287 #ifdef __cpp_concepts
288  template<euclidean_transformed V>
289 #else
290  template<typename V, std::enable_if_t<typed_matrix<V> and euclidean_transformed<V>, int> = 0>
291 #endif
293 
294 
296 #ifdef __cpp_concepts
297  template<typed_matrix_nestable V>
298 #else
299  template<typename V, std::enable_if_t<typed_matrix_nestable<V>, int> = 0>
300 #endif
301  explicit EuclideanMean(V&&) -> EuclideanMean<Dimensions<index_dimension_of_v<V, 0>>, passable_t<V>>;
302 
303 
304  // ----------------------------- //
305  // Make functions //
306  // ----------------------------- //
307 
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>)
316 #else
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>
319 #endif
320  auto make_euclidean_mean(M&& arg)
321  {
322  return EuclideanMean<StaticDescriptor, passable_t<M>>(std::forward<M>(arg));
323  }
324 
325 
330 #ifdef __cpp_concepts
331  template<typed_matrix_nestable M>
332 #else
333  template<typename M, std::enable_if_t<typed_matrix_nestable<M>, int> = 0>
334 #endif
336  {
337  using Coeffs = Dimensions<index_dimension_of_v<M, 0>>;
338  return make_mean<Coeffs>(std::forward<M>(m));
339  }
340 
341 
347 #ifdef __cpp_concepts
348  template<typed_matrix Arg> requires has_untyped_index<Arg, 1>
349 #else
350  template<typename Arg, std::enable_if_t<typed_matrix<Arg> and has_untyped_index<Arg, 1>, int> = 0>
351 #endif
352  inline auto make_euclidean_mean(Arg&& arg)
353  {
355  if constexpr(euclidean_transformed<Arg>)
356  return make_euclidean_mean<C>(nested_object(std::forward<Arg>(arg)));
357  else
358  return make_euclidean_mean<C>(nested_object(to_euclidean<C>(std::forward<Arg>(arg))));
359  }
360 
361 
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>)
372 #else
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>
375 #endif
377  {
379  }
380 
381 
388 #ifdef __cpp_concepts
389  template<typed_matrix_nestable M>
390 #else
391  template<typename M, std::enable_if_t<typed_matrix_nestable<M>, int> = 0>
392 #endif
394  {
395  return make_euclidean_mean<Dimensions<index_dimension_of_v<M, 0>>, M>();
396  }
397 
398 
399  // ------------------------- //
400  // Interfaces //
401  // ------------------------- //
402 
403  namespace interface
404  {
405  template<typename Coeffs, typename NestedMatrix>
406  struct indexible_object_traits<EuclideanMean<Coeffs, NestedMatrix>>
407  {
408  using scalar_type = scalar_type_of_t<NestedMatrix>;
409 
410  template<typename Arg>
411  static constexpr auto count_indices(const Arg& arg) { return OpenKalman::count_indices(nested_object(arg)); }
412 
413  template<typename Arg, typename N>
414  static constexpr auto get_vector_space_descriptor(const Arg& arg, N n)
415  {
416  if constexpr (values::fixed<N>)
417  {
418  if constexpr (n == 0_uz) return arg.my_dimension;
420  }
421  else if constexpr (uniform_static_vector_space_descriptor<NestedMatrix> and compares_with<Coeffs, uniform_static_vector_space_descriptor_component_of<NestedMatrix>>)
422  {
423  return arg.my_dimension;
424  }
425  else
426  {
427  if (n == 0) return DynamicDescriptor<scalar_type> {arg.my_dimension};
428  else return DynamicDescriptor<scalar_type> {OpenKalman::get_vector_space_descriptor(nested_object(arg), n)};
429  }
430  }
431 
432 
433  template<typename Arg>
434  static decltype(auto) nested_object(Arg&& arg)
435  {
436  return std::forward<Arg>(arg).nested_object();
437  }
438 
439 
440  template<typename Arg>
441  static constexpr auto get_constant(const Arg& arg)
442  {
443  if constexpr (coordinates::euclidean_pattern<Coeffs>)
444  return constant_coefficient {arg.nestedExpression()};
445  else
446  return std::monostate {};
447  }
448 
449 
450  template<typename Arg>
451  static constexpr auto get_constant_diagonal(const Arg& arg)
452  {
453  if constexpr (coordinates::euclidean_pattern<Coeffs>)
454  return constant_diagonal_coefficient {arg.nestedExpression()};
455  else
456  return std::monostate {};
457  }
458 
459 
460  template<Applicability b>
461  static constexpr bool one_dimensional = OpenKalman::one_dimensional<NestedMatrix, b>;
462 
463 
464  template<Applicability b>
465  static constexpr bool is_square = OpenKalman::square_shaped<NestedMatrix, b>;
466 
467 
468  template<TriangleType t>
469  static constexpr bool is_triangular = coordinates::euclidean_pattern<Coeffs> and triangular_matrix<NestedMatrix, t>;
470 
471 
472  static constexpr bool is_triangular_adapter = false;
473 
474 
475  static constexpr bool is_hermitian = coordinates::euclidean_pattern<Coeffs> and hermitian_matrix<NestedMatrix>;
476 
477 
478  #ifdef __cpp_lib_concepts
479  template<typename Arg, typename...I> requires element_gettable<nested_object_of_t<Arg&&>, sizeof...(I)>
480  #else
481  template<typename Arg, typename...I, std::enable_if_t<element_gettable<typename nested_object_of<Arg&&>::type, sizeof...(I)>, int> = 0>
482  #endif
483  static constexpr decltype(auto)
484  get(Arg&& arg, I...i)
485  {
486  return get_component(OpenKalman::nested_object(std::forward<Arg>(arg)), i...);
487  }
488 
489 
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)>
492  #else
493  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>
494  #endif
495  static constexpr void
496  set(Arg& arg, const scalar_type_of_t<Arg>& s, I i, Is...is)
497  {
498  set_component(OpenKalman::nested_object(arg), s, i, is...);
499  }
500 
501 
502  static constexpr bool is_writable = library_interface<std::decay_t<NestedMatrix>>::is_writable;
503 
504 
505 #ifdef __cpp_lib_concepts
506  template<typename Arg> requires raw_data_defined_for<NestedMatrix> and coordinates::euclidean_pattern<Coeffs>
507 #else
508  template<typename Arg, std::enable_if_t<raw_data_defined_for<NestedMatrix> and coordinates::euclidean_pattern<Coeffs>, int> = 0>
509 #endif
510  static constexpr auto * const
511  raw_data(Arg& arg) { return internal::raw_data(OpenKalman::nested_object(arg)); }
512 
513 
514  static constexpr Layout layout = coordinates::euclidean_pattern<Coeffs> ? layout_of_v<NestedMatrix> : Layout::none;
515 
516  };
517 
518  } // namespace interface
519 
520 
521 } // namespace OpenKalman::internal
522 
523 
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&#39;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