GCC Code Coverage Report


Directory: ./
File: include/parametric-curves/polynomial.hpp
Date: 2025-05-07 13:05:43
Exec Total Coverage
Lines: 65 84 77.4%
Branches: 43 94 45.7%

Line Branch Exec Source
1 /**
2 * \file polynomial.hpp
3 * \brief Definition of a cubic spline.
4 * \author Steve T.
5 * \version 0.1
6 * \date 06/17/2013
7 *
8 * This file contains definitions for the Polynomial struct.
9 * It allows the creation and evaluation of natural
10 * smooth splines of arbitrary dimension and order
11 */
12
13 #ifndef _parameteric_curves_polynomial_hpp
14 #define _parameteric_curves_polynomial_hpp
15
16 #include <Eigen/Dense>
17 #include <boost/archive/text_iarchive.hpp>
18 #include <boost/archive/text_oarchive.hpp>
19 #include <parametric-curves/abstract-curve.hpp>
20 #include <parametric-curves/serialization/eigen-matrix.hpp>
21 #include <stdexcept>
22 #include <vector>
23
24 namespace parametriccurves {
25 /// \class Polynomial
26 /// \brief Represents a Polynomialf arbitrary order defined on the interval
27 /// [tBegin, tEnd]. It follows the equation
28 /// x(t) = a + b(t - t_min_) + ... + d(t - t_min_)^N, where N is the order
29 ///
30 template <typename Numeric = double, Eigen::Index Dim = 3,
31 typename Point = Eigen::Matrix<Numeric, Dim, 1> >
32 struct Polynomial : public parametriccurves::AbstractCurve<Numeric, Point> {
33 typedef Point point_t;
34 typedef Numeric time_t;
35 typedef Numeric num_t;
36 typedef std::vector<Point, Eigen::aligned_allocator<Point> > t_point_t;
37 typedef AbstractCurve<Numeric, Point> curve_abc_t;
38 typedef Eigen::Matrix<double, Dim, Eigen::Dynamic> coeff_t;
39 typedef Eigen::Ref<coeff_t> coeff_t_ref;
40
41 public:
42 ///\brief Constructor
43 ///\param coefficients : a reference to an Eigen matrix where each column is a
44 /// coefficient,
45 /// from the zero order coefficient, up to the highest order. Spline order is
46 /// given by the number of the columns -1.
47 ///\param min: LOWER bound on interval definition of the spline
48 ///\param max: UPPER bound on interval definition of the spline
49 1 Polynomial(const coeff_t& coefficients, const time_t tmin, const time_t tmax)
50 : curve_abc_t(tmin, tmax),
51 1 coefficients_(coefficients),
52 1 dim_(Dim),
53
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 order_(coefficients_.cols() - 1) {
54
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 safe_check();
55 1 }
56
57 ///\brief Constructor
58 ///\param coefficients : a container containing all coefficients of the
59 /// spline, starting
60 /// with the zero order coefficient, up to the highest order. Spline order is
61 /// given by the size of the coefficients
62 ///\param min: LOWER bound on interval definition of the spline
63 ///\param max: UPPER bound on interval definition of the spline
64 1 Polynomial(const t_point_t& coefficients, const time_t tmin,
65 const time_t tmax)
66 : curve_abc_t(tmin, tmax),
67
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 coefficients_(init_coeffs(coefficients.begin(), coefficients.end())),
68 1 dim_(Dim),
69 2 order_(coefficients_.cols() - 1) {
70
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 safe_check();
71 1 }
72
73 Polynomial() {}
74
75 ///\brief Constructor
76 ///\param zeroOrderCoefficient : an iterator pointing to the first element of
77 /// a structure containing the coefficients
78 /// it corresponds to the zero degree coefficient
79 ///\param out : an iterator pointing to the last element of a structure
80 /// ofcoefficients \param min: LOWER bound on interval definition of the
81 /// spline \param max: UPPER bound on interval definition of the spline
82 template <typename In>
83 56 Polynomial(In zeroOrderCoefficient, In out, const time_t tmin,
84 const time_t tmax)
85 : curve_abc_t(tmin, tmax),
86 56 coefficients_(init_coeffs(zeroOrderCoefficient, out)),
87 56 dim_(Dim),
88
1/2
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
56 order_(coefficients_.cols() - 1) {
89
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
56 safe_check();
90 56 }
91
92 ///\brief Destructor
93 116 ~Polynomial() {
94 // NOTHING
95 116 }
96
97 54 Polynomial(const Polynomial& other)
98 54 : curve_abc_t(other.t_min, other.t_max),
99 54 coefficients_(other.coefficients_),
100 54 dim_(other.dim_),
101
1/2
✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
54 order_(other.order_) {}
102
103 // Polynomial& operator=(const Polynomial& other);
104
105 private:
106 59 void safe_check() {
107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
59 if (this->t_min > this->t_max) std::out_of_range("TODO");
108
2/2
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 3 times.
59 if (static_cast<std::size_t>(coefficients_.size()) != order_ + 1)
109 53 std::runtime_error("Spline order and coefficients do not match");
110 59 }
111
112 /* Constructors - destructors */
113
114 /*Operations*/
115 public:
116 /*/// \brief Evaluation of the cubic spline at time t.
117 /// \param t : the time when to evaluate the spine
118 /// \param return : the value x(t)
119 virtual point_t operator()(const time_t t) const
120 {
121 if((t < t_min_ || t > t_max_) && Safe){ throw
122 std::out_of_range("TODO");} time_t const dt (t-t_min_); time_t cdt(1);
123 point_t currentPoint_ = point_t::Zero();
124 for(int i = 0; i < order_+1; ++i, cdt*=dt)
125 currentPoint_ += cdt *coefficients_.col(i);
126 return currentPoint_;
127 }*/
128
129 /// \brief Evaluation of the cubic spline at time t using horner's scheme.
130 /// \param t : the time when to evaluate the spine
131 /// \param return : the value x(t)
132 60 virtual const point_t operator()(const time_t& t) const {
133
4/4
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 28 times.
60 if ((t < this->t_min || t > this->t_max)) {
134
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
4 throw std::out_of_range("TODO");
135 }
136 56 const time_t& dt(t);
137
1/2
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
56 point_t h = coefficients_.col(order_);
138 56 std::size_t i = order_ - 1;
139 56 bool ok = true;
140
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
56 if (order_ != 0) {
141
3/4
✓ Branch 0 taken 88 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 88 times.
✗ Branch 3 not taken.
232 while (ok && order_ != 0) {
142
3/6
✓ Branch 2 taken 88 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 88 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 88 times.
✗ Branch 9 not taken.
176 h = dt * h + coefficients_.col(i);
143
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 60 times.
176 if (i == 0)
144 56 ok = false;
145 else
146 120 i--;
147 }
148 56 return h;
149 } else
150 return h;
151 }
152
153 /// \brief Evaluation of the derivative spline at time t.
154 /// \param t : the time when to evaluate the spline
155 /// \param order : order of the derivative
156 /// \param return : the value x(t)
157 48 virtual const point_t derivate(const time_t& t,
158 const std::size_t& order) const {
159
2/4
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
48 if ((t < this->t_min || t > this->t_max)) {
160 throw std::out_of_range("TODO");
161 }
162 48 const time_t& dt(t);
163 48 time_t cdt(1);
164
2/4
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
48 point_t currentPoint_ = point_t::Zero(dim_);
165
2/2
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 24 times.
184 for (std::size_t i = order; i < order_ + 1; ++i, cdt *= dt)
166
4/8
✓ Branch 2 taken 68 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 68 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 68 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 68 times.
✗ Branch 12 not taken.
136 currentPoint_ += cdt * coefficients_.col(i) * fact(i, order);
167 96 return currentPoint_;
168 }
169
170 virtual const std::size_t& size() const { return dim_; }
171
172 virtual bool setInitialPoint(const point_t& /*x_init*/) { return false; }
173 virtual bool setInitialPoint(const num_t& /*x_init*/) { return false; }
174
175 protected:
176 coeff_t coefficients_; // const
177 std::size_t dim_; // const
178 std::size_t order_; // const
179
180 private:
181 // Serialization of the class
182 friend class boost::serialization::access;
183 template <class Archive>
184 void save(Archive& ar, const unsigned int /*version*/) const {
185 ar& boost::serialization::make_nvp("dim", dim_);
186 ar& boost::serialization::make_nvp("order", order_);
187 ar& boost::serialization::make_nvp("coefficients", coefficients_);
188 ar& boost::serialization::make_nvp("t_min", this->t_min);
189 ar& boost::serialization::make_nvp("t_max", this->t_max);
190 }
191
192 template <class Archive>
193 void load(Archive& ar, const unsigned int /*version*/) {
194 ar& boost::serialization::make_nvp("dim", dim_);
195 ar& boost::serialization::make_nvp("order", order_);
196 ar& boost::serialization::make_nvp("coefficients", coefficients_);
197 ar& boost::serialization::make_nvp("t_min", this->t_min);
198 ar& boost::serialization::make_nvp("t_max", this->t_max);
199 }
200
201 BOOST_SERIALIZATION_SPLIT_MEMBER()
202
203 136 num_t fact(const std::size_t n, const std::size_t order) const {
204 136 std::size_t res(1);
205
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 68 times.
328 for (std::size_t i = 0; i < order; ++i) res *= n - i;
206 136 return static_cast<num_t>(res);
207 }
208
209 /*Attributes*/
210 template <typename In>
211 58 coeff_t init_coeffs(In zeroOrderCoefficient, In highestOrderCoefficient) {
212 58 std::size_t size =
213
1/2
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
58 std::distance(zeroOrderCoefficient, highestOrderCoefficient);
214
1/2
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
58 coeff_t res = coeff_t(Dim, size);
215 58 int i = 0;
216
2/2
✓ Branch 1 taken 120 times.
✓ Branch 2 taken 29 times.
298 for (In cit = zeroOrderCoefficient; cit != highestOrderCoefficient;
217 240 ++cit, ++i)
218
2/4
✓ Branch 2 taken 120 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 120 times.
✗ Branch 6 not taken.
240 res.col(i) = *cit;
219 116 return res;
220 }
221 }; // class Polynomial
222 } // namespace parametriccurves
223 #endif //_STRUCT_POLYNOMIAL
224