OpenKalman
Mean.hpp
Go to the documentation of this file.
1 /* This file is part of OpenKalman, a header-only C++ library for
2  * Kalman filters and other recursive filters.
3  *
4  * Copyright (c) 2018-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 
15 #ifndef OPENKALMAN_MEAN_HPP
16 #define OPENKALMAN_MEAN_HPP
17 
18 namespace OpenKalman
19 {
20  namespace oin = OpenKalman::internal;
21 
22  // ------------------- //
23  // Mean //
24  // ------------------- //
25 
27 #ifdef __cpp_concepts
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>)
31 #else
32  template<typename RowCoefficients, typename NestedMatrix>
33 #endif
34  struct Mean : oin::TypedMatrixBase<
35  Mean<RowCoefficients, NestedMatrix>, NestedMatrix, RowCoefficients, Dimensions<index_dimension_of_v<NestedMatrix, 1>>>
36  {
37 
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>);
43 #endif
44 
46 
47  protected:
48 
49  using ColumnCoefficients = Dimensions<index_dimension_of_v<NestedMatrix, 1>>;
50 
51  private:
52 
53  using Base = oin::TypedMatrixBase<Mean, NestedMatrix, RowCoefficients, ColumnCoefficients>;
54 
55  public:
56 
57  using Base::Base;
58 
59 
61 #ifdef __cpp_concepts
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
65  //requires(Arg&& arg) { NestedMatrix {nested_object(std::forward<Arg>(arg))}; } // \todo doesn't work in GCC 10
66  std::constructible_from<NestedMatrix, decltype(nested_object(std::declval<Arg&&>()))>
67 #else
68  template<typename Arg, std::enable_if_t<mean<Arg> and
69  compares_with<vector_space_descriptor_of_t<Arg, 0>, RowCoefficients> and
70  compares_with<vector_space_descriptor_of_t<Arg, 1>, ColumnCoefficients> and
71  std::is_constructible_v<NestedMatrix, decltype(nested_object(std::declval<Arg&&>()))>, int> = 0>
72 #endif
73  Mean(Arg&& arg) : Base {nested_object(std::forward<Arg>(arg))} {}
74 
75 
77 #ifdef __cpp_concepts
78  template<euclidean_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)))}; }
82 #else
83  template<typename Arg, std::enable_if_t<euclidean_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_euclidean<RowCoefficients>(nested_object(std::declval<Arg&&>())))>, int> = 0>
88 #endif
89  Mean(Arg&& arg) : Base {from_euclidean<RowCoefficients>(nested_object(std::forward<Arg>(arg)))} {}
90 
91 
93 #ifdef __cpp_concepts
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)))}; }
98 #else
99  template<typename Arg, std::enable_if_t<typed_matrix<Arg> and not euclidean_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>
102 #endif
103  Mean(Arg&& arg) : Base {wrap_angles<RowCoefficients>(nested_object(std::forward<Arg>(arg)))} {}
104 
105 
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>())}; }
111 #else
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>
116 #endif
117  explicit Mean(Arg&& arg) : Base {wrap_angles<RowCoefficients>(std::forward<Arg>(arg))} {}
118 
119 
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)...))}; }
125 #else
126  template<typename ... Args, std::enable_if_t<std::conjunction_v<std::is_convertible<Args, const Scalar>...> and
127  ((diagonal_matrix<NestedMatrix> and sizeof...(Args) == index_dimension_of<NestedMatrix, 0>::value) or
129  std::is_constructible_v<NestedMatrix, decltype(wrap_angles<RowCoefficients>(std::declval<NestedMatrix>()))>,
130  int> = 0>
131 #endif
132  Mean(Args ... args)
133  : Base {wrap_angles<RowCoefficients>(make_dense_object_from<NestedMatrix>(static_cast<const Scalar>(args)...))} {}
134 
135 
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
142  std::assignable_from<std::add_lvalue_reference_t<NestedMatrix>, nested_object_of_t<Arg&&>>
143 #else
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>
147 #endif
148  auto& operator=(Arg&& other)
149  {
150  if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
151  {
152  Base::operator=(nested_object(std::forward<Arg>(other)));
153  }
154  return *this;
155  }
156 
157 
161 #ifdef __cpp_concepts
162  template<euclidean_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>>()))>
165 #else
166  template<typename Arg, std::enable_if_t<euclidean_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_euclidean<RowCoefficients>(std::declval<nested_object_of_t<Arg>>()))>, int> = 0>
169 #endif
170  auto& operator=(Arg&& other)
171  {
172  if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
173  {
174  Base::operator=(from_euclidean<RowCoefficients>(nested_object(std::forward<Arg>(other))));
175  }
176  return *this;
177  }
178 
179 
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>>()))>
188 #else
189  template<typename Arg, std::enable_if_t<typed_matrix<Arg> and
190  (not mean<Arg>) and (not euclidean_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>
193 #endif
194  auto& operator=(Arg&& other)
195  {
196  if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
197  {
198  Base::operator=(wrap_angles<RowCoefficients>(nested_object(std::forward<Arg>(other))));
199  }
200  return *this;
201  }
202 
203 
205 #ifdef __cpp_concepts
206  template<typed_matrix_nestable Arg> requires std::assignable_from<std::add_lvalue_reference_t<NestedMatrix>, Arg&&>
207 #else
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>
210 #endif
211  auto& operator=(Arg&& arg)
212  {
213  if constexpr (not zero<NestedMatrix> and not identity_matrix<NestedMatrix>)
214  {
215  Base::operator=(wrap_angles<RowCoefficients>(std::forward<Arg>(arg)));
216  }
217  return *this;
218  }
219 
220 
222  auto& operator+=(const Mean& other)
223  {
224  if constexpr(coordinates::euclidean_pattern<RowCoefficients>)
225  this->nested_object() += other.nested_object();
226  else
227  this->nested_object() = wrap_angles<RowCoefficients>(this->nested_object() + other.nested_object());
228  return *this;
229  }
230 
231 
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>)
238 #else
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 euclidean_transformed<Arg>), int> = 0>
243 #endif
244  auto& operator+=(Arg&& other)
245  {
246  if constexpr(coordinates::euclidean_pattern<RowCoefficients>)
247  this->nested_object() += nested_object(std::forward<Arg>(other));
248  else
249  this->nested_object() = wrap_angles<RowCoefficients>(
250  this->nested_object() + nested_object(std::forward<Arg>(other)));
251  return *this;
252  }
253 
254 
256 #ifdef __cpp_concepts
257  template<distribution Arg> requires (compares_with<typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>)
258 #else
259  template<typename Arg, std::enable_if_t<distribution<Arg> and
260  (compares_with<typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>), int> = 0>
261 #endif
262  auto& operator+=(const Arg& arg)
263  {
264  apply_columnwise([&arg](auto& col){
265  if constexpr(coordinates::euclidean_pattern<RowCoefficients>)
266  col += arg().nested_object();
267  else
268  col = wrap_angles<RowCoefficients>(col + arg().nested_object());
269  }, this->nested_object());
270  return *this;
271  }
272 
273 
275  auto& operator-=(const Mean& other)
276  {
277  if constexpr(coordinates::euclidean_pattern<RowCoefficients>)
278  this->nested_object() -= other.nested_object();
279  else
280  this->nested_object() = wrap_angles<RowCoefficients>(this->nested_object() - other.nested_object());
281  return *this;
282  }
283 
284 
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>)
291 #else
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 euclidean_transformed<Arg>), int> = 0>
296 #endif
297  auto& operator-=(Arg&& other)
298  {
299  if constexpr(coordinates::euclidean_pattern<RowCoefficients>)
300  this->nested_object() -= nested_object(std::forward<Arg>(other));
301  else
302  this->nested_object() = wrap_angles<RowCoefficients>(
303  this->nested_object() - nested_object(std::forward<Arg>(other)));
304  return *this;
305  }
306 
307 
309 #ifdef __cpp_concepts
310  template<distribution Arg> requires (compares_with<typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>)
311 #else
312  template<typename Arg, std::enable_if_t<distribution<Arg> and
313  (compares_with<typename DistributionTraits<Arg>::StaticDescriptor, RowCoefficients>), int> = 0>
314 #endif
315  auto& operator-=(const Arg& arg)
316  {
317  apply_columnwise([&arg](auto& col){
318  if constexpr(coordinates::euclidean_pattern<RowCoefficients>)
319  col -= arg().nested_object();
320  else
321  col = wrap_angles<RowCoefficients>(col - arg().nested_object());
322  }, this->nested_object());
323  return *this;
324  }
325 
326 
328 #ifdef __cpp_concepts
329  template<std::convertible_to<Scalar> S>
330 #else
331  template<typename S, std::enable_if_t<std::is_convertible_v<S, Scalar>, int> = 0>
332 #endif
333  auto& operator*=(const S s)
334  {
335  if constexpr(coordinates::euclidean_pattern<RowCoefficients>)
336  this->nested_object() *= s;
337  else
338  this->nested_object() = wrap_angles<RowCoefficients>(this->nested_object() * s);
339  return *this;
340  }
341 
342 
344 #ifdef __cpp_concepts
345  template<std::convertible_to<Scalar> S>
346 #else
347  template<typename S, std::enable_if_t<std::is_convertible_v<S, Scalar>, int> = 0>
348 #endif
349  auto& operator/=(const S s)
350  {
351  if constexpr(coordinates::euclidean_pattern<RowCoefficients>)
352  this->nested_object() /= s;
353  else
354  this->nested_object() = wrap_angles<RowCoefficients>(this->nested_object() / s);
355  return *this;
356  }
357 
358  protected:
359 
360  template<typename C = RowCoefficients, typename Arg>
361  static auto make(Arg&& arg)
362  {
363  return Mean<C, std::decay_t<Arg>>(std::forward<Arg>(arg));
364  }
365 
366  };
367 
368 
369  // ------------------------------- //
370  // Deduction guides //
371  // ------------------------------- //
372 
374 #ifdef __cpp_concepts
375  template<typed_matrix_nestable V>
376 #else
377  template<typename V, std::enable_if_t<typed_matrix_nestable<V>, int> = 0>
378 #endif
379  explicit Mean(V&&) -> Mean<Dimensions<index_dimension_of_v<V, 0>>, passable_t<V>>;
380 
381 
383 #if defined(__cpp_concepts) and OPENKALMAN_CPP_FEATURE_CONCEPTS_2
384  // \todo Unlike SFINAE version, this incorrectly matches V==EuclideanMean in both GCC 10.1.0 and clang 10.0.0:
385  template<typed_matrix V> requires (not euclidean_transformed<V>)
386 #else
387  template<typename V, std::enable_if_t<typed_matrix<V> and not euclidean_transformed<V>, int> = 0>
388 #endif
389  Mean(V&&) -> Mean<vector_space_descriptor_of_t<V, 0>, std::decay_t<decltype(
390  wrap_angles<vector_space_descriptor_of_t<V, 0>>(nested_object(std::forward<V>(std::declval<V>()))))>>;
391 
392 
394 #if defined(__cpp_concepts) and OPENKALMAN_CPP_FEATURE_CONCEPTS_2
395  // \todo Unlike SFINAE version, this incorrectly matches V==Mean and V==Matrix in both GCC 10.1.0 and clang 10.0.0:
396  template<euclidean_transformed V>
397 #else
398  template<typename V, std::enable_if_t<euclidean_transformed<V>, int> = 0>
399 #endif
400  Mean(V&&) -> Mean<vector_space_descriptor_of_t<V, 0>, std::decay_t<decltype(
401  from_euclidean<vector_space_descriptor_of_t<V, 0>>(nested_object(std::forward<V>(std::declval<V>()))))>>;
402 
403 
404  // ----------------------------- //
405  // Make functions //
406  // ----------------------------- //
407 
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>)
416 #else
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>
419 #endif
420  inline auto make_mean(M&& m)
421  {
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);
425  return Mean<Coeffs, passable_t<B>>(std::forward<B>(b));
426  }
427 
428 
433 #ifdef __cpp_concepts
434  template<typed_matrix_nestable M>
435 #else
436  template<typename M, std::enable_if_t<typed_matrix_nestable<M>, int> = 0>
437 #endif
438  inline auto make_mean(M&& m)
439  {
440  using Coeffs = Dimensions<index_dimension_of_v<M, 0>>;
441  return make_mean<Coeffs>(std::forward<M>(m));
442  }
443 
444 
450 #ifdef __cpp_concepts
451  template<typed_matrix Arg> requires has_untyped_index<Arg, 1>
452 #else
453  template<typename Arg, std::enable_if_t<typed_matrix<Arg> and has_untyped_index<Arg, 1>, int> = 0>
454 #endif
455  inline auto make_mean(Arg&& arg)
456  {
458  if constexpr(euclidean_transformed<Arg>)
459  return make_mean<C>(nested_object(from_euclidean<C>(std::forward<Arg>(arg))));
460  else
461  return make_mean<C>(nested_object(std::forward<Arg>(arg)));
462  }
463 
464 
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>)
475 #else
476  template<typename StaticDescriptor, typename M, std::enable_if_t<
477  fixed_pattern<StaticDescriptor> and typed_matrix_nestable<M> and
478  (index_dimension_of<M, 0>::value == coordinates::dimension_of_v<StaticDescriptor>), int> = 0>
479 #endif
480  inline auto make_mean()
481  {
483  }
484 
485 
492 #ifdef __cpp_concepts
493  template<typed_matrix_nestable M>
494 #else
495  template<typename M, std::enable_if_t<typed_matrix_nestable<M>, int> = 0>
496 #endif
497  inline auto make_mean()
498  {
499  return make_mean<Dimensions<index_dimension_of_v<M, 0>>, M>();
500  }
501 
502 
503  // ------------------------- //
504  // Interfaces //
505  // ------------------------- //
506 
507  namespace interface
508  {
509  template<typename Coeffs, typename NestedMatrix>
510  struct indexible_object_traits<Mean<Coeffs, NestedMatrix>>
511  {
512  using scalar_type = scalar_type_of_t<NestedMatrix>;
513 
514  template<typename Arg>
515  static constexpr auto count_indices(const Arg& arg) { return OpenKalman::count_indices(nested_object(arg)); }
516 
517  template<typename Arg, typename N>
518  static constexpr auto get_vector_space_descriptor(const Arg& arg, N n)
519  {
520  if constexpr (values::fixed<N>)
521  {
522  if constexpr (n == 0_uz) return arg.my_dimension;
524  }
525  else if constexpr (uniform_static_vector_space_descriptor<NestedMatrix> and compares_with<Coeffs, uniform_static_vector_space_descriptor_component_of<NestedMatrix>>)
526  {
527  return arg.my_dimension;
528  }
529  else
530  {
531  if (n == 0) return DynamicDescriptor<scalar_type> {arg.my_dimension};
532  else return DynamicDescriptor<scalar_type> {OpenKalman::get_vector_space_descriptor(nested_object(arg), n)};
533  }
534  }
535 
536 
537  template<typename Arg>
538  static decltype(auto) nested_object(Arg&& arg)
539  {
540  return std::forward<Arg>(arg).nested_object();
541  }
542 
543 
544  template<typename Arg>
545  static constexpr auto get_constant(const Arg& arg)
546  {
547  return constant_coefficient{arg.nestedExpression()};
548  }
549 
550 
551  template<typename Arg>
552  static constexpr auto get_constant_diagonal(const Arg& arg)
553  {
554  if constexpr (coordinates::euclidean_pattern<Coeffs>)
555  return constant_diagonal_coefficient {arg.nestedExpression()};
556  else
557  return std::monostate {};
558  }
559 
560 
561  template<Applicability b>
562  static constexpr bool one_dimensional = OpenKalman::one_dimensional<NestedMatrix, b>;
563 
564 
565  template<Applicability b>
566  static constexpr bool is_square = OpenKalman::square_shaped<NestedMatrix, b>;
567 
568 
569  template<TriangleType t>
570  static constexpr bool is_triangular = coordinates::euclidean_pattern<Coeffs> and triangular_matrix<NestedMatrix, t>;
571 
572 
573  static constexpr bool is_triangular_adapter = false;
574 
575 
576  static constexpr bool is_hermitian = coordinates::euclidean_pattern<Coeffs> and hermitian_matrix<NestedMatrix>;
577 
578 
579  #ifdef __cpp_lib_concepts
580  template<typename Arg, typename...I> requires element_gettable<nested_object_of_t<Arg&&>, sizeof...(I)>
581  #else
582  template<typename Arg, typename...I, std::enable_if_t<element_gettable<typename nested_object_of<Arg&&>::type, sizeof...(I)>, int> = 0>
583  #endif
584  static constexpr decltype(auto) get(Arg&& arg, I...i)
585  {
586  return get_component(OpenKalman::nested_object(std::forward<Arg>(arg)), i...);
587  }
588 
589 
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)>
592  #else
593  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>
594  #endif
595  static constexpr void set(Arg& arg, const scalar_type_of_t<Arg>& s, I i, Is...is)
596  {
597  if constexpr(wrapped_mean<Arg>)
598  {
599  const auto get_coeff = [&arg, is...] (const std::size_t row) {
600  return get_component(OpenKalman::nested_object(arg), row, is...);
601  };
602  const auto set_coeff = [&arg, is...](const std::size_t row, const scalar_type_of_t<Arg> value) {
603  set_component(nested_object(arg), value, row, is...);
604  };
605  coordinates::set_wrapped_component<Coeffs>(Coeffs{}, i, s, set_coeff, get_coeff);
606  }
607  else
608  {
609  set_component(OpenKalman::nested_object(arg), s, i, is...);
610  }
611  }
612 
613 
614  static constexpr bool is_writable = library_interface<std::decay_t<NestedMatrix>>::is_writable;
615 
616 
617 #ifdef __cpp_lib_concepts
618  template<typename Arg> requires raw_data_defined_for<NestedMatrix>
619 #else
620  template<typename Arg, std::enable_if_t<raw_data_defined_for<NestedMatrix>, int> = 0>
621 #endif
622  static constexpr auto * const
623  raw_data(Arg& arg) { return internal::raw_data(OpenKalman::nested_object(arg)); }
624 
625 
626  static constexpr Layout layout = layout_of_v<NestedMatrix>;
627 
628  };
629 
630  } // namespace interface
631 
632 
633 } // namespace OpenKalman
634 
635 
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&#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
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