INSTINCT Code Coverage Report


Directory: src/
File: Navigation/Math/Polynomial.hpp
Date: 2025-02-07 16:54:41
Exec Total Coverage
Lines: 24 25 96.0%
Functions: 5 5 100.0%
Branches: 23 34 67.6%

Line Branch Exec Source
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 Polynomial.hpp
10 /// @brief Polynomial
11 /// @author T. Topp (topp@ins.uni-stuttgart.de)
12 /// @date 2023-10-23
13
14 #pragma once
15
16 #include <cmath>
17 #include <iostream>
18 #include "util/Eigen.hpp"
19
20 namespace NAV
21 {
22
23 /// @brief Polynomial
24 template<typename Scalar>
25 class Polynomial
26 {
27 public:
28 /// @brief Constructor
29 /// @param coefficients Polynomial coefficients in order a0 + a1 * x + a2 * x^2 + ...
30 template<typename Derived>
31 351183 Polynomial(const Eigen::DenseBase<Derived>& coefficients) // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
32 351183 : _coefficients(coefficients)
33 351183 {}
34
35 /// @brief Calculates the polynomial value at given x
36 /// @param x X value
37 290666 [[nodiscard]] Scalar f(Scalar x) const
38 {
39 290666 Scalar value = 0;
40 290666 auto xpow = static_cast<Scalar>(1.0);
41
4/6
✓ Branch 1 taken 290666 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 290666 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 581328 times.
✓ Branch 9 taken 290666 times.
1162660 for (const auto& coeff : _coefficients)
42 {
43 581328 value += coeff * xpow;
44
1/2
✓ Branch 1 taken 581328 times.
✗ Branch 2 not taken.
581328 xpow *= x;
45 }
46 290666 return value;
47 }
48
49 /// @brief Calculates the derivative of the polynomial
50 [[nodiscard]] Polynomial<Scalar> getDerivative() const
51 {
52 int degree = _coefficients.size() - 1;
53 Eigen::VectorX<Scalar> derivative = Eigen::VectorX<Scalar>::Zero(degree);
54 for (int i = 0; i < degree; i++)
55 {
56 derivative(i) = (i + 1) * _coefficients(i + 1);
57 }
58 return Polynomial<Scalar>(derivative);
59 }
60
61 /// @brief Returns the coefficients
62 64754 [[nodiscard]] const Eigen::VectorX<Scalar>& coeffs() const
63 {
64 64754 return _coefficients;
65 }
66
67 /// @brief Format the polynomial as a string
68 /// @param[in] fmt Format string for the polynomial coefficients
69 /// @param[in] var Variable name to use
70 3010 [[nodiscard]] std::string toString(fmt::format_string<double> fmt = "{:.1e}", const char* var = "x") const
71 {
72 3010 std::string out;
73
2/2
✓ Branch 2 taken 9015 times.
✓ Branch 3 taken 3010 times.
12025 for (int i = 0; i < _coefficients.rows(); i++)
74 {
75
1/2
✓ Branch 1 taken 9015 times.
✗ Branch 2 not taken.
9015 bool positive = _coefficients(i) >= 0;
76
1/2
✓ Branch 1 taken 9015 times.
✗ Branch 2 not taken.
9015 std::string a = fmt::format(fmt, std::abs(_coefficients(i)));
77
2/2
✓ Branch 0 taken 3010 times.
✓ Branch 1 taken 6005 times.
9015 if (i == 0)
78 {
79
3/4
✓ Branch 0 taken 2940 times.
✓ Branch 1 taken 70 times.
✓ Branch 4 taken 3010 times.
✗ Branch 5 not taken.
6020 out += fmt::format("{}{}", positive ? "" : "-", a);
80 }
81 else
82 {
83
3/4
✓ Branch 0 taken 3125 times.
✓ Branch 1 taken 2880 times.
✓ Branch 4 taken 6005 times.
✗ Branch 5 not taken.
12010 out += fmt::format(" {} {}{}{}",
84 positive ? "+" : "-",
85 a,
86 var,
87
5/8
✓ Branch 0 taken 3000 times.
✓ Branch 1 taken 3005 times.
✓ Branch 4 taken 3005 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3005 times.
✓ Branch 8 taken 3000 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
21020 i > 1 ? fmt::format("^{}", i) : "");
88 }
89 }
90 3010 return out;
91 }
92
93 private:
94 /// @brief Polynomial coefficients in order a0 + a1 * x + a2 * x^2 + ...
95 Eigen::VectorX<Scalar> _coefficients;
96 };
97
98 } // namespace NAV
99
100 #ifndef DOXYGEN_IGNORE
101
102 /// @brief Formatter for Polynomial<Scalar>
103 template<typename Scalar>
104 struct fmt::formatter<NAV::Polynomial<Scalar>> : fmt::formatter<std::string>
105 {
106 /// @brief Defines how to format Polynomial structs
107 /// @param[in] poly Struct to format
108 /// @param[in, out] ctx Format context
109 /// @return Output iterator
110 template<typename FormatContext>
111 5 auto format(const NAV::Polynomial<Scalar>& poly, FormatContext& ctx) const
112 {
113
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
10 return fmt::formatter<std::string>::format(poly.toString(), ctx);
114 }
115 };
116
117 #endif
118
119 /// @brief Stream insertion operator overload
120 /// @param[in, out] os Output stream object to stream the time into
121 /// @param[in] obj Object to print
122 /// @return Returns the output stream object in order to chain stream insertions
123 template<typename Scalar>
124 std::ostream& operator<<(std::ostream& os, const NAV::Polynomial<Scalar>& obj)
125 {
126 return os << fmt::format("{}", obj);
127 }
128