GCC Code Coverage Report


Directory: ./
File: test/test_LP_solvers.cpp
Date: 2025-03-17 04:04:52
Exec Total Coverage
Lines: 68 84 81.0%
Branches: 152 376 40.4%

Line Branch Exec Source
1 /*
2 * Copyright 2015, LAAS-CNRS
3 * Author: Andrea Del Prete
4 */
5
6 #ifdef CLP_FOUND
7 #include <hpp/centroidal-dynamics/solver_LP_clp.hh>
8
9 #include "coin/ClpSimplex.hpp"
10 #include "coin/CoinBuild.hpp"
11 #include "coin/CoinModel.hpp"
12 #include "coin/CoinTime.hpp"
13 #endif
14
15 #include <hpp/centroidal-dynamics/logger.hh>
16 #include <hpp/centroidal-dynamics/solver_LP_qpoases.hh>
17 #include <iomanip>
18 #include <iostream>
19 #include <qpOASES.hpp>
20
21 using namespace std;
22 using namespace centroidal_dynamics;
23 USING_NAMESPACE_QPOASES
24
25 #define EPS 1e-6
26
27 #ifdef CLP_FOUND
28 /** Example addRows.cpp */
29 void test_addRows() {
30 const int N_ROWS_TO_ADD = 30000;
31 try {
32 // Empty model
33 ClpSimplex model;
34
35 // Objective - just nonzeros
36 int objIndex[] = {0, 2};
37 double objValue[] = {1.0, 4.0};
38 // Upper bounds - as dense vector
39 double upper[] = {2.0, COIN_DBL_MAX, 4.0};
40
41 // Create space for 3 columns
42 model.resize(0, 3);
43 // Fill in
44 int i;
45 // Virtuous way
46 // First objective
47 for (i = 0; i < 2; i++)
48 model.setObjectiveCoefficient(objIndex[i], objValue[i]);
49 // Now bounds (lower will be zero by default but do again)
50 for (i = 0; i < 3; i++) {
51 model.setColumnLower(i, 0.0);
52 model.setColumnUpper(i, upper[i]);
53 }
54 /*
55 We could also have done in non-virtuous way e.g.
56 double * objective = model.objective();
57 and then set directly
58 */
59 // Faster to add rows all at once - but this is easier to show
60 // Now add row 1 as >= 2.0
61 int row1Index[] = {0, 2};
62 double row1Value[] = {1.0, 1.0};
63 model.addRow(2, row1Index, row1Value, 2.0, COIN_DBL_MAX);
64 // Now add row 2 as == 1.0
65 int row2Index[] = {0, 1, 2};
66 double row2Value[] = {1.0, -5.0, 1.0};
67 model.addRow(3, row2Index, row2Value, 1.0, 1.0);
68 // solve
69 model.dual();
70
71 /*
72 Adding one row at a time has a significant overhead so let's
73 try a more complicated but faster way
74
75 First time adding in 10000 rows one by one
76 */
77 model.allSlackBasis();
78 ClpSimplex modelSave = model;
79 double time1 = CoinCpuTime();
80 int k;
81 for (k = 0; k < N_ROWS_TO_ADD; k++) {
82 int row2Index[] = {0, 1, 2};
83 double row2Value[] = {1.0, -5.0, 1.0};
84 model.addRow(3, row2Index, row2Value, 1.0, 1.0);
85 }
86 printf("Time for 10000 addRow is %g\n", CoinCpuTime() - time1);
87 model.dual();
88 model = modelSave;
89 // Now use build
90 CoinBuild buildObject;
91 time1 = CoinCpuTime();
92 for (k = 0; k < N_ROWS_TO_ADD; k++) {
93 int row2Index[] = {0, 1, 2};
94 double row2Value[] = {1.0, -5.0, 1.0};
95 buildObject.addRow(3, row2Index, row2Value, 1.0, 1.0);
96 }
97 model.addRows(buildObject);
98 printf("Time for 10000 addRow using CoinBuild is %g\n",
99 CoinCpuTime() - time1);
100 model.dual();
101 model = modelSave;
102 int del[] = {0, 1, 2};
103 model.deleteRows(2, del);
104 // Now use build +-1
105 CoinBuild buildObject2;
106 time1 = CoinCpuTime();
107 for (k = 0; k < N_ROWS_TO_ADD; k++) {
108 int row2Index[] = {0, 1, 2};
109 double row2Value[] = {1.0, -1.0, 1.0};
110 buildObject2.addRow(3, row2Index, row2Value, 1.0, 1.0);
111 }
112 model.addRows(buildObject2, true);
113 printf("Time for 10000 addRow using CoinBuild+-1 is %g\n",
114 CoinCpuTime() - time1);
115 model.dual();
116 model = modelSave;
117 model.deleteRows(2, del);
118 // Now use build +-1
119 CoinModel modelObject2;
120 time1 = CoinCpuTime();
121 for (k = 0; k < N_ROWS_TO_ADD; k++) {
122 int row2Index[] = {0, 1, 2};
123 double row2Value[] = {1.0, -1.0, 1.0};
124 modelObject2.addRow(3, row2Index, row2Value, 1.0, 1.0);
125 }
126 model.addRows(modelObject2, true);
127 printf("Time for 10000 addRow using CoinModel+-1 is %g\n",
128 CoinCpuTime() - time1);
129 model.dual();
130 model = ClpSimplex();
131 // Now use build +-1
132 CoinModel modelObject3;
133 time1 = CoinCpuTime();
134 for (k = 0; k < N_ROWS_TO_ADD; k++) {
135 int row2Index[] = {0, 1, 2};
136 double row2Value[] = {1.0, -1.0, 1.0};
137 modelObject3.addRow(3, row2Index, row2Value, 1.0, 1.0);
138 }
139 model.loadProblem(modelObject3, true);
140 printf("Time for 10000 addRow using CoinModel load +-1 is %g\n",
141 CoinCpuTime() - time1);
142 model.writeMps("xx.mps");
143 model.dual();
144 model = modelSave;
145 // Now use model
146 CoinModel modelObject;
147 time1 = CoinCpuTime();
148 for (k = 0; k < N_ROWS_TO_ADD; k++) {
149 int row2Index[] = {0, 1, 2};
150 double row2Value[] = {1.0, -5.0, 1.0};
151 modelObject.addRow(3, row2Index, row2Value, 1.0, 1.0);
152 }
153 model.addRows(modelObject);
154 printf("Time for 10000 addRow using CoinModel is %g\n",
155 CoinCpuTime() - time1);
156 model.dual();
157 model.writeMps("b.mps");
158 // Method using least memory - but most complicated
159 time1 = CoinCpuTime();
160 // Assumes we know exact size of model and matrix
161 // Empty model
162 ClpSimplex model2;
163 {
164 // Create space for 3 columns and 10000 rows
165 int numberRows = N_ROWS_TO_ADD;
166 int numberColumns = 3;
167 // This is fully dense - but would not normally be so
168 int numberElements = numberRows * numberColumns;
169 // Arrays will be set to default values
170 model2.resize(numberRows, numberColumns);
171 double *elements = new double[numberElements];
172 CoinBigIndex *starts = new CoinBigIndex[numberColumns + 1];
173 int *rows = new int[numberElements];
174 ;
175 int *lengths = new int[numberColumns];
176 // Now fill in - totally unsafe but ....
177 // no need as defaults to 0.0 double * columnLower = model2.columnLower();
178 double *columnUpper = model2.columnUpper();
179 double *objective = model2.objective();
180 double *rowLower = model2.rowLower();
181 double *rowUpper = model2.rowUpper();
182 // Columns - objective was packed
183 for (k = 0; k < 2; k++) {
184 int iColumn = objIndex[k];
185 objective[iColumn] = objValue[k];
186 }
187 for (k = 0; k < numberColumns; k++) columnUpper[k] = upper[k];
188 // Rows
189 for (k = 0; k < numberRows; k++) {
190 rowLower[k] = 1.0;
191 rowUpper[k] = 1.0;
192 }
193 // Now elements
194 double row2Value[] = {1.0, -5.0, 1.0};
195 CoinBigIndex put = 0;
196 for (k = 0; k < numberColumns; k++) {
197 starts[k] = put;
198 lengths[k] = numberRows;
199 double value = row2Value[k];
200 for (int i = 0; i < numberRows; i++) {
201 rows[put] = i;
202 elements[put] = value;
203 put++;
204 }
205 }
206 starts[numberColumns] = put;
207 // assign to matrix
208 CoinPackedMatrix *matrix = new CoinPackedMatrix(true, 0.0, 0.0);
209 matrix->assignMatrix(true, numberRows, numberColumns, numberElements,
210 elements, rows, starts, lengths);
211 ClpPackedMatrix *clpMatrix = new ClpPackedMatrix(matrix);
212 model2.replaceMatrix(clpMatrix, true);
213 printf("Time for 10000 addRow using hand written code is %g\n",
214 CoinCpuTime() - time1);
215 // If matrix is really big could switch off creation of row copy
216 // model2.setSpecialOptions(256);
217 }
218 model2.dual();
219 model2.writeMps("a.mps");
220 // Print column solution
221 int numberColumns = model.numberColumns();
222
223 // Alternatively getColSolution()
224 double *columnPrimal = model.primalColumnSolution();
225 // Alternatively getReducedCost()
226 double *columnDual = model.dualColumnSolution();
227 // Alternatively getColLower()
228 double *columnLower = model.columnLower();
229 // Alternatively getColUpper()
230 double *columnUpper = model.columnUpper();
231 // Alternatively getObjCoefficients()
232 double *columnObjective = model.objective();
233
234 int iColumn;
235
236 std::cout << " Primal Dual Lower "
237 "Upper Cost"
238 << std::endl;
239
240 for (iColumn = 0; iColumn < numberColumns; iColumn++) {
241 double value;
242 std::cout << std::setw(6) << iColumn << " ";
243 value = columnPrimal[iColumn];
244 if (fabs(value) < 1.0e5)
245 std::cout << setiosflags(std::ios::fixed | std::ios::showpoint)
246 << std::setw(14) << value;
247 else
248 std::cout << setiosflags(std::ios::scientific) << std::setw(14)
249 << value;
250 value = columnDual[iColumn];
251 if (fabs(value) < 1.0e5)
252 std::cout << setiosflags(std::ios::fixed | std::ios::showpoint)
253 << std::setw(14) << value;
254 else
255 std::cout << setiosflags(std::ios::scientific) << std::setw(14)
256 << value;
257 value = columnLower[iColumn];
258 if (fabs(value) < 1.0e5)
259 std::cout << setiosflags(std::ios::fixed | std::ios::showpoint)
260 << std::setw(14) << value;
261 else
262 std::cout << setiosflags(std::ios::scientific) << std::setw(14)
263 << value;
264 value = columnUpper[iColumn];
265 if (fabs(value) < 1.0e5)
266 std::cout << setiosflags(std::ios::fixed | std::ios::showpoint)
267 << std::setw(14) << value;
268 else
269 std::cout << setiosflags(std::ios::scientific) << std::setw(14)
270 << value;
271 value = columnObjective[iColumn];
272 if (fabs(value) < 1.0e5)
273 std::cout << setiosflags(std::ios::fixed | std::ios::showpoint)
274 << std::setw(14) << value;
275 else
276 std::cout << setiosflags(std::ios::scientific) << std::setw(14)
277 << value;
278
279 std::cout << std::endl;
280 }
281 std::cout << "--------------------------------------" << std::endl;
282 // Test CoinAssert
283 std::cout << "If Clp compiled without NDEBUG below should give assert, if "
284 "with NDEBUG or COIN_ASSERT CoinError"
285 << std::endl;
286 model = modelSave;
287 model.deleteRows(2, del);
288 // Deliberate error
289 model.deleteColumns(1, del + 2);
290 // Now use build +-1
291 CoinBuild buildObject3;
292 time1 = CoinCpuTime();
293 for (k = 0; k < N_ROWS_TO_ADD; k++) {
294 int row2Index[] = {0, 1, 2};
295 double row2Value[] = {1.0, -1.0, 1.0};
296 buildObject3.addRow(3, row2Index, row2Value, 1.0, 1.0);
297 }
298 model.addRows(buildObject3, true);
299 } catch (CoinError e) {
300 e.print();
301 if (e.lineNumber() >= 0)
302 std::cout << "This was from a CoinAssert" << std::endl;
303 }
304 }
305
306 void test_small_LP() {
307 ClpSimplex model;
308 // model.setLogLevel(1);
309
310 // Objective - just nonzeros
311 int objIndex[] = {0, 2};
312 double objValue[] = {1.0, 4.0};
313 // Upper bounds - as dense vector
314 double upper[] = {2.0, COIN_DBL_MAX, 4.0};
315
316 // Create space for 3 columns
317 model.resize(0, 3);
318
319 // Can also use maximumIterations
320 int integerValue;
321 model.getIntParam(ClpMaxNumIteration, integerValue);
322 cout << "Value of ClpMaxNumIteration is " << integerValue << endl;
323 model.setMaximumIterations(integerValue);
324
325 // Fill in
326 int i;
327 // Virtuous way
328 // First objective
329 for (i = 0; i < 2; i++)
330 model.setObjectiveCoefficient(objIndex[i], objValue[i]);
331 // Now bounds (lower will be zero by default but do again)
332 for (i = 0; i < 3; i++) {
333 model.setColumnLower(i, 0.0);
334 model.setColumnUpper(i, upper[i]);
335 }
336 /*
337 We could also have done in non-virtuous way e.g.
338 double * objective = model.objective();
339 and then set directly
340 */
341 // Faster to add rows all at once - but this is easier to show
342 // Now add row 1 as >= 2.0
343 int row1Index[] = {0, 2};
344 double row1Value[] = {1.0, 1.0};
345 model.addRow(2, row1Index, row1Value, 2.0, COIN_DBL_MAX);
346 // Now add row 2 as == 1.0
347 int row2Index[] = {0, 1, 2};
348 double row2Value[] = {1.0, -5.0, 1.0};
349 model.addRow(3, row2Index, row2Value, 1.0, 1.0);
350
351 int n = model.getNumCols();
352 int m = model.getNumRows();
353 cout << "Problem has " << n << " variables and " << m << " constraints.\n";
354
355 // solve
356 model.dual();
357
358 // Check the solution
359 if (model.isProvenOptimal()) {
360 cout << "Found optimal solution!" << endl;
361 cout << "Objective value is " << model.getObjValue() << endl;
362 cout << "Model status is " << model.status() << " after "
363 << model.numberIterations() << " iterations - objective is "
364 << model.objectiveValue() << endl;
365 const double *solution;
366 solution = model.getColSolution();
367 // We could then print the solution or examine it.
368 cout << "Solution is: ";
369 for (int i = 0; i < n; i++) cout << solution[i] << ", ";
370 cout << endl;
371 } else
372 cout << "Didn’t find optimal solution." << endl;
373 }
374 #endif
375
376 1 int main() {
377 1 cout << "Test LP Solvers (1 means ok, 0 means error)\n\n";
378
379 {
380
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 cout << "TEST QP OASES ON A SMALL 2-VARIABLE LP";
381 /* Setup data of first LP. */
382 1 real_t A[1 * 2] = {1.0, 1.0};
383 1 real_t g[2] = {1.5, 1.0};
384 1 real_t lb[2] = {0.5, -2.0};
385 1 real_t ub[2] = {5.0, 2.0};
386 1 real_t lbA[1] = {-1.0};
387 1 real_t ubA[1] = {2.0};
388
389 /* Setting up QProblem object with zero Hessian matrix. */
390
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 QProblem example(2, 1, HST_ZERO);
391
392
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Options options;
393 // options.setToMPC();
394
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 example.setOptions(options);
395
396 /* Solve first LP. */
397 1 int nWSR = 10;
398
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 int res = example.init(0, g, A, lb, ub, lbA, ubA, nWSR, 0);
399
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (res == 0)
400
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 cout << "[INFO] LP solved correctly\n";
401 else
402 cout << "[ERROR] QpOases could not solve the LP problem, error code: "
403 << res << endl;
404 1 }
405
406 {
407
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 cout << "\nTEST READ-WRITE METHODS OF SOLVER_LP_ABSTRACT\n";
408 Solver_LP_abstract *solverOases =
409
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Solver_LP_abstract::getNewSolver(SOLVER_LP_QPOASES);
410 1 const int n = 3;
411 1 const int m = 4;
412 1 const char *filename = "small_3_x_4_LP.dat";
413
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 VectorX c = VectorX::Random(n);
414
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 VectorX lb = -100 * VectorX::Ones(n);
415
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 VectorX ub = 100 * VectorX::Ones(n);
416
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 MatrixXX A = MatrixXX::Random(m, n);
417
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 VectorX Alb = -100 * VectorX::Ones(m);
418
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 VectorX Aub = 100 * VectorX::Ones(m);
419
9/18
✓ 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 20 taken 1 times.
✗ Branch 21 not taken.
✓ Branch 23 taken 1 times.
✗ Branch 24 not taken.
✗ Branch 33 not taken.
✓ Branch 34 taken 1 times.
1 if (!solverOases->writeLpToFile(filename, c, lb, ub, A, Alb, Aub)) {
420 SEND_ERROR_MSG("Error while writing LP to file");
421 return -1;
422 }
423
5/10
✓ 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.
1 VectorX c2, lb2, ub2, Alb2, Aub2;
424
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 MatrixXX A2;
425
3/6
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
1 if (!solverOases->readLpFromFile(filename, c2, lb2, ub2, A2, Alb2, Aub2)) {
426 SEND_ERROR_MSG("Error while reading LP from file");
427 return -1;
428 }
429
430
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
1 cout << "Check number of variables: " << (c.size() == c2.size()) << endl;
431
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
1 cout << "Check number of constraints: " << (A.rows() == A2.rows()) << endl;
432
4/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
1 cout << "Check gradient vector c: " << c.isApprox(c2) << endl;
433
4/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
1 cout << "Check lower bound vector lb: " << lb.isApprox(lb2) << endl;
434
4/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
1 cout << "Check upper bound vector ub: " << ub.isApprox(ub2) << endl;
435
4/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
1 cout << "Check constraint matrix A: " << A.isApprox(A2) << endl;
436
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
1 cout << "Check constraint lower bound vector Alb: " << Alb.isApprox(Alb2)
437
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 << endl;
438
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
1 cout << "Check constraint upper bound vector Aub: " << Aub.isApprox(Aub2)
439
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 << endl;
440
12/24
✓ 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.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 35 not taken.
1 }
441
442 {
443
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 cout << "\nTEST QP OASES ON SOME LP PROBLEMS\n";
444
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 string file_path = "../test_data/";
445 Solver_LP_abstract *solverOases =
446
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Solver_LP_abstract::getNewSolver(SOLVER_LP_QPOASES);
447 1 const int PROBLEM_NUMBER = 14;
448 string problem_filenames[PROBLEM_NUMBER] = {
449 "DLP_findExtremumOverLine20151103_112611",
450 "DLP_findExtremumOverLine20151103_115627",
451 "DLP_findExtremumOverLine20151103_014022",
452 "DLP_findExtremumOverLine_32_generators",
453 "DLP_findExtremumOverLine_64_generators",
454 "DLP_findExtremumOverLine_128_generators",
455 "DLP_findExtremumOverLine_128_generators_bis",
456 "LP_findExtremumOverLine20151103_112610",
457 "LP_findExtremumOverLine20151103_112611",
458 "LP_findExtremumOverLine20151103_014022",
459 "LP_findExtremumOverLine_32_generators",
460 "LP_findExtremumOverLine_64_generators",
461 "LP_findExtremumOverLine_128_generators",
462
14/28
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 27 taken 1 times.
✗ Branch 28 not taken.
✓ Branch 32 taken 1 times.
✗ Branch 33 not taken.
✓ Branch 37 taken 1 times.
✗ Branch 38 not taken.
✓ Branch 42 taken 1 times.
✗ Branch 43 not taken.
✓ Branch 47 taken 1 times.
✗ Branch 48 not taken.
✓ Branch 52 taken 1 times.
✗ Branch 53 not taken.
✓ Branch 57 taken 1 times.
✗ Branch 58 not taken.
✓ Branch 62 taken 1 times.
✗ Branch 63 not taken.
✓ Branch 67 taken 1 times.
✗ Branch 68 not taken.
16 "LP_findExtremumOverLine_128_generators_bis"};
463
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 VectorX c, lb, ub, Alb, Aub, realSol, sol;
464
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 MatrixXX A;
465
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 1 times.
15 for (int i = 0; i < PROBLEM_NUMBER; i++) {
466 14 string &problem_filename = problem_filenames[i];
467
4/8
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 14 times.
✗ Branch 8 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 14 times.
14 if (!solverOases->readLpFromFile(file_path + problem_filename + ".dat", c,
468 lb, ub, A, Alb, Aub)) {
469 SEND_ERROR_MSG("Error while reading LP from file " + problem_filename);
470 return -1;
471 }
472
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 string solution_filename = problem_filename + "_solution";
473
4/8
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 14 times.
✗ Branch 8 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 14 times.
14 if (!readMatrixFromFile(file_path + solution_filename + ".dat",
474 realSol)) {
475 SEND_ERROR_MSG("Error while reading LP solution from file " +
476 solution_filename);
477 // return -1;
478 }
479
1/2
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
14 sol.resize(c.size());
480
8/16
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 14 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 14 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 14 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 14 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 14 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 14 times.
✗ Branch 23 not taken.
14 solverOases->solve(c, lb, ub, A, Alb, Aub, sol);
481
3/4
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 6 times.
14 if (sol.isApprox(realSol, EPS)) {
482
3/6
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
8 cout << "[INFO] Solution of problem " << problem_filename << " ("
483
3/6
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 8 times.
✗ Branch 10 not taken.
8 << c.size() << " var, " << A.rows()
484
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 << " constr) is equal to the expected value!\n";
485 } else {
486
3/6
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
6 if (fabs(c.dot(sol) - c.dot(realSol)) < EPS)
487
3/6
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
6 cout << "[WARNING] Solution of problem " << problem_filename << " ("
488
3/6
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 6 times.
✗ Branch 10 not taken.
6 << c.size() << " var, " << A.rows()
489 << " constr) is different from expected but it has the same "
490
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 "cost\n";
491 else {
492 cout << "[ERROR] Solution of problem " << problem_filename << " ("
493 << c.size() << " var, " << A.rows()
494 << " constr) is different from the expected value:\n";
495 cout << "\tSolution found " << sol.transpose() << endl;
496 cout << "\tExpected solution " << realSol.transpose() << endl;
497 cout << "\tCost found " << (c.dot(sol)) << endl;
498 cout << "\tCost expected " << (c.dot(realSol)) << endl;
499 }
500 }
501 14 }
502
503 1 return 0;
504
2/4
✓ Branch 8 taken 14 times.
✓ Branch 9 taken 1 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
17 }
505
506 #ifdef CLP_FOUND
507 test_addRows();
508 test_small_LP();
509
510 Solver_LP_abstract *solver = Solver_LP_abstract::getNewSolver(SOLVER_LP_CLP);
511 Vector3 c, lb, ub, x;
512 MatrixXX A(2, 3);
513 Vector2 Alb, Aub;
514 c << 1.0, 0.0, 4.0;
515 lb << 0.0, 0.0, 0.0;
516 ub << 2.0, COIN_DBL_MAX, 4.0;
517 A << 1.0, 0.0, 1.0, 1.0, -5.0, 1.0;
518 Alb << 2.0, 1.0;
519 Aub << COIN_DBL_MAX, 1.0;
520 if (solver->solve(c, lb, ub, A, Alb, Aub, x) == LP_STATUS_OPTIMAL) {
521 cout << "solver_LP_clp solved the problem\n";
522 cout << "The solution is " << x.transpose() << endl;
523 } else
524 cout << "solver_LP_clp failed to solve the problem\n";
525 #endif
526
527 return 1;
528 }
529