EmrysFilter 0.1.0
State estimation utilities in C++23 using Eigen
Loading...
Searching...
No Matches
Coordinates.h
Go to the documentation of this file.
1#pragma once
2
9
10#include <limits>
11#include <numbers>
12
15
16namespace Emrys
17{
18
19namespace internal
20{
21
25template <int Dimension, int MaxDimension>
26class LeafExtent
27{
28public:
29
31 [[nodiscard]] static constexpr Eigen::Index
32 valueDimension()
33 {
34 return Dimension;
35 }
36
38 friend bool
39 operator==(LeafExtent const &, LeafExtent const &) = default;
40};
41
43template <int MaxDimension>
44class LeafExtent<Eigen::Dynamic, MaxDimension>
45{
46public:
47
49 [[nodiscard]] Eigen::Index
50 valueDimension() const
51 {
52 return m_size;
53 }
54
56 void
57 resize(Eigen::Index n)
58 {
59 EMRYS_FILTER_ASSERT(
60 n >= 0 && (MaxDimension == Eigen::Dynamic || n <= MaxDimension) && "the dimension does not fit the space"
61 );
62 m_size = n;
63 }
64
66 friend bool
67 operator==(LeafExtent const &, LeafExtent const &) = default;
68
69private:
70
71 Eigen::Index m_size = 0;
72};
73
74} // namespace internal
75
85template <int Dimension_ = 1, int MaxDimension_ = Dimension_>
86struct Linear : internal::LeafExtent<Dimension_, MaxDimension_>
87{
88 static_assert(Dimension_ == Eigen::Dynamic || Dimension_ >= 0);
89 static_assert(Dimension_ == Eigen::Dynamic || MaxDimension_ == Dimension_, "a fixed size is its own maximum");
90 static constexpr int FixedValueDimension =
91 Dimension_ == Eigen::Dynamic ? 0 : Dimension_;
92 static constexpr int ValueDimensionStep =
93 Dimension_ == Eigen::Dynamic ? 1 : 0;
94 static constexpr int MaxValueDimension = MaxDimension_;
95
96 Linear() = default;
97
99 explicit Linear(Eigen::Index n)
100 requires(Dimension_ == Eigen::Dynamic)
101 {
102 this->resize(n);
103 }
104
106 [[nodiscard]] Linear
108 {
109 return *this;
110 }
111
113 friend bool
114 operator==(Linear const &, Linear const &) = default;
115};
116
123{
124 double lower = std::numeric_limits<double>::quiet_NaN();
125 double upper = std::numeric_limits<double>::quiet_NaN();
126};
127
142template <PeriodicInterval Interval, int Dimension_ = 1, int MaxDimension_ = Dimension_>
143class Periodic : public internal::LeafExtent<Dimension_, MaxDimension_>
144{
145public:
146
147 static_assert(Dimension_ == Eigen::Dynamic || Dimension_ >= 1);
148 static_assert(Dimension_ == Eigen::Dynamic || MaxDimension_ == Dimension_, "a fixed size is its own maximum");
149 static_assert(Interval.lower == Interval.lower, "the lower end must be given");
150 static_assert(Interval.upper == Interval.upper, "the upper end must be given");
151 static_assert(Interval.lower < Interval.upper, "the upper end must be above the lower");
152
153 static_assert(
154 Interval.upper - Interval.lower < std::numeric_limits<double>::infinity(),
155 "the period must be finite"
156 );
157
158 static constexpr int FixedValueDimension =
159 Dimension_ == Eigen::Dynamic ? 0 : Dimension_;
160 static constexpr int ValueDimensionStep =
161 Dimension_ == Eigen::Dynamic ? 1 : 0;
162 static constexpr int MaxValueDimension = MaxDimension_;
163
164 Periodic() = default;
165
167 explicit Periodic(Eigen::Index n)
168 requires(Dimension_ == Eigen::Dynamic)
169 {
170 this->resize(n);
171 }
172
174 [[nodiscard]] static consteval double
176 {
177 return Interval.lower;
178 }
179
181 [[nodiscard]] static consteval double
183 {
184 return Interval.upper;
185 }
186
188 [[nodiscard]] static consteval double
190 {
191 return Interval.upper - Interval.lower;
192 }
193
197 template <typename Derived>
198 void
199 normalize(Eigen::MatrixBase<Derived> const & block) const
200 {
201 writable(block) = block.unaryExpr([](auto x) {
202 return internal::wrapValue<lower(), period()>(x);
203 });
204 }
205
207 [[nodiscard]] auto
209 {
210 using Difference =
211 Periodic<PeriodicInterval{.lower = -period() / 2, .upper = period() / 2}, Dimension_, MaxDimension_>;
212 if constexpr (Dimension_ == Eigen::Dynamic)
213 {
214 return Difference{this->valueDimension()};
215 }
216 else
217 {
218 return Difference{};
219 }
220 }
221
223 friend bool
224 operator==(Periodic const &, Periodic const &) = default;
225};
226
230template <int Dimension = 1, int MaxDimension = Dimension>
232 Periodic<PeriodicInterval{.lower = -std::numbers::pi, .upper = std::numbers::pi}, Dimension, MaxDimension>;
233
237template <int Dimension = 1, int MaxDimension = Dimension>
238using Radians2Pi = Periodic<PeriodicInterval{.lower = 0.0, .upper = 2 * std::numbers::pi}, Dimension, MaxDimension>;
239
243template <int Dimension = 1, int MaxDimension = Dimension>
244using Degrees180 = Periodic<PeriodicInterval{.lower = -180.0, .upper = 180.0}, Dimension, MaxDimension>;
245
249template <int Dimension = 1, int MaxDimension = Dimension>
250using Degrees360 = Periodic<PeriodicInterval{.lower = 0.0, .upper = 360.0}, Dimension, MaxDimension>;
251
252} // namespace Emrys
The macros every header includes first.
The Space concept and what every continuous space shares (decisions.md [sizes-and-dimensions]): the t...
Dimension_ coordinates that wrap with a common period, such as angles or DFT bins.
Definition Coordinates.h:144
static consteval double period()
Definition Coordinates.h:189
static consteval double upper()
Definition Coordinates.h:182
void normalize(Eigen::MatrixBase< Derived > const &block) const
Wraps every value in block into [lower(), upper()), writing through the const reference (see writable...
Definition Coordinates.h:199
friend bool operator==(Periodic const &, Periodic const &)=default
Equal when every stored parameter and size is; a fixed-size Periodic is always equal.
Periodic(Eigen::Index n)
n coordinates of a resizable Periodic.
Definition Coordinates.h:167
auto difference() const
The Periodic on [-period()/2, period()/2), with the same size.
Definition Coordinates.h:208
static consteval double lower()
Definition Coordinates.h:175
Eigen::MatrixBase< Derived > & writable(Eigen::MatrixBase< Derived > const &block)
block, writable: Eigen's idiom for a function that writes through an expression passed as const&.
Definition Space.h:389
auto block(Space auto const &space, X &&x)
Definition TagPath.h:979
Periodic< PeriodicInterval{.lower=0.0,.upper=360.0}, Dimension, MaxDimension > Degrees360
Dimension angles in degrees, in [0, 360), such as a compass heading.
Definition Coordinates.h:250
Periodic< PeriodicInterval{.lower=-std::numbers::pi,.upper=std::numbers::pi}, Dimension, MaxDimension > RadiansPi
Dimension angles in radians, in [-π, π).
Definition Coordinates.h:231
Periodic< PeriodicInterval{.lower=-180.0,.upper=180.0}, Dimension, MaxDimension > Degrees180
Dimension angles in degrees, in [-180, 180).
Definition Coordinates.h:244
Periodic< PeriodicInterval{.lower=0.0,.upper=2 *std::numbers::pi}, Dimension, MaxDimension > Radians2Pi
Dimension angles in radians, in [0, 2π).
Definition Coordinates.h:238
Dimension_ plain coordinates, or a resizable run of at most MaxDimension_ of them if Dimension_ is Ei...
Definition Coordinates.h:87
Linear difference() const
The Linear of the same sizes, which a tag derived from this one does not carry.
Definition Coordinates.h:107
static constexpr int ValueDimensionStep
Definition Coordinates.h:92
static constexpr int MaxValueDimension
Definition Coordinates.h:94
Linear(Eigen::Index n)
n coordinates of a resizable Linear.
Definition Coordinates.h:99
friend bool operator==(Linear const &, Linear const &)=default
Equal when every stored parameter and size is; a fixed-size Linear is always equal.
static constexpr int FixedValueDimension
Definition Coordinates.h:90
Where a Periodic coordinate's values lie: the half-open interval [lower, upper), whose width is the p...
Definition Coordinates.h:123
double upper
the excluded upper end, lower + period
Definition Coordinates.h:125
double lower
the included lower end
Definition Coordinates.h:124