GCC Code Coverage Report


Directory: ./
File: include/ndcurves/curve_abc.h
Date: 2025-03-05 17:18:30
Exec Total Coverage
Lines: 24 26 92.3%
Branches: 20 30 66.7%

Line Branch Exec Source
1 /**
2 * \file curve_abc.h
3 * \brief interface for a Curve of arbitrary dimension.
4 * \author Steve T.
5 * \version 0.1
6 * \date 06/17/2013
7 *
8 * Interface for a curve
9 */
10
11 #ifndef _STRUCT_CURVE_ABC
12 #define _STRUCT_CURVE_ABC
13
14 #include <functional>
15 #include <memory>
16
17 #include "MathDefs.h"
18 #include "serialization/archive.hpp"
19 #include "serialization/eigen-matrix.hpp"
20 #include "serialization/registeration.hpp"
21
22 namespace ndcurves {
23
24 template <typename T>
25 669 bool isApprox(const T a, const T b, const T eps = 1e-6) {
26 669 return fabs(a - b) < eps;
27 }
28
29 /// \struct curve_abc.
30 /// \brief Represents a curve of dimension Dim.
31 /// If value of parameter Safe is false, no verification is made on the
32 /// evaluation of the curve.
33 template <typename Time = double, typename Numeric = Time, bool Safe = false,
34 typename Point = Eigen::Matrix<Numeric, Eigen::Dynamic, 1>,
35 typename Point_derivate = Point>
36 struct curve_abc : public serialization::Serializable {
37 typedef Point point_t;
38 typedef Point_derivate point_derivate_t;
39 typedef Time time_t;
40 typedef Numeric num_t;
41 typedef curve_abc<Time, Numeric, Safe, point_t, point_derivate_t>
42 curve_t; // parent class
43 typedef curve_abc<Time, Numeric, Safe, point_derivate_t>
44 curve_derivate_t; // parent class
45 typedef std::shared_ptr<curve_t> curve_ptr_t;
46
47 /* Constructors - destructors */
48 public:
49 /// \brief Constructor.
50 50010 curve_abc() {}
51
52 /// \brief Destructor.
53 50076 virtual ~curve_abc() {}
54 /* Constructors - destructors */
55
56 /*Operations*/
57 /// \brief Evaluation of the cubic spline at time t.
58 /// \param t : time when to evaluate the spine
59 /// \return \f$x(t)\f$, point corresponding on curve at time t.
60 virtual point_t operator()(const time_t t) const = 0;
61
62 /// \brief Compute the derived curve at order N.
63 /// \param order : order of derivative.
64 /// \return A pointer to \f$\frac{d^Nx(t)}{dt^N}\f$ derivative order N of the
65 /// curve.
66 virtual curve_derivate_t* compute_derivate_ptr(
67 const std::size_t order) const = 0;
68
69 /// \brief Evaluate the derivative of order N of curve at time t.
70 /// \param t : time when to evaluate the spline.
71 /// \param order : order of derivative.
72 /// \return \f$\frac{d^Nx(t)}{dt^N}\f$, point corresponding on derivative
73 /// curve of order N at time t.
74 virtual point_derivate_t derivate(const time_t t,
75 const std::size_t order) const = 0;
76
77 /**
78 * @brief isEquivalent check if other and *this are approximately equal by
79 * values, given a precision threshold. This test is done by discretizing both
80 * curves and evaluating them and their derivatives.
81 * @param other the other curve to check
82 * @param order the order up to which the derivatives of the curves are
83 * checked for equality
84 * @param prec the precision threshold, default
85 * Eigen::NumTraits<Numeric>::dummy_precision()
86 * @return true if the two curves are approximately equal
87 */
88 28 bool isEquivalent(
89 const curve_t* other,
90 const Numeric prec = Eigen::NumTraits<Numeric>::dummy_precision(),
91 const size_t order = 5) const {
92
1/2
✓ Branch 3 taken 14 times.
✗ Branch 4 not taken.
54 bool equal = ndcurves::isApprox<num_t>(min(), other->min()) &&
93
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 1 times.
54 ndcurves::isApprox<num_t>(max(), other->max()) &&
94
1/2
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
26 (dim() == other->dim());
95
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 14 times.
28 if (!equal) {
96 2 return false;
97 }
98 26 time_t inc =
99 26 (max() - min()) / 10.; // FIXME : define this step somewhere ??
100 // check the value along the two curves
101 26 time_t t = min();
102
2/2
✓ Branch 1 taken 146 times.
✓ Branch 2 taken 14 times.
296 while (t <= max()) {
103
4/8
✓ Branch 2 taken 146 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 146 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 10 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 136 times.
270 if (!(*this)(t).isApprox(other->operator()(t), prec)) {
104 return false;
105 }
106 270 t += inc;
107 }
108 // check if the derivatives are equal
109
2/2
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 14 times.
150 for (size_t n = 1; n <= order; ++n) {
110 124 t = min();
111
2/2
✓ Branch 1 taken 697 times.
✓ Branch 2 taken 67 times.
1408 while (t <= max()) {
112
4/8
✓ Branch 2 taken 697 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 697 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 50 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 647 times.
1284 if (!derivate(t, n).isApprox(other->derivate(t, n), prec)) {
113 return false;
114 }
115 1284 t += inc;
116 }
117 }
118 26 return true;
119 }
120
121 /**
122 * @brief isApprox check if other and *this are approximately equal given a
123 * precision threshold Only two curves of the same class can be approximately
124 * equal, for comparison between different type of curves see isEquivalent.
125 * @param other the other curve to check
126 * @param prec the precision threshold, default
127 * Eigen::NumTraits<Numeric>::dummy_precision()
128 * @return true if the two curves are approximately equal
129 */
130 virtual bool isApprox(
131 const curve_t* other,
132 const Numeric prec =
133 Eigen::NumTraits<Numeric>::dummy_precision()) const = 0;
134
135 /*Operations*/
136
137 /*Helpers*/
138 /// \brief Get dimension of curve.
139 /// \return dimension of curve.
140 virtual std::size_t dim() const = 0;
141 /// \brief Get the minimum time for which the curve is defined.
142 /// \return \f$t_{min}\f$, lower bound of time range.
143 virtual time_t min() const = 0;
144 /// \brief Get the maximum time for which the curve is defined.
145 /// \return \f$t_{max}\f$, upper bound of time range.
146 virtual time_t max() const = 0;
147 /// \brief Get the degree of the curve.
148 /// \return \f$degree\f$, the degree of the curve.
149 virtual std::size_t degree() const = 0;
150
151 std::pair<time_t, time_t> timeRange() { return std::make_pair(min(), max()); }
152 /*Helpers*/
153
154 // Serialization of the class
155 friend class boost::serialization::access;
156 template <class Archive>
157 656 void serialize(Archive& ar, const unsigned int version) {
158 656 serialization::register_types<Archive>(ar, version);
159 if (version) {
160 // Do something depending on version ?
161 }
162 }
163 };
164 BOOST_SERIALIZATION_ASSUME_ABSTRACT(curve_abc)
165 } // namespace ndcurves
166
167 DEFINE_CLASS_TEMPLATE_VERSION(
168 SINGLE_ARG(typename Time, typename Numeric, bool Safe, typename Point,
169 typename Point_derivate),
170 SINGLE_ARG(ndcurves::curve_abc<Time, Numeric, Safe, Point, Point_derivate>))
171 #endif //_STRUCT_CURVE_ABC
172