| 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 19 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 31 not taken.
✓ Branch 32 taken 1 times.
|
3 | 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 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
|
3 | 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 1 taken 1 times.
✗ Branch 2 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/32✓ 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.
✓ Branch 37 taken 1 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
|
17 | "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 |