0.5.0
Loading...
Searching...
No Matches
Math.hpp
Go to the documentation of this file.
1// This file is part of INSTINCT, the INS Toolkit for Integrated
2// Navigation Concepts and Training by the Institute of Navigation of
3// the University of Stuttgart, Germany.
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9/// @file Math.hpp
10/// @brief Simple Math functions
11/// @author T. Topp (topp@ins.uni-stuttgart.de)
12/// @author N. Stahl (HiWi: Elliptical integral)
13/// @date 2023-07-04
14
15#pragma once
16
17#include <concepts>
18#include <cstdint>
19#include <optional>
20#include <type_traits>
21#include <Eigen/Core>
22#include <Eigen/Dense>
23#include <gcem.hpp>
24#include <fmt/format.h>
25
26#include "util/Assert.h"
27
28namespace NAV::math
29{
30
31/// @brief Calculates the factorial of an unsigned integer
32/// @param[in] n Unsigned integer
33/// @return The factorial of 'n'
34uint64_t factorial(uint64_t n);
35
36/// @brief Round the number to the specified amount of digits
37/// @param[in] value Value to round
38/// @param[in] digits Amount of digits
39/// @return The rounded value
40template<std::floating_point T>
41constexpr T round(const T& value, size_t digits)
42{
43 auto factor = std::pow(10, digits);
44 return std::round(value * factor) / factor;
45}
46
47/// @brief Round the number to the specified amount of significant digits
48/// @param[in] value Value to round
49/// @param[in] digits Amount of digits
50/// @return The rounded value
51template<std::floating_point T>
52constexpr T roundSignificantDigits(T value, size_t digits)
53{
54 if (value == 0.0) { return 0.0; }
55 // LOG_DEBUG("value = {:.13e} --> Round to {} digits", value, digits);
56 auto absVal = gcem::abs(value);
57 auto log10 = static_cast<int32_t>(gcem::log10(absVal));
58 auto exp = log10 + (log10 > 0 || (log10 == 0 && absVal >= 1.0));
59 auto fac = static_cast<T>(digits) - static_cast<T>(exp);
60 // LOG_DEBUG(" log10 = {}, exp = {}, fac = {}", log10, exp, fac);
61 auto factor = static_cast<T>(gcem::pow(10.0, fac));
62 // LOG_DEBUG(" factor = {:.0e} --> value * factor = {}", factor, value * factor);
63 // LOG_DEBUG(" round = {} --> ... / factor = {}", gcem::round(value * factor), gcem::round(value * factor) / factor);
64 return static_cast<T>(gcem::round(value * factor) / factor);
65}
66
67/// @brief Interprets the input integer with certain amount of Bits as Output type. Takes care of sign extension
68/// @tparam Out Output type
69/// @tparam Bits Size of the input data
70/// @tparam In Input data type (needs to be bigger than the amount of Bits)
71/// @param[in] in Number as two's complement, with the sign bit (+ or -) occupying the MSB
72/// @return Output type
73template<std::integral Out, size_t Bits, std::integral In>
74constexpr Out interpretAs(In in)
75{
76 static_assert(Bits < sizeof(In) * 8);
77 static_assert(Bits < sizeof(Out) * 8);
78
79 constexpr size_t N = sizeof(Out) * 8 - Bits;
80 return static_cast<Out>(static_cast<Out>((in & static_cast<In>(gcem::pow(2, Bits) - 1)) << N) >> N);
81}
82
83/// @brief Calculates the skew symmetric matrix of the given vector.
84/// This is needed to perform the cross product with a scalar product operation
85/// @tparam Derived Derived Eigen Type
86/// @param[in] a The vector
87/// @return Skew symmetric matrix
88/// @note See Groves (2013) equation (2.50)
89template<typename Derived>
90Eigen::Matrix<typename Derived::Scalar, 3, 3> skewSymmetricMatrix(const Eigen::MatrixBase<Derived>& a)
91{
92 INS_ASSERT_USER_ERROR(a.cols() == 1, "Given Eigen Object must be a vector");
93 INS_ASSERT_USER_ERROR(a.rows() == 3, "Given Vector must have 3 Rows");
94
95 Eigen::Matrix<typename Derived::Scalar, 3, 3> skewMat;
96 skewMat << 0, -a(2), a(1),
97 a(2), 0, -a(0),
98 -a(1), a(0), 0;
99
100 return skewMat;
101}
102
103/// @brief Calculates the square of a skew symmetric matrix of the given vector.
104/// @tparam Derived Derived Eigen Type
105/// @param[in] a The vector
106/// @return Square of skew symmetric matrix
107template<typename Derived>
108Eigen::Matrix<typename Derived::Scalar, 3, 3> skewSymmetricMatrixSquared(const Eigen::MatrixBase<Derived>& a)
109{
110 INS_ASSERT_USER_ERROR(a.cols() == 1, "Given Eigen Object must be a vector");
111 INS_ASSERT_USER_ERROR(a.rows() == 3, "Given Vector must have 3 Rows");
112
113 Eigen::Matrix<typename Derived::Scalar, 3, 3> skewMat2;
114 skewMat2 << std::pow(a(2), 2) + std::pow(a(1), 2), a(0) * a(1), a(0) * a(2),
115 a(0) * a(1), std::pow(a(2), 2) + std::pow(a(0), 2), a(1) * a(2),
116 a(0) * a(2), a(1) * a(2), std::pow(a(0), 2) + std::pow(a(1), 2);
117
118 return skewMat2;
119}
120
121/// @brief Calculates the matrix exponential map of the given vector.
122/// @tparam Derived Derived Eigen Type
123/// @param[in] v The vector
124/// @return The matrix exponential map
125template<typename Derived>
126Eigen::Matrix<typename Derived::Scalar, 3, 3> expMapMatrix(const Eigen::MatrixBase<Derived>& v)
127{
128 INS_ASSERT_USER_ERROR(v.cols() == 1, "Given Eigen Object must be a vector");
129 INS_ASSERT_USER_ERROR(v.rows() == 3, "Given Vector must have 3 Rows");
130
131 return math::skewSymmetricMatrix(v).exp();
132}
133
134/// @brief Calculates the quaternionic exponential map of the given vector.
135/// @tparam Derived Derived Eigen Type
136/// @param[in] v The vector
137/// @return The quaternionic exponential map
138template<typename Derived>
139Eigen::Quaternion<typename Derived::Scalar> expMapQuat(const Eigen::MatrixBase<Derived>& v)
140{
141 INS_ASSERT_USER_ERROR(v.cols() == 1, "Given Eigen Object must be a vector");
142 INS_ASSERT_USER_ERROR(v.rows() == 3, "Given Vector must have 3 Rows");
143
144 Eigen::Vector3<typename Derived::Scalar> omega = 0.5 * v;
145 auto omegaNorm = omega.norm();
146 if (omegaNorm < 1e-9) { return Eigen::Quaternion<typename Derived::Scalar>::Identity(); }
147 Eigen::Vector3<typename Derived::Scalar> quatVec = omega / omegaNorm * std::sin(omegaNorm);
148
149 return { std::cos(omegaNorm), quatVec.x(), quatVec.y(), quatVec.z() };
150}
151
152/// @brief Calculates the right Jacobian of SO(3) which relates additive increments in the tangent space to multiplicative increments applied on the right-hand side
153/// @param[in] phi Vector applied on the right side
154/// @return Right Jacobian J_r
155template<typename Derived>
156[[nodiscard]] Eigen::Matrix3<typename Derived::Scalar> J_r(const Eigen::MatrixBase<Derived>& phi)
157{
158 INS_ASSERT_USER_ERROR(phi.cols() == 1, "Given Eigen Object must be a vector");
159 INS_ASSERT_USER_ERROR(phi.rows() == 3, "Given Vector must have 3 Rows");
160
161 auto phiNorm = phi.norm();
162 auto phiNorm2 = phiNorm * phiNorm;
163 auto phiNorm3 = phiNorm2 * phiNorm;
164 return Eigen::Matrix3<typename Derived::Scalar>::Identity()
165 - (1.0 - std::cos(phiNorm)) / phiNorm2 * skewSymmetricMatrix(phi)
166 + (phiNorm - std::sin(phiNorm)) / phiNorm3 * skewSymmetricMatrixSquared(phi);
167}
168
169/// @brief Calculates the secant of a value (sec(x) = csc(pi/2 - x) = 1 / cos(x))
170template<std::floating_point T>
171T sec(const T& x)
172{
173 return 1.0 / std::cos(x);
174}
175
176/// @brief Calculates the cosecant of a value (csc(x) = sec(pi/2 - x) = 1 / sin(x))
177template<std::floating_point T>
178T csc(const T& x)
179{
180 return 1.0 / std::sin(x);
181}
182
183/// @brief Returns the sign of the given value
184/// @param[in] val Value to get the sign from
185/// @return Sign of the given value
186template<typename T>
187int sgn(const T& val)
188{
189 return (T(0) < val) - (val < T(0));
190}
191
192/// @brief Calculates the state transition matrix 𝚽 limited to specified order in 𝐅𝜏ₛ
193/// @param[in] X Matrix
194/// @param[in] order The order of the Taylor polynom to calculate
195/// @note See \cite Groves2013 Groves, ch. 3.2.3, eq. 3.34, p. 98
196template<typename Derived>
197typename Derived::PlainObject expm(const Eigen::MatrixBase<Derived>& X, size_t order)
198{
199 INS_ASSERT_USER_ERROR(X.rows() == X.cols(), "Matrix exponential calculation only possible for n x n matrices");
200
201 typename Derived::PlainObject e_X;
202
203 if constexpr (Derived::RowsAtCompileTime == Eigen::Dynamic)
204 {
205 e_X = Eigen::MatrixBase<Derived>::Identity(X.rows(), X.cols());
206 }
207 else
208 {
209 e_X = Eigen::MatrixBase<Derived>::Identity();
210 }
211 typename Derived::PlainObject Xpower = X;
212 for (size_t i = 1; i <= order; i++)
213 {
214 e_X += Xpower / static_cast<double>(math::factorial(i));
215
216 if (i < order)
217 {
218 Xpower *= X;
219 }
220 }
221
222 return e_X;
223}
224
225/// @brief Find (L^T D L)-decomposition of Q-matrix via outer product method
226/// @param[in] Qmatrix Symmetric positive definite matrix to be factored
227/// @return L - Factor matrix (strict lower triangular)
228/// @return D - Vector with entries of the diagonal matrix
229/// @note See \cite deJonge1996 de Jonge 1996, Algorithm FMFAC5
230/// @attention Consider using NAV::math::LtDLdecomp_choleskyFact() because it is faster by up to a factor 10
231template<typename Derived>
232std::optional<std::pair<Eigen::Matrix<typename Derived::Scalar, Derived::RowsAtCompileTime, Derived::ColsAtCompileTime>,
233 Eigen::Vector<typename Derived::Scalar, Derived::RowsAtCompileTime>>>
234 LtDLdecomp_outerProduct(const Eigen::MatrixBase<Derived>& Qmatrix)
235{
236 using Eigen::seq;
237
238 auto n = Qmatrix.rows();
239 Eigen::Matrix<typename Derived::Scalar, Derived::RowsAtCompileTime, Derived::ColsAtCompileTime> Q = Qmatrix.template triangularView<Eigen::Lower>();
240 Eigen::Matrix<typename Derived::Scalar, Derived::RowsAtCompileTime, Derived::ColsAtCompileTime> L;
241 Eigen::Vector<typename Derived::Scalar, Derived::RowsAtCompileTime> D;
242
243 if constexpr (Derived::RowsAtCompileTime == Eigen::Dynamic)
244 {
245 L = Eigen::Matrix<typename Derived::Scalar, Eigen::Dynamic, Eigen::Dynamic>::Zero(n, n);
246 D.setZero(n);
247 }
248 else
249 {
250 L = Eigen::Matrix<typename Derived::Scalar, Derived::RowsAtCompileTime, Derived::ColsAtCompileTime>::Zero();
251 D.setZero();
252 }
253
254 for (Eigen::Index i = n - 1; i >= 0; i--)
255 {
256 D(i) = Q(i, i);
257 if (Q(i, i) <= 0.0) { return {}; }
258 L(i, seq(0, i)) = Q(i, seq(0, i)) / std::sqrt(Q(i, i));
259
260 for (Eigen::Index j = 0; j <= i - 1; j++)
261 {
262 Q(j, seq(0, j)) -= L(i, seq(0, j)) * L(i, j);
263 }
264 L(i, seq(0, i)) /= L(i, i);
265 }
266
267 return std::make_pair(L, D);
268}
269
270/// @brief Find (L^T D L)-decomposition of Q-matrix via a backward Cholesky factorization in a bordering method formulation
271/// @param[in] Q Symmetric positive definite matrix to be factored
272/// @return L - Factor matrix (strict lower triangular)
273/// @return D - Vector with entries of the diagonal matrix
274/// @note See \cite deJonge1996 de Jonge 1996, Algorithm FMFAC6
275template<typename Derived>
276std::optional<std::pair<Eigen::Matrix<typename Derived::Scalar, Derived::RowsAtCompileTime, Derived::ColsAtCompileTime>,
277 Eigen::Vector<typename Derived::Scalar, Derived::RowsAtCompileTime>>>
278 LtDLdecomp_choleskyFact(const Eigen::MatrixBase<Derived>& Q)
279{
280 using Eigen::seq;
281
282 auto n = Q.rows();
283 typename Derived::PlainObject L = Q.template triangularView<Eigen::Lower>();
284 Eigen::Vector<typename Derived::Scalar, Derived::RowsAtCompileTime> D;
285 double cmin = 1;
286
287 if constexpr (Derived::RowsAtCompileTime == Eigen::Dynamic) { D.setZero(n); }
288 else { D.setZero(); }
289
290 for (Eigen::Index j = n - 1; j >= 0; j--)
291 {
292 for (Eigen::Index i = n - 1; i >= j + 1; i--)
293 {
294 L(i, j) = (L(i, j) - L(seq(i + 1, n - 1), j).dot(L(seq(i + 1, n - 1), i))) / L(i, i);
295 }
296 double t = L(j, j) - L(seq(j + 1, n - 1), j).dot(L(seq(j + 1, n - 1), j));
297 if (t <= 0.0) { return {}; }
298 double c = t / L(j, j);
299 cmin = std::min(c, cmin);
300 L(j, j) = std::sqrt(t);
301 }
302 for (Eigen::Index i = 0; i < n; i++)
303 {
304 L.row(i).leftCols(i) /= L(i, i);
305 D(i) = std::pow(L(i, i), 2.0);
306 L(i, i) = 1;
307 }
308
309 return std::make_pair(L, D);
310}
311
312/// @brief Calculates the squared norm of the vector and matrix
313///
314/// \anchor eq-squaredNorm \f{equation}{ \label{eq:eq-squaredNorm}
315/// ||\mathbf{\dots}||^2_{\mathbf{Q}} = (\dots)^T \mathbf{Q}^{-1} (\dots)
316/// \f}
317/// @param a Vector
318/// @param Q Covariance matrix of the vector
319/// @return Squared norm
320template<typename DerivedA, typename DerivedQ>
321typename DerivedA::Scalar squaredNormVectorMatrix(const Eigen::MatrixBase<DerivedA>& a, const Eigen::MatrixBase<DerivedQ>& Q)
322{
323 static_assert(DerivedA::ColsAtCompileTime == Eigen::Dynamic || DerivedA::ColsAtCompileTime == 1);
324 INS_ASSERT_USER_ERROR(a.cols() == 1, "Parameter 'a' has to be a vector");
325 INS_ASSERT_USER_ERROR(a.rows() == Q.rows(), "Parameter 'a' and 'Q' need to have same size");
326 INS_ASSERT_USER_ERROR(Q.cols() == Q.rows(), "Parameter 'Q' needs to be quadratic");
327
328 return a.transpose() * Q.inverse() * a;
329}
330
331/// @brief Calculates the cumulative distribution function (CDF) of the standard normal distribution
332///
333/// \anchor eq-normalDistCDF \f{equation}{ \label{eq:eq-normalDistCDF}
334/// \Phi(x) = \int\displaylimits_{-\infty}^x \frac{1}{\sqrt{2\pi}} \exp{\left(-\frac{1}{2} v^2\right)} \text{d}v
335/// \f}
336/// which can be expressed with the error function
337/// \anchor eq-normalDistCDF-erf \f{equation}{ \label{eq:eq-normalDistCDF-erf}
338/// \Phi(x) = \frac{1}{2} \left[ 1 + \text{erf}{\left(\frac{x}{\sqrt{2}}\right)} \right]
339/// \f}
340/// Using the property
341/// \anchor eq-erf-minus \f{equation}{ \label{eq:eq-erf-minus}
342/// \text{erf}{\left( -x \right)} = -\text{erf}{\left( x \right)}
343/// \f}
344/// and the complementary error function
345/// \anchor eq-erfc \f{equation}{ \label{eq:eq-erfc}
346/// \text{erfc}{\left( x \right)} = 1 - \text{erf}{\left( x \right)}
347/// \f}
348/// we can simplify equation \eqref{eq-normalDistCDF-erf} to
349/// \anchor eq-normalDistCDF-erfc \f{equation}{ \label{eq:eq-normalDistCDF-erfc}
350/// \begin{aligned}
351/// \Phi(x) &= \frac{1}{2} \left[ 1 - \text{erf}{\left(-\frac{x}{\sqrt{2}}\right)} \right] \\
352/// &= \frac{1}{2} \text{erfc}{\left(-\frac{x}{\sqrt{2}}\right)}
353/// \end{aligned}
354/// \f}
355///
356/// @param value Value to calculate the CDF for
357double normalCDF(double value);
358
359/// @brief Returns the inverse square root of a matrix
360/// @param matrix Matrix to use
361template<typename Derived>
362[[nodiscard]] typename Derived::PlainObject inverseSqrt(const Eigen::MatrixBase<Derived>& matrix)
363{
364 INS_ASSERT_USER_ERROR(matrix.rows() == matrix.cols(), "Only square matrix supported");
365 if constexpr (std::is_floating_point_v<typename Derived::Scalar>)
366 {
367 return matrix.inverse().sqrt(); // Eigen::SelfAdjointEigenSolver<Eigen::MatrixX<T>>{ covMatrix }.operatorInverseSqrt();
368 }
369 else // Eigen gets problems with ceres::Jet in the .sqrt() function
370 {
371 Eigen::JacobiSVD<Eigen::MatrixX<typename Derived::Scalar>> svd(matrix.inverse(), Eigen::ComputeFullV);
372 typename Derived::PlainObject sqrtInverse = svd.matrixV() * svd.singularValues().cwiseSqrt().asDiagonal() * svd.matrixV().transpose();
373 INS_ASSERT_USER_ERROR(!sqrtInverse.hasNaN(), "The matrix is not invertible");
374 return sqrtInverse;
375 }
376}
377
378/// @brief Change the sign of x according to the value of y
379/// @param[in] x input value
380/// @param[in] y input value
381/// @return -x or +x
382template<typename T>
383T sign(const T& x, const T& y)
384{
385 // similar function 'sign' in fortran
386 if (y >= 0.0)
387 {
388 return fabs(x);
389 }
390 return -1.0 * fabs(x);
391}
392
393/// @brief Linear interpolation between vectors
394/// @param a Left value
395/// @param b Right value
396/// @param t Multiplier. [0, 1] for interpolation
397/// @return a + t * (b - a)
398template<typename Derived>
399typename Derived::PlainObject lerp(const Eigen::MatrixBase<Derived>& a, const Eigen::MatrixBase<Derived>& b, auto t)
400{
401 return a + t * (b - a);
402}
403
404/// Lerp Search Result
406{
407 size_t l; ///< Lower bound index
408 size_t u; ///< Upper bound index (l + 1)
409 double t; ///< [0, 1] for Interpolation, otherwise Extrapolation
410};
411
412/// @brief Searches the value in the data container
413/// @param[in] data Data container
414/// @param[in] value Value to search
415LerpSearchResult lerpSearch(const auto& data, const auto& value)
416{
417 auto i = static_cast<size_t>(std::distance(data.begin(), std::upper_bound(data.begin(), data.end(), value)));
418 if (i > 0) { i--; }
419 if (i == data.size() - 1) { i--; }
420 const auto& lb = data.at(i);
421 const auto& ub = data.at(i + 1);
422 double t = (value - lb) / (ub - lb);
423
424 return { .l = i, .u = i + 1, .t = t };
425}
426
427/// @brief Bilinear interpolation
428/// @param[in] tx Distance in x component to interpolate [0, 1]
429/// @param[in] ty Distance in y component to interpolate [0, 1]
430/// @param[in] c00 Value for tx = ty = 0
431/// @param[in] c10 Value for tx = 1 and ty = 0
432/// @param[in] c01 Value for tx = 0 and ty = 1
433/// @param[in] c11 Value for tx = ty = 1
434///
435/// c01 ------ c11
436/// | |
437/// | |
438/// | |
439/// c00 ------ c10
440///
441/// @note See https://www.scratchapixel.com/lessons/mathematics-physics-for-computer-graphics/interpolation/bilinear-filtering.html
442auto bilinearInterpolation(const auto& tx, const auto& ty,
443 const auto& c00, const auto& c10,
444 const auto& c01, const auto& c11)
445{
446 auto a = c00 * (1.0 - tx) + c10 * tx;
447 auto b = c01 * (1.0 - tx) + c11 * tx;
448 return a * (1.0 - ty) + b * ty;
449 // Alternative implementation:
450 // return (1.0 - tx) * (1.0 - ty) * c00 + tx * (1.0 - ty) * c10 + (1.0 - tx) * ty * c01 + tx * ty * c11;
451}
452
453/// @brief Calculates the incomplete elliptical integral of the second kind
454/// @param[in] phi Interval bound the integration uses from 0 to phi
455/// @param[in] m Function parameter that is integrated 1-m*sin(t)^2
456/// @return Incomplete elliptical integral of the second kind
457/// @note See http://www2.iap.fr/users/pichon/doc/html_xref/elliptic-es.html
458double calcEllipticalIntegral(double phi, double m);
459
460} // namespace NAV::math
Assertion helpers.
#define INS_ASSERT_USER_ERROR(_EXP, _MSG)
Assert function with message.
Definition Assert.h:21
T sec(const T &x)
Calculates the secant of a value (sec(x) = csc(pi/2 - x) = 1 / cos(x))
Definition Math.hpp:171
LerpSearchResult lerpSearch(const auto &data, const auto &value)
Searches the value in the data container.
Definition Math.hpp:415
Eigen::Quaternion< typename Derived::Scalar > expMapQuat(const Eigen::MatrixBase< Derived > &v)
Calculates the quaternionic exponential map of the given vector.
Definition Math.hpp:139
T csc(const T &x)
Calculates the cosecant of a value (csc(x) = sec(pi/2 - x) = 1 / sin(x))
Definition Math.hpp:178
DerivedA::Scalar squaredNormVectorMatrix(const Eigen::MatrixBase< DerivedA > &a, const Eigen::MatrixBase< DerivedQ > &Q)
Calculates the squared norm of the vector and matrix.
Definition Math.hpp:321
Derived::PlainObject expm(const Eigen::MatrixBase< Derived > &X, size_t order)
Calculates the state transition matrix 𝚽 limited to specified order in 𝐅𝜏ₛ
Definition Math.hpp:197
Eigen::Matrix< typename Derived::Scalar, 3, 3 > expMapMatrix(const Eigen::MatrixBase< Derived > &v)
Calculates the matrix exponential map of the given vector.
Definition Math.hpp:126
int sgn(const T &val)
Returns the sign of the given value.
Definition Math.hpp:187
std::optional< std::pair< Eigen::Matrix< typename Derived::Scalar, Derived::RowsAtCompileTime, Derived::ColsAtCompileTime >, Eigen::Vector< typename Derived::Scalar, Derived::RowsAtCompileTime > > > LtDLdecomp_outerProduct(const Eigen::MatrixBase< Derived > &Qmatrix)
Find (L^T D L)-decomposition of Q-matrix via outer product method.
Definition Math.hpp:234
T sign(const T &x, const T &y)
Change the sign of x according to the value of y.
Definition Math.hpp:383
Eigen::Matrix< typename Derived::Scalar, 3, 3 > skewSymmetricMatrixSquared(const Eigen::MatrixBase< Derived > &a)
Calculates the square of a skew symmetric matrix of the given vector.
Definition Math.hpp:108
auto bilinearInterpolation(const auto &tx, const auto &ty, const auto &c00, const auto &c10, const auto &c01, const auto &c11)
Bilinear interpolation.
Definition Math.hpp:442
constexpr T roundSignificantDigits(T value, size_t digits)
Round the number to the specified amount of significant digits.
Definition Math.hpp:52
Derived::PlainObject lerp(const Eigen::MatrixBase< Derived > &a, const Eigen::MatrixBase< Derived > &b, auto t)
Linear interpolation between vectors.
Definition Math.hpp:399
Eigen::Matrix3< typename Derived::Scalar > J_r(const Eigen::MatrixBase< Derived > &phi)
Calculates the right Jacobian of SO(3) which relates additive increments in the tangent space to mult...
Definition Math.hpp:156
double calcEllipticalIntegral(double phi, double m)
Calculates the incomplete elliptical integral of the second kind.
Definition Math.cpp:53
Eigen::Matrix< typename Derived::Scalar, 3, 3 > skewSymmetricMatrix(const Eigen::MatrixBase< Derived > &a)
Calculates the skew symmetric matrix of the given vector. This is needed to perform the cross product...
Definition Math.hpp:90
uint64_t factorial(uint64_t n)
Calculates the factorial of an unsigned integer.
Definition Math.cpp:14
double normalCDF(double value)
Calculates the cumulative distribution function (CDF) of the standard normal distribution.
Definition Math.cpp:48
constexpr T round(const T &value, size_t digits)
Round the number to the specified amount of digits.
Definition Math.hpp:41
constexpr Out interpretAs(In in)
Interprets the input integer with certain amount of Bits as Output type. Takes care of sign extension...
Definition Math.hpp:74
Derived::PlainObject inverseSqrt(const Eigen::MatrixBase< Derived > &matrix)
Returns the inverse square root of a matrix.
Definition Math.hpp:362
std::optional< std::pair< Eigen::Matrix< typename Derived::Scalar, Derived::RowsAtCompileTime, Derived::ColsAtCompileTime >, Eigen::Vector< typename Derived::Scalar, Derived::RowsAtCompileTime > > > LtDLdecomp_choleskyFact(const Eigen::MatrixBase< Derived > &Q)
Find (L^T D L)-decomposition of Q-matrix via a backward Cholesky factorization in a bordering method ...
Definition Math.hpp:278
Lerp Search Result.
Definition Math.hpp:406
size_t u
Upper bound index (l + 1)
Definition Math.hpp:408
double t
[0, 1] for Interpolation, otherwise Extrapolation
Definition Math.hpp:409
size_t l
Lower bound index.
Definition Math.hpp:407