1 #include "soplex.h" 2 #include "soplex_interface.h" 3 #include <iostream> 4 5 using namespace soplex; 6 7 /** creates new SoPlex struct **/ 8 void* SoPlex_create() 9 { 10 SoPlex* so = new SoPlex(); 11 return so; 12 } 13 14 /** frees SoPlex struct **/ 15 void SoPlex_free(void* soplex) 16 { 17 SoPlex* so = (SoPlex*)(soplex); 18 delete so; 19 } 20 21 /** clears the (floating point) LP **/ 22 void SoPlex_clearLPReal(void* soplex) 23 { 24 SoPlex* so = (SoPlex*)(soplex); 25 so->clearLPReal(); 26 } 27 28 /** returns number of rows **/ 29 int SoPlex_numRows(void* soplex) 30 { 31 SoPlex* so = (SoPlex*)(soplex); 32 return so->numRows(); 33 } 34 35 /** returns number of columns **/ 36 int SoPlex_numCols(void* soplex) 37 { 38 SoPlex* so = (SoPlex*)(soplex); 39 return so->numCols(); 40 } 41 42 /** enables rational solving mode **/ 43 void SoPlex_setRational(void* soplex) 44 { 45 #ifndef SOPLEX_WITH_BOOST 46 throw SPxException("Rational functions cannot be used when built without Boost."); 47 #endif 48 /* coverity[unreachable] */ 49 SoPlex* so = (SoPlex*)(soplex); 50 so->setIntParam(SoPlex::READMODE, SoPlex::READMODE_RATIONAL); 51 so->setIntParam(SoPlex::SOLVEMODE, SoPlex::SOLVEMODE_RATIONAL); 52 so->setIntParam(SoPlex::CHECKMODE, SoPlex::CHECKMODE_RATIONAL); 53 so->setIntParam(SoPlex::SYNCMODE, SoPlex::SYNCMODE_AUTO); 54 so->setRealParam(SoPlex::FEASTOL, 0.0); 55 so->setRealParam(SoPlex::OPTTOL, 0.0); 56 } 57 58 /** sets integer parameter value **/ 59 void SoPlex_setIntParam(void* soplex, int paramcode, int paramvalue) 60 { 61 SoPlex* so = (SoPlex*)(soplex); 62 so->setIntParam((SoPlex::IntParam)paramcode, paramvalue); 63 } 64 65 /** returns value of integer parameter **/ 66 int SoPlex_getIntParam(void* soplex, int paramcode) 67 { 68 SoPlex* so = (SoPlex*)(soplex); 69 return so->intParam((SoPlex::IntParam)paramcode); 70 } 71 72 /** adds a single (floating point) column **/ 73 void SoPlex_addColReal( 74 void* soplex, 75 double* colentries, 76 int colsize, 77 int nnonzeros, 78 double objval, 79 double lb, 80 double ub 81 ) 82 { 83 SoPlex* so = (SoPlex*)(soplex); 84 DSVector col(nnonzeros); 85 86 /* add nonzero entries to column vector */ 87 for(int i = 0; i < colsize; ++i) 88 { 89 if(colentries[i] != 0.0) 90 col.add(i, colentries[i]); 91 } 92 93 so->addColReal(LPCol(objval, col, ub, lb)); 94 } 95 96 /** adds a single rational column **/ 97 void SoPlex_addColRational( 98 void* soplex, 99 long* colnums, 100 long* coldenoms, 101 int colsize, 102 int nnonzeros, 103 long objvalnum, 104 long objvaldenom, 105 long lbnum, 106 long lbdenom, 107 long ubnum, 108 long ubdenom 109 ) 110 { 111 #ifndef SOPLEX_WITH_BOOST 112 throw SPxException("Rational functions cannot be used when built without Boost."); 113 #endif 114 /* coverity[unreachable] */ 115 SoPlex* so = (SoPlex*)(soplex); 116 DSVectorRational col(nnonzeros); 117 118 /* get rational lower bound */ 119 Rational lower(lbnum, lbdenom); 120 121 /* get rational upper bound */ 122 Rational upper(ubnum, ubdenom); 123 124 /* get rational objective value */ 125 Rational objval(objvalnum, objvaldenom); 126 127 /* add nonzero entries to column vector */ 128 for(int i = 0; i < colsize; ++i) 129 { 130 if(colnums[i] != 0) 131 { 132 /* get rational nonzero entry */ 133 Rational colentry(colnums[i], coldenoms[i]); 134 col.add(i, colentry); 135 } 136 } 137 138 so->addColRational(LPColRational(objval, col, upper, lower)); 139 } 140 141 /** adds a single (floating point) row **/ 142 void SoPlex_addRowReal( 143 void* soplex, 144 double* rowentries, 145 int rowsize, 146 int nnonzeros, 147 double lb, 148 double ub 149 ) 150 { 151 SoPlex* so = (SoPlex*)(soplex); 152 DSVector row(nnonzeros); 153 154 /* add nonzero entries to row vector */ 155 for(int i = 0; i < rowsize; ++i) 156 { 157 if(rowentries[i] != 0.0) 158 row.add(i, rowentries[i]); 159 } 160 161 so->addRowReal(LPRow(lb, row, ub)); 162 } 163 164 /** adds a single rational row **/ 165 void SoPlex_addRowRational( 166 void* soplex, 167 long* rownums, 168 long* rowdenoms, 169 int rowsize, 170 int nnonzeros, 171 long lbnum, 172 long lbdenom, 173 long ubnum, 174 long ubdenom 175 ) 176 { 177 #ifndef SOPLEX_WITH_BOOST 178 throw SPxException("Rational functions cannot be used when built without Boost."); 179 #endif 180 /* coverity[unreachable] */ 181 SoPlex* so = (SoPlex*)(soplex); 182 DSVectorRational row(nnonzeros); 183 184 /* get rational lower bound */ 185 Rational lower(lbnum, lbdenom); 186 187 /* get rational upper bound */ 188 Rational upper(ubnum, ubdenom); 189 190 /* add nonzero entries to row vector */ 191 for(int i = 0; i < rowsize; ++i) 192 { 193 if(rownums[i] != 0) 194 { 195 /* get rational nonzero entry */ 196 Rational rowentry(rownums[i], rowdenoms[i]); 197 row.add(i, rowentry); 198 } 199 } 200 201 so->addRowRational(LPRowRational(lower, row, upper)); 202 } 203 204 /** gets primal solution **/ 205 void SoPlex_getPrimalReal(void* soplex, double* primal, int dim) 206 { 207 SoPlex* so = (SoPlex*)(soplex); 208 so->getPrimalReal(primal, dim); 209 } 210 211 /** Returns rational primal solution in a char pointer. 212 * The caller needs to ensure the char array is freed. 213 **/ 214 char* SoPlex_getPrimalRationalString(void* soplex, int dim) 215 { 216 #ifndef SOPLEX_WITH_BOOST 217 throw SPxException("Rational functions cannot be used when built without Boost."); 218 #endif 219 /* coverity[unreachable] */ 220 SoPlex* so = (SoPlex*)(soplex); 221 VectorRational primal(dim); 222 std::string primalstring; 223 char* rawstring; 224 long unsigned int stringlength; 225 226 so->getPrimalRational(primal); 227 228 for(int i = 0; i < dim; ++i) 229 { 230 primalstring.append(primal[i].str()); 231 primalstring.append(" "); 232 } 233 234 stringlength = strlen(primalstring.c_str()) + 1; 235 rawstring = new char[stringlength]; 236 strncpy(rawstring, primalstring.c_str(), stringlength); 237 return rawstring; 238 } 239 240 /** gets dual solution **/ 241 void SoPlex_getDualReal(void* soplex, double* dual, int dim) 242 { 243 SoPlex* so = (SoPlex*)(soplex); 244 so->getDualReal(dual, dim); 245 } 246 247 /** optimizes the given LP **/ 248 int SoPlex_optimize(void* soplex) 249 { 250 SoPlex* so = (SoPlex*)(soplex); 251 return so->optimize(); 252 } 253 254 /** changes objective function vector to obj **/ 255 void SoPlex_changeObjReal(void* soplex, double* obj, int dim) 256 { 257 SoPlex* so = (SoPlex*)(soplex); 258 Vector objective(dim, obj); 259 return so->changeObjReal(objective); 260 } 261 262 /** changes rational objective function vector to obj **/ 263 void SoPlex_changeObjRational(void* soplex, long* objnums, long* objdenoms, int dim) 264 { 265 #ifndef SOPLEX_WITH_BOOST 266 throw SPxException("Rational functions cannot be used when built without Boost."); 267 #endif 268 /* coverity[unreachable] */ 269 SoPlex* so = (SoPlex*)(soplex); 270 Rational* objrational = new Rational [dim]; 271 272 /* create rational objective vector */ 273 for(int i = 0; i < dim; ++i) 274 { 275 Rational objentry(objnums[i], objdenoms[i]); 276 objrational[i] = objentry; 277 } 278 279 VectorRational objective(dim, objrational); 280 return so->changeObjRational(objective); 281 } 282 283 /** changes left-hand side vector for constraints to lhs **/ 284 void SoPlex_changeLhsReal(void* soplex, double* lhs, int dim) 285 { 286 SoPlex* so = (SoPlex*)(soplex); 287 Vector lhsvec(dim, lhs); 288 return so->changeLhsReal(lhsvec); 289 } 290 291 /** changes rational left-hand side vector for constraints to lhs **/ 292 void SoPlex_changeLhsRational(void* soplex, long* lhsnums, long* lhsdenoms, int dim) 293 { 294 #ifndef SOPLEX_WITH_BOOST 295 throw SPxException("Rational functions cannot be used when built without Boost."); 296 #endif 297 /* coverity[unreachable] */ 298 SoPlex* so = (SoPlex*)(soplex); 299 Rational* lhsrational = new Rational [dim]; 300 301 /* create rational lhs vector */ 302 for(int i = 0; i < dim; ++i) 303 { 304 Rational lhsentry(lhsnums[i], lhsdenoms[i]); 305 lhsrational[i] = lhsentry; 306 } 307 308 VectorRational lhs(dim, lhsrational); 309 return so->changeLhsRational(lhs); 310 } 311 312 /** changes right-hand side vector for constraints to rhs **/ 313 void SoPlex_changeRhsReal(void* soplex, double* rhs, int dim) 314 { 315 SoPlex* so = (SoPlex*)(soplex); 316 Vector rhsvec(dim, rhs); 317 return so->changeRhsReal(rhsvec); 318 } 319 320 /** changes rational right-hand side vector for constraints to rhs **/ 321 void SoPlex_changeRhsRational(void* soplex, long* rhsnums, long* rhsdenoms, int dim) 322 { 323 #ifndef SOPLEX_WITH_BOOST 324 throw SPxException("Rational functions cannot be used when built without Boost."); 325 #endif 326 /* coverity[unreachable] */ 327 SoPlex* so = (SoPlex*)(soplex); 328 Rational* rhsrational = new Rational [dim]; 329 330 /* create rational rhs vector */ 331 for(int i = 0; i < dim; ++i) 332 { 333 Rational rhsentry(rhsnums[i], rhsdenoms[i]); 334 rhsrational[i] = rhsentry; 335 } 336 337 VectorRational rhs(dim, rhsrational); 338 return so->changeRhsRational(rhs); 339 } 340 341 /** write LP to file **/ 342 void SoPlex_writeFileReal(void* soplex, char* filename) 343 { 344 SoPlex* so = (SoPlex*)(soplex); 345 so->writeFile(filename); 346 } 347 348 /** returns the objective value if a primal solution is available **/ 349 double SoPlex_objValueReal(void* soplex) 350 { 351 SoPlex* so = (SoPlex*)(soplex); 352 return so->objValueReal(); 353 } 354 355 /** Returns the rational objective value (as a string) if a primal solution is available. 356 * The caller needs to ensure the char array is freed. 357 **/ 358 char* SoPlex_objValueRationalString(void* soplex) 359 { 360 #ifndef SOPLEX_WITH_BOOST 361 throw SPxException("Rational functions cannot be used when built without Boost."); 362 #endif 363 /* coverity[unreachable] */ 364 long unsigned int stringlength; 365 char* value; 366 std::string objstring; 367 SoPlex* so = (SoPlex*)(soplex); 368 369 stringlength = strlen(objstring.c_str()) + 1; 370 objstring = so->objValueRational().str(); 371 value = new char[stringlength]; 372 strncpy(value, objstring.c_str(), stringlength); 373 return value; 374 } 375 376 /** changes vectors of column bounds to lb and ub **/ 377 void SoPlex_changeBoundsReal(void* soplex, double* lb, double* ub, int dim) 378 { 379 SoPlex* so = (SoPlex*)(soplex); 380 Vector lbvec(dim, lb); 381 Vector ubvec(dim, ub); 382 return so->changeBoundsReal(lbvec, ubvec); 383 } 384 385 /** changes bounds of a column to lb and ub **/ 386 void SoPlex_changeVarBoundsReal(void* soplex, int colidx, double lb, double ub) 387 { 388 SoPlex* so = (SoPlex*)(soplex); 389 return so->changeBoundsReal(colidx, lb, ub); 390 } 391 392 /** changes rational bounds of a column to lbnum/lbdenom and ubnum/ubdenom **/ 393 void SoPlex_changeVarBoundsRational( 394 void* soplex, 395 int colidx, 396 long lbnum, 397 long lbdenom, 398 long ubnum, 399 long ubdenom 400 ) 401 { 402 #ifndef SOPLEX_WITH_BOOST 403 throw SPxException("Rational functions cannot be used when built without Boost."); 404 #endif 405 /* coverity[unreachable] */ 406 SoPlex* so = (SoPlex*)(soplex); 407 408 /* get rational lower bound */ 409 Rational lower(lbnum, lbdenom); 410 411 /* get rational upper bound */ 412 Rational upper(ubnum, ubdenom); 413 414 return so->changeBoundsRational(colidx, lower, upper); 415 } 416 417 /** changes upper bound of column to ub **/ 418 void SoPlex_changeVarUpperReal(void* soplex, int colidx, double ub) 419 { 420 SoPlex* so = (SoPlex*)(soplex); 421 return so->changeLowerReal(colidx, ub); 422 } 423 424 /** changes upper bound vector of columns to ub **/ 425 void SoPlex_getUpperReal(void* soplex, double* ub, int dim) 426 { 427 SoPlex* so = (SoPlex*)(soplex); 428 Vector ubvec(dim, ub); 429 430 so->getLowerReal(ubvec); 431 432 for(int i = 0; i < dim; ++i) 433 ub[i] = ubvec[i]; 434 } 435 436 /** returns status of row 437 * 0 -> row is set to its upper bound 438 * 1 -> row is set to its lower bound 439 * 2 -> row is fixed to its identical bounds 440 * 4 -> row is basic 441 * 5 -> nothing known about basis status 442 **/ 443 int SoPlex_basisRowStatus(void* soplex, int rowidx) 444 { 445 SoPlex* so = (SoPlex*)(soplex); 446 447 return so->basisRowStatus(rowidx); 448 } 449 450 /** returns status of column 451 * 0 -> column is set to its upper bound 452 * 1 -> column is set to its lower bound 453 * 2 -> column is fixed to its identical bounds 454 * 3 -> column is free and fixed to zero 455 * 4 -> column is basic 456 * 5 -> nothing known about basis status 457 **/ 458 int SoPlex_basisColStatus(void* soplex, int colidx) 459 { 460 SoPlex* so = (SoPlex*)(soplex); 461 462 return so->basisColStatus(colidx); 463 } 464 465 /** get non-zero entries and indices of row i **/ 466 void SoPlex_getRowVectorReal( 467 void* soplex, 468 int i, 469 int* nnonzeros, 470 long* indices, 471 double* coefs 472 ) 473 { 474 SoPlex* so = (SoPlex*)(soplex); 475 DSVector row; 476 477 so->getRowVectorReal(i, row); 478 479 *nnonzeros = row.size(); 480 481 for(int j = 0; j < *nnonzeros; ++j) 482 { 483 coefs[j] = row.value(j); 484 indices[j] = row.index(j); 485 } 486 } 487 488 /** get non-zero entries and indices of rational row i **/ 489 void SoPlex_getRowVectorRational( 490 void* soplex, 491 int i, 492 int* nnonzeros, 493 long* indices, 494 long* coefsnum, 495 long* coefsdenom 496 ) 497 { 498 #ifndef SOPLEX_WITH_BOOST 499 throw SPxException("Rational functions cannot be used when built without Boost."); 500 #endif 501 SoPlex* so = (SoPlex*)(soplex); 502 LPRowRational lprow; 503 SVectorRational row; 504 505 so->getRowRational(i, lprow); 506 row = lprow.rowVector(); 507 508 *nnonzeros = row.size(); 509 510 for(int j = 0; j < *nnonzeros; ++j) 511 { 512 coefsnum[j] = (long int) numerator(row.value(j)); 513 coefsdenom[j] = (long int) denominator(row.value(j)); 514 indices[j] = row.index(j); 515 } 516 } 517 518 /** get lower and upper bounds of row i **/ 519 void SoPlex_getRowBoundsReal( 520 void* soplex, 521 int i, 522 double* lb, 523 double* ub 524 ) 525 { 526 SoPlex* so = (SoPlex*)(soplex); 527 528 *lb = so->lhsReal(i); 529 *ub = so->rhsReal(i); 530 } 531 532 /** get rational lower and upper bounds of row i **/ 533 void SoPlex_getRowBoundsRational( 534 void* soplex, 535 int i, 536 long* lbnum, 537 long* lbdenom, 538 long* ubnum, 539 long* ubdenom 540 ) 541 { 542 #ifndef SOPLEX_WITH_BOOST 543 throw SPxException("Rational functions cannot be used when built without Boost."); 544 #endif 545 SoPlex* so = (SoPlex*)(soplex); 546 547 *lbnum = (long int) numerator(so->lhsRational(i)); 548 *lbdenom = (long int) denominator(so->lhsRational(i)); 549 *ubnum = (long int) numerator(so->rhsRational(i)); 550 *ubdenom = (long int) denominator(so->rhsRational(i)); 551 } 552