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 |