OpenKalman
SphericalSimplex.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) 2017-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 
16 #ifndef OPENKALMAN_SPHERICALSIMPLEX_HPP
17 #define OPENKALMAN_SPHERICALSIMPLEX_HPP
18 
19 #include <limits>
20 
21 namespace OpenKalman
22 {
23  namespace oin = OpenKalman::internal;
24 
25  template<typename Parameters>
27 
29  {
31  static constexpr double alpha = 0.001;
33  static constexpr double beta = 2.0;
36  template<std::size_t dim>
37  static constexpr double W0 = 1. / (double(dim) + 2.);
38  };
39 
40 
42 
43 
49  template<typename Parameters = SphericalSimplexParameters>
50  struct SphericalSimplex : oin::ScaledSigmaPointsBase<SphericalSimplex<Parameters>>
51  {
57  template<std::size_t dim>
58  static constexpr size_t sigma_point_count = dim + 2;
59 
60 
65  static constexpr auto alpha = Parameters::alpha;
66 
67 
72  static constexpr auto beta = Parameters::beta;
73 
74 
75  /*
76  * \brief The unscaled W0 parameter.
77  * \tparam dim The total number of dimensions of all inputs.
78  * \note Used by base class.
79  */
80  template<std::size_t dim>
81  static constexpr auto unscaled_W0()
82  {
83  return Parameters::template W0<dim>;
84  }
85 
86 
87  /*
88  * \brief The unscaled W parameter.
89  * \tparam dim The total number of dimensions of all inputs.
90  * \note Used by base class.
91  */
92  template<std::size_t dim>
93  static constexpr auto unscaled_W()
94  {
95  return (1 - Parameters::template W0<dim>) / (sigma_point_count<dim> - 1);
96  }
97 
98  private:
99 
101  SphericalSimplex() {};
102 
103 
104  template<std::size_t j, std::size_t i, std::size_t dim, typename Scalar>
105  static constexpr auto
106  sigma_point_coeff()
107  {
108  constexpr auto denom = 1 / static_cast<std::size_t>(values::sqrt((j + 1)) * (j + 2) * unscaled_W<dim>());
109  if constexpr(i == 0)
110  return Scalar(0);
111  else if constexpr(i < j + 2)
112  return -denom;
113  else if constexpr (i == j + 2)
114  return (j + 1) * denom;
115  else
116  return Scalar(0);
117  }
118 
119 
120  template<typename Dist, std::size_t dim, std::size_t pos, std::size_t...ns>
121  static constexpr auto
122  unscaled_sigma_points(std::index_sequence<ns...>)
123  {
124  using StaticDescriptor = typename DistributionTraits<Dist>::StaticDescriptor;
125  using Scalar = typename DistributionTraits<Dist>::Scalar;
126  constexpr auto rows = index_dimension_of_v<Dist, 0>;
127  constexpr auto count = sigma_point_count<dim>;
128  using M = typename DistributionTraits<Dist>::Mean;
130  Matrix<StaticDescriptor, Dimensions<count>, Xnative> X {sigma_point_coeff<ns / count + pos, ns % count, dim, Scalar>()...};
131  return X;
132  }
133 
134 
135  template<std::size_t dim, std::size_t pos = 0, typename D, typename...Ds>
136  static auto
137  sigma_points_impl(const D& d, const Ds&...ds)
138  {
139  constexpr auto rows = index_dimension_of_v<D, 0>;
140  constexpr auto count = sigma_point_count<dim>;
141  auto X = unscaled_sigma_points<D, dim, pos>(std::make_index_sequence<count * rows> {});
142  // Scale based on covariance:
143  auto ret {make_self_contained(square_root(covariance_of(d)) * alpha * X)};
144  //
145  if constexpr(sizeof...(ds) > 0)
146  return std::tuple_cat(std::tuple {std::move(ret)}, sigma_points_impl<dim, pos + rows>(ds...));
147  else
148  return std::tuple {std::move(ret)};
149  }
150 
151  public:
152 
160 #ifdef __cpp_concepts
161  template<gaussian_distribution ... Dist> requires (sizeof...(Dist) > 0)
162 #else
163  template<typename...Dist, std::enable_if_t<
164  (gaussian_distribution<Dist> and ...) and (sizeof...(Dist) > 0), int> = 0>
165 #endif
166  static constexpr auto
167  sample_points(const Dist&...ds)
168  {
169  constexpr auto dim = (index_dimension_of_v<Dist, 0> + ...);
170  return sigma_points_impl<dim>(ds...);
171  }
172 
173  };
174 
175 
176 }
177 
178 #endif //OPENKALMAN_SPHERICALSIMPLEX_HPP
Definition: ScaledSigmaPointsBase.hpp:37
Spherical simplex sigma points, as implemented in, e.g., Simon J.
Definition: SphericalSimplex.hpp:26
static constexpr double W0
The first weight, 0 <= W0 <= 1.
Definition: SphericalSimplex.hpp:37
static constexpr double alpha
Scaling factor (typically 0.001 but may be from 0.0001 to 1).
Definition: SphericalSimplex.hpp:31
The root namespace for OpenKalman.
Definition: basics.hpp:34
constexpr auto sqrt(const Arg &arg)
A constexpr alternative to std::sqrt.
Definition: sqrt.hpp:46
Definition: SphericalSimplex.hpp:28
static constexpr auto sample_points(const Dist &...ds)
Calculate the scaled and translated sigma points, given a prior distribution and noise terms...
Definition: SphericalSimplex.hpp:167
std::decay_t< decltype(make_dense_object< T, layout, S >(std::declval< D >()))> dense_writable_matrix_t
An alias for a dense, writable matrix, patterned on parameter T.
Definition: dense_writable_matrix_t.hpp:38
constexpr bool gaussian_distribution
T is a Gaussian distribution.
Definition: object-types.hpp:182
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.
Definition: basics.hpp:48
A matrix with typed rows and columns.
Definition: forward-class-declarations.hpp:448
static constexpr double beta
Factor to compensate for the distribution (beta==2 is optimal for Gaussian distributions).
Definition: SphericalSimplex.hpp:33