EmrysFilter
0.1.0
State estimation utilities in C++23 using Eigen
Toggle main menu visibility
Loading...
Searching...
No Matches
Math.h
Go to the documentation of this file.
1
#pragma once
2
57
58
#include <cmath>
59
#include <concepts>
60
#include <numbers>
61
#include <type_traits>
62
63
#include <
EmrysFilter/Core/Macros.h
>
64
65
#include <unsupported/Eigen/AutoDiff>
66
#include <unsupported/Eigen/SpecialFunctions>
67
68
namespace
Emrys
69
{
70
79
template
<
typename
T>
80
concept
RealScalar
=
81
!Eigen::NumTraits<T>::IsInteger && !Eigen::NumTraits<T>::IsComplex &&
requires
(T
const
& a, T
const
& b) {
82
a + b;
83
a - b;
84
a * b;
85
a / b;
86
a < b;
87
};
88
89
namespace
internal
90
{
91
99
template
<
typename
T>
100
inline
constexpr
bool
isAutoDiffScalar =
false
;
101
103
template
<
typename
Derivatives>
104
inline
constexpr
bool
isAutoDiffScalar<Eigen::AutoDiffScalar<Derivatives>>{
true
};
105
107
115
template
<
typename
... Values>
116
requires
(std::is_arithmetic_v<Values> && ...)
117
struct DeducedScalarOf
118
{
120
using
type = std::conditional_t<
121
(std::integral<Values> && ...),
122
double,
123
std::common_type_t<std::conditional_t<std::integral<Values>, float, Values>...>>;
124
};
125
127
template
<
typename
... Values>
128
using
DeducedScalar =
typename
DeducedScalarOf<Values...>::type;
129
130
}
// namespace internal
131
143
template
<
typename
Scalar>
144
[[nodiscard]] Scalar
145
pi
()
146
{
147
using
Literal =
typename
Eigen::NumTraits<Scalar>::Literal;
148
if
constexpr
(std::floating_point<Scalar>)
149
{
150
return
std::numbers::pi_v<Scalar>;
151
}
152
else
if
constexpr
(std::floating_point<Literal>)
153
{
154
return
Scalar(std::numbers::pi_v<Literal>);
155
}
156
else
157
{
158
return
Scalar(4) * Eigen::numext::atan(Scalar(1));
159
}
160
}
161
175
template
<
typename
Scalar>
176
[[nodiscard]] Scalar
177
log2Pi
()
178
{
179
using
Literal =
typename
Eigen::NumTraits<Scalar>::Literal;
180
if
constexpr
(std::floating_point<Scalar>)
181
{
182
return
Scalar(1.83787706640934548356065947281123527972L);
183
}
184
else
if
constexpr
(std::floating_point<Literal>)
185
{
186
return
Scalar(
log2Pi<Literal>
());
187
}
188
else
189
{
190
Scalar
const
twoPi = Scalar(2) *
pi<Scalar>
();
191
return
Eigen::numext::log(twoPi);
192
}
193
}
194
214
template
<
typename
Scalar>
215
[[nodiscard]] Scalar
216
logGamma
(std::type_identity_t<Scalar>
const
& x)
217
{
218
if
constexpr
(std::floating_point<Scalar>)
219
{
220
return
std::lgamma(x);
221
}
222
else
if
constexpr
(internal::isAutoDiffScalar<Scalar>)
223
{
224
using
Real =
typename
Scalar::Real;
225
return
Scalar{
logGamma<Real>
(x.value()), Eigen::numext::digamma(x.value()) * x.derivatives()};
226
}
227
else
228
{
229
return
lgamma(x);
230
}
231
}
232
245
template
<
typename
Scalar>
246
[[nodiscard]] Scalar
247
logOnePlus
(std::type_identity_t<Scalar>
const
& x)
248
{
249
if
constexpr
(std::floating_point<Scalar>)
250
{
251
return
std::log1p(x);
252
}
253
else
if
constexpr
(internal::isAutoDiffScalar<Scalar>)
254
{
255
using
Real =
typename
Scalar::Real;
256
return
Scalar{
logOnePlus<Real>
(x.value()), x.derivatives() / (Real(1) + x.value())};
257
}
258
else
259
{
260
return
Eigen::numext::log1p(x);
261
}
262
}
263
275
template
<
typename
Scalar>
276
[[nodiscard]] Scalar
277
floorOf
(std::type_identity_t<Scalar>
const
& x)
278
{
279
if
constexpr
(std::floating_point<Scalar>)
280
{
281
return
std::floor(x);
282
}
283
else
if
constexpr
(internal::isAutoDiffScalar<Scalar>)
284
{
285
using
Real =
typename
Scalar::Real;
286
return
Scalar{
floorOf<Real>
(x.value()), Scalar::DerType::Zero(x.derivatives().size())};
287
}
288
else
289
{
290
return
Eigen::numext::floor(x);
291
}
292
}
293
303
template
<
typename
T>
304
[[nodiscard]]
bool
305
isFinite
(T
const
& x)
306
{
307
if
constexpr
(std::floating_point<T>)
308
{
309
return
std::isfinite(x);
310
}
311
else
if
constexpr
(internal::isAutoDiffScalar<T>)
312
{
313
return
isFinite
(x.value());
314
}
315
else
316
{
317
return
Eigen::numext::isfinite(x);
318
}
319
}
320
327
template
<
typename
T>
328
[[nodiscard]]
bool
329
isNaN
(T
const
& x)
330
{
331
if
constexpr
(std::floating_point<T>)
332
{
333
return
std::isnan(x);
334
}
335
else
if
constexpr
(internal::isAutoDiffScalar<T>)
336
{
337
return
isNaN
(x.value());
338
}
339
else
340
{
341
return
Eigen::numext::isnan(x);
342
}
343
}
344
352
template
<
typename
Derived>
353
[[nodiscard]]
bool
354
allFinite
(Eigen::DenseBase<Derived>
const
& x)
355
{
356
if
constexpr
(std::floating_point<typename Derived::Scalar>)
357
{
358
return
x.allFinite();
359
}
360
else
361
{
362
for
(Eigen::Index j = 0; j < x.cols(); ++j)
363
{
364
for
(Eigen::Index i = 0; i < x.rows(); ++i)
365
{
366
if
(!
isFinite
(x.coeff(i, j)))
367
{
368
return
false
;
369
}
370
}
371
}
372
return
true
;
373
}
374
}
375
376
namespace
internal
377
{
378
386
template
<
typename
Scalar>
387
[[nodiscard]] Scalar
388
scalarFromCount(std::integral
auto
count)
389
{
390
using
Literal =
typename
Eigen::NumTraits<Scalar>::Literal;
391
if
constexpr
(std::floating_point<Literal>)
392
{
393
return
Scalar(Literal(count));
394
}
395
else
396
{
397
return
Scalar(count);
398
}
399
}
400
406
[[nodiscard]]
consteval
double
407
compileTimeSqrt(
double
x)
408
{
409
if
(x <= 0)
410
{
411
return
0;
412
}
413
double
root = x > 1 ? x : 1;
414
while
(
true
)
415
{
416
double
const
next = (root + x / root) / 2;
417
if
(!(next < root))
418
{
419
return
root;
420
}
421
root = next;
422
}
423
}
424
425
}
// namespace internal
426
427
}
// namespace Emrys
Macros.h
The macros every header includes first.
Emrys::RealScalar
A type usable as the scalar of a distribution: a real number type such as float, double,...
Definition
Math.h:80
Emrys::pi
Scalar pi()
Definition
Math.h:145
Emrys::allFinite
bool allFinite(Eigen::DenseBase< Derived > const &x)
Definition
Math.h:354
Emrys::logOnePlus
Scalar logOnePlus(std::type_identity_t< Scalar > const &x)
Definition
Math.h:247
Emrys::logGamma
Scalar logGamma(std::type_identity_t< Scalar > const &x)
Definition
Math.h:216
Emrys::isNaN
bool isNaN(T const &x)
Definition
Math.h:329
Emrys::floorOf
Scalar floorOf(std::type_identity_t< Scalar > const &x)
Definition
Math.h:277
Emrys::isFinite
bool isFinite(T const &x)
Definition
Math.h:305
Emrys::log2Pi
Scalar log2Pi()
Definition
Math.h:177
EmrysFilter
Core
Math.h
Generated by
1.18.0