GCC Code Coverage Report


Directory: ./
File: include/ndcurves/optimization/details.h
Date: 2025-03-05 17:18:30
Exec Total Coverage
Lines: 192 203 94.6%
Branches: 180 322 55.9%

Line Branch Exec Source
1 /**
2 * \file bezier_curve.h
3 * \brief class allowing to create a Bezier curve of dimension 1 <= n <= 3.
4 * \author Steve T.
5 * \version 0.1
6 * \date 06/17/2013
7 */
8
9 #ifndef _CLASS_LINEAR_PROBLEM_DETAILS
10 #define _CLASS_LINEAR_PROBLEM_DETAILS
11
12 #include <ndcurves/bernstein.h>
13 #include <ndcurves/bezier_curve.h>
14 #include <ndcurves/curve_constraint.h>
15 #include <ndcurves/linear_variable.h>
16 #include <ndcurves/optimization/definitions.h>
17
18 namespace ndcurves {
19 namespace optimization {
20 template <typename Point, typename Numeric, bool Safe = true>
21 struct problem_data {
22 29 problem_data(const std::size_t dim) : bezier(0), dim_(dim) {}
23 37 ~problem_data() {
24
2/4
✓ Branch 0 taken 37 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 37 times.
✗ Branch 3 not taken.
37 if (bezier) delete bezier;
25 37 }
26
27 typedef linear_variable<Numeric> var_t;
28 typedef std::vector<var_t> T_var_t;
29 typedef bezier_curve<Numeric, Numeric, true, linear_variable<Numeric> >
30 bezier_t;
31
32 std::vector<var_t> variables_; // includes constant variables
33 std::size_t numVariables; // total number of variable (/ DIM for total size)
34 std::size_t numControlPoints; // total number of control Points (variables +
35 // waypoints) / DIM )
36 std::size_t startVariableIndex; // before that index, variables are constant
37 std::size_t numStateConstraints;
38 bezier_t* bezier;
39 const std::size_t dim_;
40
41 8 problem_data(const problem_data& other)
42 8 : variables_(other.variables_),
43 8 numVariables(other.numVariables),
44 8 numControlPoints(other.numControlPoints),
45 8 startVariableIndex(other.startVariableIndex),
46 8 numStateConstraints(other.numStateConstraints),
47 8 dim_(other.dim_) {
48 8 const bezier_t& b = *other.bezier;
49
1/2
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
8 bezier = new bezier_t(b.waypoints().begin(), b.waypoints().end(), b.T_min_,
50
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 b.T_max_, b.mult_T_);
51 8 }
52 };
53
54 33 inline std::size_t num_active_constraints(const constraint_flag& flag) {
55 33 long lValue = (long)(flag);
56 33 std::size_t iCount = 0;
57
2/2
✓ Branch 0 taken 89 times.
✓ Branch 1 taken 33 times.
122 while (lValue != 0) {
58 89 lValue = lValue & (lValue - 1);
59 89 iCount++;
60 }
61
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 30 times.
33 return (flag & NONE) ? iCount - 1 : iCount;
62 }
63
64 template <typename Numeric, typename LinearVar>
65 223 LinearVar fill_with_zeros(const LinearVar& var, const std::size_t i,
66 const std::size_t startVariableIndex,
67 const std::size_t numVariables,
68 const std::size_t Dim) {
69 typedef Eigen::Matrix<Numeric, Eigen::Dynamic, Eigen::Dynamic> matrix_t;
70
1/2
✓ Branch 1 taken 223 times.
✗ Branch 2 not taken.
223 typename LinearVar::matrix_x_t B;
71
2/4
✓ Branch 1 taken 223 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 223 times.
✗ Branch 5 not taken.
223 B = matrix_t::Zero(Dim, numVariables * Dim);
72
7/8
✓ Branch 0 taken 193 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 168 times.
✓ Branch 3 taken 25 times.
✓ Branch 4 taken 168 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 168 times.
✓ Branch 7 taken 55 times.
391 if (startVariableIndex <= i && i <= startVariableIndex + numVariables - 1 &&
73 168 var.size() > 0)
74
2/4
✓ Branch 2 taken 168 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 168 times.
✗ Branch 6 not taken.
168 B.block(0, Dim * (i - startVariableIndex), Dim, Dim) = var.B();
75
1/2
✓ Branch 2 taken 223 times.
✗ Branch 3 not taken.
446 return LinearVar(B, var.c());
76 223 }
77
78 template <typename Point, typename Numeric, typename Bezier, typename LinearVar>
79 29 Bezier* compute_linear_control_points(const problem_data<Point, Numeric>& pData,
80 const std::vector<LinearVar>& linearVars,
81 const Numeric totalTime) {
82 29 std::vector<LinearVar> res;
83 // now need to fill all this with zeros...
84 29 std::size_t totalvar = linearVars.size();
85
2/2
✓ Branch 0 taken 223 times.
✓ Branch 1 taken 29 times.
252 for (std::size_t i = 0; i < totalvar; ++i)
86
2/4
✓ Branch 1 taken 223 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 223 times.
✗ Branch 5 not taken.
223 res.push_back(fill_with_zeros<Numeric, LinearVar>(
87 223 linearVars[i], i, pData.startVariableIndex, pData.numVariables,
88 223 pData.dim_));
89
2/4
✓ Branch 3 taken 29 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 29 times.
✗ Branch 7 not taken.
58 return new Bezier(res.begin(), res.end(), 0., totalTime);
90 29 }
91
92 template <typename Point, typename Numeric, bool Safe>
93 33 problem_data<Point, Numeric, Safe> setup_control_points(
94 const problem_definition<Point, Numeric>& pDef) {
95 typedef Numeric num_t;
96 typedef Point point_t;
97 typedef linear_variable<Numeric> var_t;
98 typedef problem_data<Point, Numeric> problem_data_t;
99
100 33 const std::size_t& degree = pDef.degree;
101 33 const constraint_flag& flag = pDef.flag;
102
103 33 const std::size_t numControlPoints = pDef.degree + 1;
104 33 const std::size_t numActiveConstraints = num_active_constraints(flag);
105
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 29 times.
33 if (numActiveConstraints >= numControlPoints)
106
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 throw std::runtime_error(
107 "In setup_control_points; too many constraints for the considered "
108 "degree");
109
110 29 problem_data_t problemData(pDef.dim_);
111 29 typename problem_data_t::T_var_t& variables_ = problemData.variables_;
112
113 29 std::size_t numConstants = 0;
114 29 std::size_t i = 0;
115
2/2
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 14 times.
29 if (flag & INIT_POS) {
116
3/6
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
15 variables_.push_back(var_t(pDef.init_pos));
117 15 ++numConstants;
118 15 ++i;
119
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 5 times.
15 if (flag & INIT_VEL) {
120
2/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
20 point_t vel =
121
2/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
20 pDef.init_pos + (pDef.init_vel / (num_t)degree) / pDef.totalTime;
122
3/6
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
10 variables_.push_back(var_t(vel));
123 10 ++numConstants;
124 10 ++i;
125
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 6 times.
10 if (flag & INIT_ACC) {
126
4/8
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
4 point_t acc = (pDef.init_acc / (num_t)(degree * (degree - 1))) /
127
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 (pDef.totalTime * pDef.totalTime) +
128
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 2 * vel - pDef.init_pos;
129 ;
130
3/6
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
4 variables_.push_back(var_t(acc));
131 4 ++numConstants;
132 4 ++i;
133
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
4 if (flag & INIT_JERK) {
134
7/14
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
1 point_t jerk = pDef.init_jerk * pDef.totalTime * pDef.totalTime *
135 1 pDef.totalTime /
136
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 (num_t)(degree * (degree - 1) * (degree - 2)) +
137
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 3 * acc - 3 * vel + pDef.init_pos;
138
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
1 variables_.push_back(var_t(jerk));
139 1 ++numConstants;
140 1 ++i;
141 }
142 2 }
143 4 }
144 }
145 29 const std::size_t first_variable_idx = i;
146 // variables
147
2/2
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 29 times.
114 for (; i + 4 < numControlPoints; ++i)
148
2/4
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 85 times.
✗ Branch 5 not taken.
85 variables_.push_back(var_t::X(pDef.dim_));
149 // end constraints
150
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 17 times.
29 if (flag & END_POS) {
151
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 5 times.
12 if (flag & END_VEL) {
152
2/4
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
14 point_t vel =
153
2/4
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
14 pDef.end_pos - (pDef.end_vel / (num_t)degree) / pDef.totalTime;
154
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 2 times.
7 if (flag & END_ACC) {
155
5/10
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 5 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 5 times.
✗ Branch 14 not taken.
5 point_t acc = (pDef.end_acc / (num_t)(degree * (degree - 1))) /
156
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 (pDef.totalTime) * (pDef.totalTime) +
157
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 2 * vel - pDef.end_pos;
158
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 4 times.
5 if (flag & END_JERK) {
159
8/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
1 point_t jerk = -pDef.end_jerk * pDef.totalTime * pDef.totalTime *
160 1 pDef.totalTime /
161
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 (num_t)(degree * (degree - 1) * (degree - 2)) +
162
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 3 * acc - 3 * vel + pDef.end_pos;
163
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
1 variables_.push_back(var_t(jerk));
164 1 ++numConstants;
165 1 ++i;
166 } else
167
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 while (i < numControlPoints - 3) {
168
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 variables_.push_back(var_t::X(pDef.dim_));
169 4 ++i;
170 }
171
3/6
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
5 variables_.push_back(var_t(acc));
172 5 ++numConstants;
173 5 ++i;
174 2 } else
175
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 while (i < numControlPoints - 2) {
176
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 variables_.push_back(var_t::X(pDef.dim_));
177 4 ++i;
178 }
179
3/6
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5 times.
✗ Branch 8 not taken.
7 variables_.push_back(var_t(vel));
180 7 ++numConstants;
181 7 ++i;
182 2 } else {
183
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 5 times.
15 while (i < numControlPoints - 1) {
184
2/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
10 variables_.push_back(var_t::X(pDef.dim_));
185 10 ++i;
186 }
187 }
188
3/6
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
12 variables_.push_back(var_t(pDef.end_pos));
189 12 ++numConstants;
190 12 ++i;
191 }
192 // add remaining variables (only if no end_pos constraints)
193
4/6
✓ Branch 1 taken 65 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 65 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 65 times.
✓ Branch 8 taken 29 times.
94 for (; i < numControlPoints; ++i) variables_.push_back(var_t::X(pDef.dim_));
194
195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
29 if (numControlPoints <= numConstants) {
196 throw std::runtime_error("numControlPoints < numConstants");
197 }
198
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
29 if (numControlPoints != variables_.size()) {
199 throw std::runtime_error("numControlPoints != variables_.size()");
200 }
201
202 29 problemData.numControlPoints = numControlPoints;
203 29 problemData.numVariables = numControlPoints - numConstants;
204 29 problemData.startVariableIndex = first_variable_idx;
205 29 problemData.numStateConstraints =
206 29 numActiveConstraints - problemData.numVariables;
207 29 problemData.bezier = compute_linear_control_points<
208 58 Point, Numeric, bezier_curve<Numeric, Numeric, true, var_t>, var_t>(
209
1/2
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
29 problemData, variables_, pDef.totalTime);
210 29 return problemData;
211 }
212
213 // TODO assumes constant are inside constraints...
214 template <typename Point, typename Numeric>
215 2 long compute_num_ineq_control_points(
216 const problem_definition<Point, Numeric>& pDef,
217 const problem_data<Point, Numeric>& pData) {
218 typedef problem_definition<Point, Numeric> problem_definition_t;
219 2 long rows(0);
220 // rows depends on each constraint size, and the number of waypoints
221 2 for (typename problem_definition_t::CIT_vector_x_t cit =
222 2 pDef.inequalityVectors_.begin();
223
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2 times.
3 cit != pDef.inequalityVectors_.end(); ++cit)
224 1 rows += cit->rows() * pData.numControlPoints;
225 2 return rows;
226 }
227
228 template <typename Point, typename Numeric>
229 std::vector<bezier_curve<Numeric, Numeric, true, linear_variable<Numeric> > >
230 1 split(const problem_definition<Point, Numeric>& pDef,
231 problem_data<Point, Numeric>& pData) {
232 typedef linear_variable<Numeric> linear_variable_t;
233 typedef bezier_curve<Numeric, Numeric, true, linear_variable_t> bezier_t;
234 typedef std::vector<bezier_t> T_bezier_t;
235
236 1 const Eigen::VectorXd& times = pDef.splitTimes_;
237 1 T_bezier_t res;
238 1 bezier_t* current = pData.bezier;
239 1 Numeric current_time = 0.;
240 Numeric tmp;
241
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 for (int i = 0; i < times.rows(); ++i) {
242 tmp = times[i];
243 std::pair<bezier_t, bezier_t> pairsplit =
244 current->split(tmp - current_time);
245 res.push_back(pairsplit.first);
246 current = &(pairsplit.second);
247 current_time += tmp - current_time;
248 }
249
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 res.push_back(*current);
250 1 return res;
251 }
252
253 template <typename Point, typename Numeric>
254 2 void initInequalityMatrix(const problem_definition<Point, Numeric>& pDef,
255 problem_data<Point, Numeric>& pData,
256 quadratic_problem<Point, Numeric>& prob) {
257 2 const std::size_t& Dim = pData.dim_;
258 typedef problem_definition<Point, Numeric> problem_definition_t;
259 typedef typename problem_definition_t::matrix_x_t matrix_x_t;
260 typedef typename problem_definition_t::vector_x_t vector_x_t;
261 typedef bezier_curve<Numeric, Numeric, true, linear_variable<Numeric> >
262 bezier_t;
263 typedef std::vector<bezier_t> T_bezier_t;
264 typedef typename T_bezier_t::const_iterator CIT_bezier_t;
265 typedef typename bezier_t::t_point_t t_point;
266 typedef typename bezier_t::t_point_t::const_iterator cit_point;
267
268 2 long cols = pData.numVariables * Dim;
269 2 long rows = compute_num_ineq_control_points<Point, Numeric>(pDef, pData);
270
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 prob.ineqMatrix = matrix_x_t::Zero(rows, cols);
271
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 prob.ineqVector = vector_x_t::Zero(rows);
272
273
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if (pDef.inequalityMatrices_.size() == 0) return;
274
275 // compute sub-bezier curves
276
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 T_bezier_t beziers = split<Point, Numeric>(pDef, pData);
277
278
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (pDef.inequalityMatrices_.size() != pDef.inequalityVectors_.size()) {
279 throw std::invalid_argument(
280 "The sizes of the inequality matrices and vectors do not match.");
281 }
282
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (pDef.inequalityMatrices_.size() != beziers.size()) {
283 throw std::invalid_argument(
284 "The sizes of the inequality matrices and the bezier degree do not "
285 "match.");
286 }
287
288 1 long currentRowIdx = 0;
289 typename problem_definition_t::CIT_matrix_x_t cmit =
290 1 pDef.inequalityMatrices_.begin();
291 typename problem_definition_t::CIT_vector_x_t cvit =
292 1 pDef.inequalityVectors_.begin();
293 // for each bezier split ..
294
2/2
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
2 for (CIT_bezier_t bit = beziers.begin(); bit != beziers.end();
295 1 ++bit, ++cvit, ++cmit) {
296 // compute vector of linear expressions of each control point
297 1 const t_point& wps = bit->waypoints();
298 // each control has a linear expression depending on all variables
299
2/2
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 1 times.
6 for (cit_point cit = wps.begin(); cit != wps.end(); ++cit) {
300
2/4
✓ Branch 3 taken 5 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
5 prob.ineqMatrix.block(currentRowIdx, 0, cmit->rows(), cols) =
301
1/2
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
5 (*cmit) * (cit->B()); // constraint inequality for current bezier *
302 // expression of control point
303
3/6
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 5 times.
✗ Branch 10 not taken.
5 prob.ineqVector.segment(currentRowIdx, cmit->rows()) =
304
1/2
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
5 *cvit - (*cmit) * (cit->c());
305 5 currentRowIdx += cmit->rows();
306 }
307 }
308
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 assert(rows == currentRowIdx); // we filled all the constraints - NB: leave
309 // assert for Debug tests
310 1 }
311
312 template <typename Point, typename Numeric, typename In>
313 2 quadratic_variable<Numeric> bezier_product(In PointsBegin1, In PointsEnd1,
314 In PointsBegin2, In PointsEnd2,
315 const std::size_t /*Dim*/) {
316 typedef Eigen::Matrix<Numeric, Eigen::Dynamic, 1> vector_x_t;
317 2 unsigned int nPoints1 =
318
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 (unsigned int)(std::distance(PointsBegin1, PointsEnd1)),
319 2 nPoints2 =
320
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 (unsigned int)(std::distance(PointsBegin2, PointsEnd2));
321
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 if (nPoints1 <= 0 || nPoints2 <= 0) {
322 throw std::runtime_error(
323 "This should never happen because an unsigned int cannot go negative "
324 "without underflowing.");
325 }
326 2 unsigned int deg1 = nPoints1 - 1, deg2 = nPoints2 - 1;
327 2 unsigned int newDeg = (deg1 + deg2);
328 // the integral of the primitive will simply be the last control points of the
329 // primitive, divided by the degree of the primitive, newDeg. We will store
330 // this in matrices for bilinear terms, and a vector for the linear terms, as
331 // well as another one for the constants.
332
3/6
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
2 quadratic_variable<Numeric> res(vector_x_t::Zero(PointsBegin1->B().cols()));
333 // depending on the index, the fraction coefficient of the bernstein polynom
334 // is either the fraction given by (i+j)/ (deg1+deg2), or 1 - (i+j)/
335 // (deg1+deg2). The trick is that the condition is given by whether the
336 // current index in the combinatorial is odd or even. time parametrization is
337 // not relevant for the cost
338
339 Numeric ratio;
340
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
16 for (unsigned int i = 0; i < newDeg + 1; ++i) {
341
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 8 times.
14 unsigned int j = i > deg2 ? i - deg2 : 0;
342
2/2
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 14 times.
46 for (; j < std::min(deg1, i) + 1; ++j) {
343
2/4
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
32 ratio = (Numeric)(bin(deg1, j) * bin(deg2, i - j)) /
344
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 (Numeric)(bin(newDeg, i));
345 32 In itj = PointsBegin1 + j;
346 32 In iti = PointsBegin2 + (i - j);
347
3/6
✓ Branch 3 taken 32 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 32 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 32 times.
✗ Branch 10 not taken.
32 res += ((*itj) * (*iti)) * ratio;
348 }
349 }
350
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 return res / (newDeg + 1);
351 2 }
352
353 inline constraint_flag operator~(constraint_flag a) {
354 return static_cast<constraint_flag>(~static_cast<int>(a));
355 }
356
357 21 inline constraint_flag operator|(constraint_flag a, constraint_flag b) {
358 21 return static_cast<constraint_flag>(static_cast<int>(a) |
359 21 static_cast<int>(b));
360 }
361
362 111 inline constraint_flag operator&(constraint_flag a, constraint_flag b) {
363 111 return static_cast<constraint_flag>(static_cast<int>(a) &
364 111 static_cast<int>(b));
365 }
366
367 inline constraint_flag operator^(constraint_flag a, constraint_flag b) {
368 return static_cast<constraint_flag>(static_cast<int>(a) ^
369 static_cast<int>(b));
370 }
371
372 inline constraint_flag& operator|=(constraint_flag& a, constraint_flag b) {
373 return (constraint_flag&)((int&)(a) |= static_cast<int>(b));
374 }
375
376 inline constraint_flag& operator&=(constraint_flag& a, constraint_flag b) {
377 return (constraint_flag&)((int&)(a) &= static_cast<int>(b));
378 }
379
380 inline constraint_flag& operator^=(constraint_flag& a, constraint_flag b) {
381 return (constraint_flag&)((int&)(a) ^= static_cast<int>(b));
382 }
383
384 } // namespace optimization
385 } // namespace ndcurves
386 #endif //_CLASS_LINEAR_PROBLEM_DETAILS
387