| 1 | /* $Id: ClpInterior.cpp 1665 2011-01-04 17:55:54Z lou $ */ |
| 2 | // Copyright (C) 2002, International Business Machines |
| 3 | // Corporation and others. All Rights Reserved. |
| 4 | // This code is licensed under the terms of the Eclipse Public License (EPL). |
| 5 | |
| 6 | |
| 7 | #include "CoinPragma.hpp" |
| 8 | |
| 9 | #include <math.h> |
| 10 | |
| 11 | #include "CoinHelperFunctions.hpp" |
| 12 | #include "ClpInterior.hpp" |
| 13 | #include "ClpMatrixBase.hpp" |
| 14 | #ifdef COIN_DO_PDCO |
| 15 | #include "ClpLsqr.hpp" |
| 16 | #include "ClpPdcoBase.hpp" |
| 17 | #endif |
| 18 | #include "CoinDenseVector.hpp" |
| 19 | #include "ClpMessage.hpp" |
| 20 | #include "ClpHelperFunctions.hpp" |
| 21 | #include "ClpCholeskyDense.hpp" |
| 22 | #include "ClpLinearObjective.hpp" |
| 23 | #include "ClpQuadraticObjective.hpp" |
| 24 | #include <cfloat> |
| 25 | |
| 26 | #include <string> |
| 27 | #include <stdio.h> |
| 28 | #include <iostream> |
| 29 | //############################################################################# |
| 30 | |
| 31 | ClpInterior::ClpInterior () : |
| 32 | |
| 33 | ClpModel(), |
| 34 | largestPrimalError_(0.0), |
| 35 | largestDualError_(0.0), |
| 36 | sumDualInfeasibilities_(0.0), |
| 37 | sumPrimalInfeasibilities_(0.0), |
| 38 | worstComplementarity_(0.0), |
| 39 | xsize_(0.0), |
| 40 | zsize_(0.0), |
| 41 | lower_(NULL), |
| 42 | rowLowerWork_(NULL), |
| 43 | columnLowerWork_(NULL), |
| 44 | upper_(NULL), |
| 45 | rowUpperWork_(NULL), |
| 46 | columnUpperWork_(NULL), |
| 47 | cost_(NULL), |
| 48 | rhs_(NULL), |
| 49 | x_(NULL), |
| 50 | y_(NULL), |
| 51 | dj_(NULL), |
| 52 | lsqrObject_(NULL), |
| 53 | pdcoStuff_(NULL), |
| 54 | mu_(0.0), |
| 55 | objectiveNorm_(1.0e-12), |
| 56 | rhsNorm_(1.0e-12), |
| 57 | solutionNorm_(1.0e-12), |
| 58 | dualObjective_(0.0), |
| 59 | primalObjective_(0.0), |
| 60 | diagonalNorm_(1.0e-12), |
| 61 | stepLength_(0.995), |
| 62 | linearPerturbation_(1.0e-12), |
| 63 | diagonalPerturbation_(1.0e-15), |
| 64 | gamma_(0.0), |
| 65 | delta_(0), |
| 66 | targetGap_(1.0e-12), |
| 67 | projectionTolerance_(1.0e-7), |
| 68 | maximumRHSError_(0.0), |
| 69 | maximumBoundInfeasibility_(0.0), |
| 70 | maximumDualError_(0.0), |
| 71 | diagonalScaleFactor_(0.0), |
| 72 | scaleFactor_(1.0), |
| 73 | actualPrimalStep_(0.0), |
| 74 | actualDualStep_(0.0), |
| 75 | smallestInfeasibility_(0.0), |
| 76 | complementarityGap_(0.0), |
| 77 | baseObjectiveNorm_(0.0), |
| 78 | worstDirectionAccuracy_(0.0), |
| 79 | maximumRHSChange_(0.0), |
| 80 | errorRegion_(NULL), |
| 81 | rhsFixRegion_(NULL), |
| 82 | upperSlack_(NULL), |
| 83 | lowerSlack_(NULL), |
| 84 | diagonal_(NULL), |
| 85 | solution_(NULL), |
| 86 | workArray_(NULL), |
| 87 | deltaX_(NULL), |
| 88 | deltaY_(NULL), |
| 89 | deltaZ_(NULL), |
| 90 | deltaW_(NULL), |
| 91 | deltaSU_(NULL), |
| 92 | deltaSL_(NULL), |
| 93 | primalR_(NULL), |
| 94 | dualR_(NULL), |
| 95 | rhsB_(NULL), |
| 96 | rhsU_(NULL), |
| 97 | rhsL_(NULL), |
| 98 | rhsZ_(NULL), |
| 99 | rhsW_(NULL), |
| 100 | rhsC_(NULL), |
| 101 | zVec_(NULL), |
| 102 | wVec_(NULL), |
| 103 | cholesky_(NULL), |
| 104 | numberComplementarityPairs_(0), |
| 105 | numberComplementarityItems_(0), |
| 106 | maximumBarrierIterations_(200), |
| 107 | gonePrimalFeasible_(false), |
| 108 | goneDualFeasible_(false), |
| 109 | algorithm_(-1) |
| 110 | { |
| 111 | memset(historyInfeasibility_, 0, LENGTH_HISTORY * sizeof(CoinWorkDouble)); |
| 112 | solveType_ = 3; // say interior based life form |
| 113 | cholesky_ = new ClpCholeskyDense(); // put in placeholder |
| 114 | } |
| 115 | |
| 116 | // Subproblem constructor |
| 117 | ClpInterior::ClpInterior ( const ClpModel * rhs, |
| 118 | int numberRows, const int * whichRow, |
| 119 | int numberColumns, const int * whichColumn, |
| 120 | bool dropNames, bool dropIntegers) |
| 121 | : ClpModel(rhs, numberRows, whichRow, |
| 122 | numberColumns, whichColumn, dropNames, dropIntegers), |
| 123 | largestPrimalError_(0.0), |
| 124 | largestDualError_(0.0), |
| 125 | sumDualInfeasibilities_(0.0), |
| 126 | sumPrimalInfeasibilities_(0.0), |
| 127 | worstComplementarity_(0.0), |
| 128 | xsize_(0.0), |
| 129 | zsize_(0.0), |
| 130 | lower_(NULL), |
| 131 | rowLowerWork_(NULL), |
| 132 | columnLowerWork_(NULL), |
| 133 | upper_(NULL), |
| 134 | rowUpperWork_(NULL), |
| 135 | columnUpperWork_(NULL), |
| 136 | cost_(NULL), |
| 137 | rhs_(NULL), |
| 138 | x_(NULL), |
| 139 | y_(NULL), |
| 140 | dj_(NULL), |
| 141 | lsqrObject_(NULL), |
| 142 | pdcoStuff_(NULL), |
| 143 | mu_(0.0), |
| 144 | objectiveNorm_(1.0e-12), |
| 145 | rhsNorm_(1.0e-12), |
| 146 | solutionNorm_(1.0e-12), |
| 147 | dualObjective_(0.0), |
| 148 | primalObjective_(0.0), |
| 149 | diagonalNorm_(1.0e-12), |
| 150 | stepLength_(0.99995), |
| 151 | linearPerturbation_(1.0e-12), |
| 152 | diagonalPerturbation_(1.0e-15), |
| 153 | gamma_(0.0), |
| 154 | delta_(0), |
| 155 | targetGap_(1.0e-12), |
| 156 | projectionTolerance_(1.0e-7), |
| 157 | maximumRHSError_(0.0), |
| 158 | maximumBoundInfeasibility_(0.0), |
| 159 | maximumDualError_(0.0), |
| 160 | diagonalScaleFactor_(0.0), |
| 161 | scaleFactor_(0.0), |
| 162 | actualPrimalStep_(0.0), |
| 163 | actualDualStep_(0.0), |
| 164 | smallestInfeasibility_(0.0), |
| 165 | complementarityGap_(0.0), |
| 166 | baseObjectiveNorm_(0.0), |
| 167 | worstDirectionAccuracy_(0.0), |
| 168 | maximumRHSChange_(0.0), |
| 169 | errorRegion_(NULL), |
| 170 | rhsFixRegion_(NULL), |
| 171 | upperSlack_(NULL), |
| 172 | lowerSlack_(NULL), |
| 173 | diagonal_(NULL), |
| 174 | solution_(NULL), |
| 175 | workArray_(NULL), |
| 176 | deltaX_(NULL), |
| 177 | deltaY_(NULL), |
| 178 | deltaZ_(NULL), |
| 179 | deltaW_(NULL), |
| 180 | deltaSU_(NULL), |
| 181 | deltaSL_(NULL), |
| 182 | primalR_(NULL), |
| 183 | dualR_(NULL), |
| 184 | rhsB_(NULL), |
| 185 | rhsU_(NULL), |
| 186 | rhsL_(NULL), |
| 187 | rhsZ_(NULL), |
| 188 | rhsW_(NULL), |
| 189 | rhsC_(NULL), |
| 190 | zVec_(NULL), |
| 191 | wVec_(NULL), |
| 192 | cholesky_(NULL), |
| 193 | numberComplementarityPairs_(0), |
| 194 | numberComplementarityItems_(0), |
| 195 | maximumBarrierIterations_(200), |
| 196 | gonePrimalFeasible_(false), |
| 197 | goneDualFeasible_(false), |
| 198 | algorithm_(-1) |
| 199 | { |
| 200 | memset(historyInfeasibility_, 0, LENGTH_HISTORY * sizeof(CoinWorkDouble)); |
| 201 | solveType_ = 3; // say interior based life form |
| 202 | cholesky_ = new ClpCholeskyDense(); |
| 203 | } |
| 204 | |
| 205 | //----------------------------------------------------------------------------- |
| 206 | |
| 207 | ClpInterior::~ClpInterior () |
| 208 | { |
| 209 | gutsOfDelete(); |
| 210 | } |
| 211 | //############################################################################# |
| 212 | /* |
| 213 | This does housekeeping |
| 214 | */ |
| 215 | int |
| 216 | ClpInterior::housekeeping() |
| 217 | { |
| 218 | numberIterations_++; |
| 219 | return 0; |
| 220 | } |
| 221 | // Copy constructor. |
| 222 | ClpInterior::ClpInterior(const ClpInterior &rhs) : |
| 223 | ClpModel(rhs), |
| 224 | largestPrimalError_(0.0), |
| 225 | largestDualError_(0.0), |
| 226 | sumDualInfeasibilities_(0.0), |
| 227 | sumPrimalInfeasibilities_(0.0), |
| 228 | worstComplementarity_(0.0), |
| 229 | xsize_(0.0), |
| 230 | zsize_(0.0), |
| 231 | lower_(NULL), |
| 232 | rowLowerWork_(NULL), |
| 233 | columnLowerWork_(NULL), |
| 234 | upper_(NULL), |
| 235 | rowUpperWork_(NULL), |
| 236 | columnUpperWork_(NULL), |
| 237 | cost_(NULL), |
| 238 | rhs_(NULL), |
| 239 | x_(NULL), |
| 240 | y_(NULL), |
| 241 | dj_(NULL), |
| 242 | lsqrObject_(NULL), |
| 243 | pdcoStuff_(NULL), |
| 244 | errorRegion_(NULL), |
| 245 | rhsFixRegion_(NULL), |
| 246 | upperSlack_(NULL), |
| 247 | lowerSlack_(NULL), |
| 248 | diagonal_(NULL), |
| 249 | solution_(NULL), |
| 250 | workArray_(NULL), |
| 251 | deltaX_(NULL), |
| 252 | deltaY_(NULL), |
| 253 | deltaZ_(NULL), |
| 254 | deltaW_(NULL), |
| 255 | deltaSU_(NULL), |
| 256 | deltaSL_(NULL), |
| 257 | primalR_(NULL), |
| 258 | dualR_(NULL), |
| 259 | rhsB_(NULL), |
| 260 | rhsU_(NULL), |
| 261 | rhsL_(NULL), |
| 262 | rhsZ_(NULL), |
| 263 | rhsW_(NULL), |
| 264 | rhsC_(NULL), |
| 265 | zVec_(NULL), |
| 266 | wVec_(NULL), |
| 267 | cholesky_(NULL) |
| 268 | { |
| 269 | gutsOfDelete(); |
| 270 | gutsOfCopy(rhs); |
| 271 | solveType_ = 3; // say interior based life form |
| 272 | } |
| 273 | // Copy constructor from model |
| 274 | ClpInterior::ClpInterior(const ClpModel &rhs) : |
| 275 | ClpModel(rhs), |
| 276 | largestPrimalError_(0.0), |
| 277 | largestDualError_(0.0), |
| 278 | sumDualInfeasibilities_(0.0), |
| 279 | sumPrimalInfeasibilities_(0.0), |
| 280 | worstComplementarity_(0.0), |
| 281 | xsize_(0.0), |
| 282 | zsize_(0.0), |
| 283 | lower_(NULL), |
| 284 | rowLowerWork_(NULL), |
| 285 | columnLowerWork_(NULL), |
| 286 | upper_(NULL), |
| 287 | rowUpperWork_(NULL), |
| 288 | columnUpperWork_(NULL), |
| 289 | cost_(NULL), |
| 290 | rhs_(NULL), |
| 291 | x_(NULL), |
| 292 | y_(NULL), |
| 293 | dj_(NULL), |
| 294 | lsqrObject_(NULL), |
| 295 | pdcoStuff_(NULL), |
| 296 | mu_(0.0), |
| 297 | objectiveNorm_(1.0e-12), |
| 298 | rhsNorm_(1.0e-12), |
| 299 | solutionNorm_(1.0e-12), |
| 300 | dualObjective_(0.0), |
| 301 | primalObjective_(0.0), |
| 302 | diagonalNorm_(1.0e-12), |
| 303 | stepLength_(0.99995), |
| 304 | linearPerturbation_(1.0e-12), |
| 305 | diagonalPerturbation_(1.0e-15), |
| 306 | gamma_(0.0), |
| 307 | delta_(0), |
| 308 | targetGap_(1.0e-12), |
| 309 | projectionTolerance_(1.0e-7), |
| 310 | maximumRHSError_(0.0), |
| 311 | maximumBoundInfeasibility_(0.0), |
| 312 | maximumDualError_(0.0), |
| 313 | diagonalScaleFactor_(0.0), |
| 314 | scaleFactor_(0.0), |
| 315 | actualPrimalStep_(0.0), |
| 316 | actualDualStep_(0.0), |
| 317 | smallestInfeasibility_(0.0), |
| 318 | complementarityGap_(0.0), |
| 319 | baseObjectiveNorm_(0.0), |
| 320 | worstDirectionAccuracy_(0.0), |
| 321 | maximumRHSChange_(0.0), |
| 322 | errorRegion_(NULL), |
| 323 | rhsFixRegion_(NULL), |
| 324 | upperSlack_(NULL), |
| 325 | lowerSlack_(NULL), |
| 326 | diagonal_(NULL), |
| 327 | solution_(NULL), |
| 328 | workArray_(NULL), |
| 329 | deltaX_(NULL), |
| 330 | deltaY_(NULL), |
| 331 | deltaZ_(NULL), |
| 332 | deltaW_(NULL), |
| 333 | deltaSU_(NULL), |
| 334 | deltaSL_(NULL), |
| 335 | primalR_(NULL), |
| 336 | dualR_(NULL), |
| 337 | rhsB_(NULL), |
| 338 | rhsU_(NULL), |
| 339 | rhsL_(NULL), |
| 340 | rhsZ_(NULL), |
| 341 | rhsW_(NULL), |
| 342 | rhsC_(NULL), |
| 343 | zVec_(NULL), |
| 344 | wVec_(NULL), |
| 345 | cholesky_(NULL), |
| 346 | numberComplementarityPairs_(0), |
| 347 | numberComplementarityItems_(0), |
| 348 | maximumBarrierIterations_(200), |
| 349 | gonePrimalFeasible_(false), |
| 350 | goneDualFeasible_(false), |
| 351 | algorithm_(-1) |
| 352 | { |
| 353 | memset(historyInfeasibility_, 0, LENGTH_HISTORY * sizeof(CoinWorkDouble)); |
| 354 | solveType_ = 3; // say interior based life form |
| 355 | cholesky_ = new ClpCholeskyDense(); |
| 356 | } |
| 357 | // Assignment operator. This copies the data |
| 358 | ClpInterior & |
| 359 | ClpInterior::operator=(const ClpInterior & rhs) |
| 360 | { |
| 361 | if (this != &rhs) { |
| 362 | gutsOfDelete(); |
| 363 | ClpModel::operator=(rhs); |
| 364 | gutsOfCopy(rhs); |
| 365 | } |
| 366 | return *this; |
| 367 | } |
| 368 | void |
| 369 | ClpInterior::gutsOfCopy(const ClpInterior & rhs) |
| 370 | { |
| 371 | lower_ = ClpCopyOfArray(rhs.lower_, numberColumns_ + numberRows_); |
| 372 | rowLowerWork_ = lower_ + numberColumns_; |
| 373 | columnLowerWork_ = lower_; |
| 374 | upper_ = ClpCopyOfArray(rhs.upper_, numberColumns_ + numberRows_); |
| 375 | rowUpperWork_ = upper_ + numberColumns_; |
| 376 | columnUpperWork_ = upper_; |
| 377 | //cost_ = ClpCopyOfArray(rhs.cost_,2*(numberColumns_+numberRows_)); |
| 378 | cost_ = ClpCopyOfArray(rhs.cost_, numberColumns_); |
| 379 | rhs_ = ClpCopyOfArray(rhs.rhs_, numberRows_); |
| 380 | x_ = ClpCopyOfArray(rhs.x_, numberColumns_); |
| 381 | y_ = ClpCopyOfArray(rhs.y_, numberRows_); |
| 382 | dj_ = ClpCopyOfArray(rhs.dj_, numberColumns_ + numberRows_); |
| 383 | #ifdef COIN_DO_PDCO |
| 384 | lsqrObject_ = new ClpLsqr(*rhs.lsqrObject_); |
| 385 | pdcoStuff_ = rhs.pdcoStuff_->clone(); |
| 386 | #endif |
| 387 | largestPrimalError_ = rhs.largestPrimalError_; |
| 388 | largestDualError_ = rhs.largestDualError_; |
| 389 | sumDualInfeasibilities_ = rhs.sumDualInfeasibilities_; |
| 390 | sumPrimalInfeasibilities_ = rhs.sumPrimalInfeasibilities_; |
| 391 | worstComplementarity_ = rhs.worstComplementarity_; |
| 392 | xsize_ = rhs.xsize_; |
| 393 | zsize_ = rhs.zsize_; |
| 394 | solveType_ = rhs.solveType_; |
| 395 | mu_ = rhs.mu_; |
| 396 | objectiveNorm_ = rhs.objectiveNorm_; |
| 397 | rhsNorm_ = rhs.rhsNorm_; |
| 398 | solutionNorm_ = rhs.solutionNorm_; |
| 399 | dualObjective_ = rhs.dualObjective_; |
| 400 | primalObjective_ = rhs.primalObjective_; |
| 401 | diagonalNorm_ = rhs.diagonalNorm_; |
| 402 | stepLength_ = rhs.stepLength_; |
| 403 | linearPerturbation_ = rhs.linearPerturbation_; |
| 404 | diagonalPerturbation_ = rhs.diagonalPerturbation_; |
| 405 | gamma_ = rhs.gamma_; |
| 406 | delta_ = rhs.delta_; |
| 407 | targetGap_ = rhs.targetGap_; |
| 408 | projectionTolerance_ = rhs.projectionTolerance_; |
| 409 | maximumRHSError_ = rhs.maximumRHSError_; |
| 410 | maximumBoundInfeasibility_ = rhs.maximumBoundInfeasibility_; |
| 411 | maximumDualError_ = rhs.maximumDualError_; |
| 412 | diagonalScaleFactor_ = rhs.diagonalScaleFactor_; |
| 413 | scaleFactor_ = rhs.scaleFactor_; |
| 414 | actualPrimalStep_ = rhs.actualPrimalStep_; |
| 415 | actualDualStep_ = rhs.actualDualStep_; |
| 416 | smallestInfeasibility_ = rhs.smallestInfeasibility_; |
| 417 | complementarityGap_ = rhs.complementarityGap_; |
| 418 | baseObjectiveNorm_ = rhs.baseObjectiveNorm_; |
| 419 | worstDirectionAccuracy_ = rhs.worstDirectionAccuracy_; |
| 420 | maximumRHSChange_ = rhs.maximumRHSChange_; |
| 421 | errorRegion_ = ClpCopyOfArray(rhs.errorRegion_, numberRows_); |
| 422 | rhsFixRegion_ = ClpCopyOfArray(rhs.rhsFixRegion_, numberRows_); |
| 423 | deltaY_ = ClpCopyOfArray(rhs.deltaY_, numberRows_); |
| 424 | upperSlack_ = ClpCopyOfArray(rhs.upperSlack_, numberRows_ + numberColumns_); |
| 425 | lowerSlack_ = ClpCopyOfArray(rhs.lowerSlack_, numberRows_ + numberColumns_); |
| 426 | diagonal_ = ClpCopyOfArray(rhs.diagonal_, numberRows_ + numberColumns_); |
| 427 | deltaX_ = ClpCopyOfArray(rhs.deltaX_, numberRows_ + numberColumns_); |
| 428 | deltaZ_ = ClpCopyOfArray(rhs.deltaZ_, numberRows_ + numberColumns_); |
| 429 | deltaW_ = ClpCopyOfArray(rhs.deltaW_, numberRows_ + numberColumns_); |
| 430 | deltaSU_ = ClpCopyOfArray(rhs.deltaSU_, numberRows_ + numberColumns_); |
| 431 | deltaSL_ = ClpCopyOfArray(rhs.deltaSL_, numberRows_ + numberColumns_); |
| 432 | primalR_ = ClpCopyOfArray(rhs.primalR_, numberRows_ + numberColumns_); |
| 433 | dualR_ = ClpCopyOfArray(rhs.dualR_, numberRows_ + numberColumns_); |
| 434 | rhsB_ = ClpCopyOfArray(rhs.rhsB_, numberRows_); |
| 435 | rhsU_ = ClpCopyOfArray(rhs.rhsU_, numberRows_ + numberColumns_); |
| 436 | rhsL_ = ClpCopyOfArray(rhs.rhsL_, numberRows_ + numberColumns_); |
| 437 | rhsZ_ = ClpCopyOfArray(rhs.rhsZ_, numberRows_ + numberColumns_); |
| 438 | rhsW_ = ClpCopyOfArray(rhs.rhsW_, numberRows_ + numberColumns_); |
| 439 | rhsC_ = ClpCopyOfArray(rhs.rhsC_, numberRows_ + numberColumns_); |
| 440 | solution_ = ClpCopyOfArray(rhs.solution_, numberRows_ + numberColumns_); |
| 441 | workArray_ = ClpCopyOfArray(rhs.workArray_, numberRows_ + numberColumns_); |
| 442 | zVec_ = ClpCopyOfArray(rhs.zVec_, numberRows_ + numberColumns_); |
| 443 | wVec_ = ClpCopyOfArray(rhs.wVec_, numberRows_ + numberColumns_); |
| 444 | cholesky_ = rhs.cholesky_->clone(); |
| 445 | numberComplementarityPairs_ = rhs.numberComplementarityPairs_; |
| 446 | numberComplementarityItems_ = rhs.numberComplementarityItems_; |
| 447 | maximumBarrierIterations_ = rhs.maximumBarrierIterations_; |
| 448 | gonePrimalFeasible_ = rhs.gonePrimalFeasible_; |
| 449 | goneDualFeasible_ = rhs.goneDualFeasible_; |
| 450 | algorithm_ = rhs.algorithm_; |
| 451 | } |
| 452 | |
| 453 | void |
| 454 | ClpInterior::gutsOfDelete() |
| 455 | { |
| 456 | delete [] lower_; |
| 457 | lower_ = NULL; |
| 458 | rowLowerWork_ = NULL; |
| 459 | columnLowerWork_ = NULL; |
| 460 | delete [] upper_; |
| 461 | upper_ = NULL; |
| 462 | rowUpperWork_ = NULL; |
| 463 | columnUpperWork_ = NULL; |
| 464 | delete [] cost_; |
| 465 | cost_ = NULL; |
| 466 | delete [] rhs_; |
| 467 | rhs_ = NULL; |
| 468 | delete [] x_; |
| 469 | x_ = NULL; |
| 470 | delete [] y_; |
| 471 | y_ = NULL; |
| 472 | delete [] dj_; |
| 473 | dj_ = NULL; |
| 474 | #ifdef COIN_DO_PDCO |
| 475 | delete lsqrObject_; |
| 476 | lsqrObject_ = NULL; |
| 477 | //delete pdcoStuff_; |
| 478 | pdcoStuff_ = NULL; |
| 479 | #endif |
| 480 | delete [] errorRegion_; |
| 481 | errorRegion_ = NULL; |
| 482 | delete [] rhsFixRegion_; |
| 483 | rhsFixRegion_ = NULL; |
| 484 | delete [] deltaY_; |
| 485 | deltaY_ = NULL; |
| 486 | delete [] upperSlack_; |
| 487 | upperSlack_ = NULL; |
| 488 | delete [] lowerSlack_; |
| 489 | lowerSlack_ = NULL; |
| 490 | delete [] diagonal_; |
| 491 | diagonal_ = NULL; |
| 492 | delete [] deltaX_; |
| 493 | deltaX_ = NULL; |
| 494 | delete [] deltaZ_; |
| 495 | deltaZ_ = NULL; |
| 496 | delete [] deltaW_; |
| 497 | deltaW_ = NULL; |
| 498 | delete [] deltaSU_; |
| 499 | deltaSU_ = NULL; |
| 500 | delete [] deltaSL_; |
| 501 | deltaSL_ = NULL; |
| 502 | delete [] primalR_; |
| 503 | primalR_ = NULL; |
| 504 | delete [] dualR_; |
| 505 | dualR_ = NULL; |
| 506 | delete [] rhsB_; |
| 507 | rhsB_ = NULL; |
| 508 | delete [] rhsU_; |
| 509 | rhsU_ = NULL; |
| 510 | delete [] rhsL_; |
| 511 | rhsL_ = NULL; |
| 512 | delete [] rhsZ_; |
| 513 | rhsZ_ = NULL; |
| 514 | delete [] rhsW_; |
| 515 | rhsW_ = NULL; |
| 516 | delete [] rhsC_; |
| 517 | rhsC_ = NULL; |
| 518 | delete [] solution_; |
| 519 | solution_ = NULL; |
| 520 | delete [] workArray_; |
| 521 | workArray_ = NULL; |
| 522 | delete [] zVec_; |
| 523 | zVec_ = NULL; |
| 524 | delete [] wVec_; |
| 525 | wVec_ = NULL; |
| 526 | delete cholesky_; |
| 527 | } |
| 528 | bool |
| 529 | ClpInterior::createWorkingData() |
| 530 | { |
| 531 | bool goodMatrix = true; |
| 532 | //check matrix |
| 533 | if (!matrix_->allElementsInRange(this, 1.0e-12, 1.0e20)) { |
| 534 | problemStatus_ = 4; |
| 535 | goodMatrix = false; |
| 536 | } |
| 537 | int nTotal = numberRows_ + numberColumns_; |
| 538 | delete [] solution_; |
| 539 | solution_ = new CoinWorkDouble[nTotal]; |
| 540 | CoinMemcpyN(columnActivity_, numberColumns_, solution_); |
| 541 | CoinMemcpyN(rowActivity_, numberRows_, solution_ + numberColumns_); |
| 542 | delete [] cost_; |
| 543 | cost_ = new CoinWorkDouble[nTotal]; |
| 544 | int i; |
| 545 | CoinWorkDouble direction = optimizationDirection_ * objectiveScale_; |
| 546 | // direction is actually scale out not scale in |
| 547 | if (direction) |
| 548 | direction = 1.0 / direction; |
| 549 | const double * obj = objective(); |
| 550 | for (i = 0; i < numberColumns_; i++) |
| 551 | cost_[i] = direction * obj[i]; |
| 552 | memset(cost_ + numberColumns_, 0, numberRows_ * sizeof(CoinWorkDouble)); |
| 553 | // do scaling if needed |
| 554 | if (scalingFlag_ > 0 && !rowScale_) { |
| 555 | if (matrix_->scale(this)) |
| 556 | scalingFlag_ = -scalingFlag_; // not scaled after all |
| 557 | } |
| 558 | delete [] lower_; |
| 559 | delete [] upper_; |
| 560 | lower_ = new CoinWorkDouble[nTotal]; |
| 561 | upper_ = new CoinWorkDouble[nTotal]; |
| 562 | rowLowerWork_ = lower_ + numberColumns_; |
| 563 | columnLowerWork_ = lower_; |
| 564 | rowUpperWork_ = upper_ + numberColumns_; |
| 565 | columnUpperWork_ = upper_; |
| 566 | CoinMemcpyN(rowLower_, numberRows_, rowLowerWork_); |
| 567 | CoinMemcpyN(rowUpper_, numberRows_, rowUpperWork_); |
| 568 | CoinMemcpyN(columnLower_, numberColumns_, columnLowerWork_); |
| 569 | CoinMemcpyN(columnUpper_, numberColumns_, columnUpperWork_); |
| 570 | // clean up any mismatches on infinity |
| 571 | for (i = 0; i < numberColumns_; i++) { |
| 572 | if (columnLowerWork_[i] < -1.0e30) |
| 573 | columnLowerWork_[i] = -COIN_DBL_MAX; |
| 574 | if (columnUpperWork_[i] > 1.0e30) |
| 575 | columnUpperWork_[i] = COIN_DBL_MAX; |
| 576 | } |
| 577 | // clean up any mismatches on infinity |
| 578 | for (i = 0; i < numberRows_; i++) { |
| 579 | if (rowLowerWork_[i] < -1.0e30) |
| 580 | rowLowerWork_[i] = -COIN_DBL_MAX; |
| 581 | if (rowUpperWork_[i] > 1.0e30) |
| 582 | rowUpperWork_[i] = COIN_DBL_MAX; |
| 583 | } |
| 584 | // check rim of problem okay |
| 585 | if (!sanityCheck()) |
| 586 | goodMatrix = false; |
| 587 | if(rowScale_) { |
| 588 | for (i = 0; i < numberColumns_; i++) { |
| 589 | CoinWorkDouble multiplier = rhsScale_ / columnScale_[i]; |
| 590 | cost_[i] *= columnScale_[i]; |
| 591 | if (columnLowerWork_[i] > -1.0e50) |
| 592 | columnLowerWork_[i] *= multiplier; |
| 593 | if (columnUpperWork_[i] < 1.0e50) |
| 594 | columnUpperWork_[i] *= multiplier; |
| 595 | |
| 596 | } |
| 597 | for (i = 0; i < numberRows_; i++) { |
| 598 | CoinWorkDouble multiplier = rhsScale_ * rowScale_[i]; |
| 599 | if (rowLowerWork_[i] > -1.0e50) |
| 600 | rowLowerWork_[i] *= multiplier; |
| 601 | if (rowUpperWork_[i] < 1.0e50) |
| 602 | rowUpperWork_[i] *= multiplier; |
| 603 | } |
| 604 | } else if (rhsScale_ != 1.0) { |
| 605 | for (i = 0; i < numberColumns_ + numberRows_; i++) { |
| 606 | if (lower_[i] > -1.0e50) |
| 607 | lower_[i] *= rhsScale_; |
| 608 | if (upper_[i] < 1.0e50) |
| 609 | upper_[i] *= rhsScale_; |
| 610 | |
| 611 | } |
| 612 | } |
| 613 | assert (!errorRegion_); |
| 614 | errorRegion_ = new CoinWorkDouble [numberRows_]; |
| 615 | assert (!rhsFixRegion_); |
| 616 | rhsFixRegion_ = new CoinWorkDouble [numberRows_]; |
| 617 | assert (!deltaY_); |
| 618 | deltaY_ = new CoinWorkDouble [numberRows_]; |
| 619 | CoinZeroN(deltaY_, numberRows_); |
| 620 | assert (!upperSlack_); |
| 621 | upperSlack_ = new CoinWorkDouble [nTotal]; |
| 622 | assert (!lowerSlack_); |
| 623 | lowerSlack_ = new CoinWorkDouble [nTotal]; |
| 624 | assert (!diagonal_); |
| 625 | diagonal_ = new CoinWorkDouble [nTotal]; |
| 626 | assert (!deltaX_); |
| 627 | deltaX_ = new CoinWorkDouble [nTotal]; |
| 628 | CoinZeroN(deltaX_, nTotal); |
| 629 | assert (!deltaZ_); |
| 630 | deltaZ_ = new CoinWorkDouble [nTotal]; |
| 631 | CoinZeroN(deltaZ_, nTotal); |
| 632 | assert (!deltaW_); |
| 633 | deltaW_ = new CoinWorkDouble [nTotal]; |
| 634 | CoinZeroN(deltaW_, nTotal); |
| 635 | assert (!deltaSU_); |
| 636 | deltaSU_ = new CoinWorkDouble [nTotal]; |
| 637 | CoinZeroN(deltaSU_, nTotal); |
| 638 | assert (!deltaSL_); |
| 639 | deltaSL_ = new CoinWorkDouble [nTotal]; |
| 640 | CoinZeroN(deltaSL_, nTotal); |
| 641 | assert (!primalR_); |
| 642 | assert (!dualR_); |
| 643 | // create arrays if we are doing KKT |
| 644 | if (cholesky_->type() >= 20) { |
| 645 | primalR_ = new CoinWorkDouble [nTotal]; |
| 646 | CoinZeroN(primalR_, nTotal); |
| 647 | dualR_ = new CoinWorkDouble [numberRows_]; |
| 648 | CoinZeroN(dualR_, numberRows_); |
| 649 | } |
| 650 | assert (!rhsB_); |
| 651 | rhsB_ = new CoinWorkDouble [numberRows_]; |
| 652 | CoinZeroN(rhsB_, numberRows_); |
| 653 | assert (!rhsU_); |
| 654 | rhsU_ = new CoinWorkDouble [nTotal]; |
| 655 | CoinZeroN(rhsU_, nTotal); |
| 656 | assert (!rhsL_); |
| 657 | rhsL_ = new CoinWorkDouble [nTotal]; |
| 658 | CoinZeroN(rhsL_, nTotal); |
| 659 | assert (!rhsZ_); |
| 660 | rhsZ_ = new CoinWorkDouble [nTotal]; |
| 661 | CoinZeroN(rhsZ_, nTotal); |
| 662 | assert (!rhsW_); |
| 663 | rhsW_ = new CoinWorkDouble [nTotal]; |
| 664 | CoinZeroN(rhsW_, nTotal); |
| 665 | assert (!rhsC_); |
| 666 | rhsC_ = new CoinWorkDouble [nTotal]; |
| 667 | CoinZeroN(rhsC_, nTotal); |
| 668 | assert (!workArray_); |
| 669 | workArray_ = new CoinWorkDouble [nTotal]; |
| 670 | CoinZeroN(workArray_, nTotal); |
| 671 | assert (!zVec_); |
| 672 | zVec_ = new CoinWorkDouble [nTotal]; |
| 673 | CoinZeroN(zVec_, nTotal); |
| 674 | assert (!wVec_); |
| 675 | wVec_ = new CoinWorkDouble [nTotal]; |
| 676 | CoinZeroN(wVec_, nTotal); |
| 677 | assert (!dj_); |
| 678 | dj_ = new CoinWorkDouble [nTotal]; |
| 679 | if (!status_) |
| 680 | status_ = new unsigned char [numberRows_+numberColumns_]; |
| 681 | memset(status_, 0, numberRows_ + numberColumns_); |
| 682 | return goodMatrix; |
| 683 | } |
| 684 | void |
| 685 | ClpInterior::deleteWorkingData() |
| 686 | { |
| 687 | int i; |
| 688 | if (optimizationDirection_ != 1.0 || objectiveScale_ != 1.0) { |
| 689 | CoinWorkDouble scaleC = optimizationDirection_ / objectiveScale_; |
| 690 | // and modify all dual signs |
| 691 | for (i = 0; i < numberColumns_; i++) |
| 692 | reducedCost_[i] = scaleC * dj_[i]; |
| 693 | for (i = 0; i < numberRows_; i++) |
| 694 | dual_[i] *= scaleC; |
| 695 | } |
| 696 | if (rowScale_) { |
| 697 | CoinWorkDouble scaleR = 1.0 / rhsScale_; |
| 698 | for (i = 0; i < numberColumns_; i++) { |
| 699 | CoinWorkDouble scaleFactor = columnScale_[i]; |
| 700 | CoinWorkDouble valueScaled = columnActivity_[i]; |
| 701 | columnActivity_[i] = valueScaled * scaleFactor * scaleR; |
| 702 | CoinWorkDouble valueScaledDual = reducedCost_[i]; |
| 703 | reducedCost_[i] = valueScaledDual / scaleFactor; |
| 704 | } |
| 705 | for (i = 0; i < numberRows_; i++) { |
| 706 | CoinWorkDouble scaleFactor = rowScale_[i]; |
| 707 | CoinWorkDouble valueScaled = rowActivity_[i]; |
| 708 | rowActivity_[i] = (valueScaled * scaleR) / scaleFactor; |
| 709 | CoinWorkDouble valueScaledDual = dual_[i]; |
| 710 | dual_[i] = valueScaledDual * scaleFactor; |
| 711 | } |
| 712 | } else if (rhsScale_ != 1.0) { |
| 713 | CoinWorkDouble scaleR = 1.0 / rhsScale_; |
| 714 | for (i = 0; i < numberColumns_; i++) { |
| 715 | CoinWorkDouble valueScaled = columnActivity_[i]; |
| 716 | columnActivity_[i] = valueScaled * scaleR; |
| 717 | } |
| 718 | for (i = 0; i < numberRows_; i++) { |
| 719 | CoinWorkDouble valueScaled = rowActivity_[i]; |
| 720 | rowActivity_[i] = valueScaled * scaleR; |
| 721 | } |
| 722 | } |
| 723 | delete [] cost_; |
| 724 | cost_ = NULL; |
| 725 | delete [] solution_; |
| 726 | solution_ = NULL; |
| 727 | delete [] lower_; |
| 728 | lower_ = NULL; |
| 729 | delete [] upper_; |
| 730 | upper_ = NULL; |
| 731 | delete [] errorRegion_; |
| 732 | errorRegion_ = NULL; |
| 733 | delete [] rhsFixRegion_; |
| 734 | rhsFixRegion_ = NULL; |
| 735 | delete [] deltaY_; |
| 736 | deltaY_ = NULL; |
| 737 | delete [] upperSlack_; |
| 738 | upperSlack_ = NULL; |
| 739 | delete [] lowerSlack_; |
| 740 | lowerSlack_ = NULL; |
| 741 | delete [] diagonal_; |
| 742 | diagonal_ = NULL; |
| 743 | delete [] deltaX_; |
| 744 | deltaX_ = NULL; |
| 745 | delete [] workArray_; |
| 746 | workArray_ = NULL; |
| 747 | delete [] zVec_; |
| 748 | zVec_ = NULL; |
| 749 | delete [] wVec_; |
| 750 | wVec_ = NULL; |
| 751 | delete [] dj_; |
| 752 | dj_ = NULL; |
| 753 | } |
| 754 | // Sanity check on input data - returns true if okay |
| 755 | bool |
| 756 | ClpInterior::sanityCheck() |
| 757 | { |
| 758 | // bad if empty |
| 759 | if (!numberColumns_ || ((!numberRows_ || !matrix_->getNumElements()) && objective_->type() < 2)) { |
| 760 | problemStatus_ = emptyProblem(); |
| 761 | return false; |
| 762 | } |
| 763 | int numberBad ; |
| 764 | CoinWorkDouble largestBound, smallestBound, minimumGap; |
| 765 | CoinWorkDouble smallestObj, largestObj; |
| 766 | int firstBad; |
| 767 | int modifiedBounds = 0; |
| 768 | int i; |
| 769 | numberBad = 0; |
| 770 | firstBad = -1; |
| 771 | minimumGap = 1.0e100; |
| 772 | smallestBound = 1.0e100; |
| 773 | largestBound = 0.0; |
| 774 | smallestObj = 1.0e100; |
| 775 | largestObj = 0.0; |
| 776 | // If bounds are too close - fix |
| 777 | CoinWorkDouble fixTolerance = 1.1 * primalTolerance(); |
| 778 | for (i = numberColumns_; i < numberColumns_ + numberRows_; i++) { |
| 779 | CoinWorkDouble value; |
| 780 | value = CoinAbs(cost_[i]); |
| 781 | if (value > 1.0e50) { |
| 782 | numberBad++; |
| 783 | if (firstBad < 0) |
| 784 | firstBad = i; |
| 785 | } else if (value) { |
| 786 | if (value > largestObj) |
| 787 | largestObj = value; |
| 788 | if (value < smallestObj) |
| 789 | smallestObj = value; |
| 790 | } |
| 791 | value = upper_[i] - lower_[i]; |
| 792 | if (value < -primalTolerance()) { |
| 793 | numberBad++; |
| 794 | if (firstBad < 0) |
| 795 | firstBad = i; |
| 796 | } else if (value <= fixTolerance) { |
| 797 | if (value) { |
| 798 | // modify |
| 799 | upper_[i] = lower_[i]; |
| 800 | modifiedBounds++; |
| 801 | } |
| 802 | } else { |
| 803 | if (value < minimumGap) |
| 804 | minimumGap = value; |
| 805 | } |
| 806 | if (lower_[i] > -1.0e100 && lower_[i]) { |
| 807 | value = CoinAbs(lower_[i]); |
| 808 | if (value > largestBound) |
| 809 | largestBound = value; |
| 810 | if (value < smallestBound) |
| 811 | smallestBound = value; |
| 812 | } |
| 813 | if (upper_[i] < 1.0e100 && upper_[i]) { |
| 814 | value = CoinAbs(upper_[i]); |
| 815 | if (value > largestBound) |
| 816 | largestBound = value; |
| 817 | if (value < smallestBound) |
| 818 | smallestBound = value; |
| 819 | } |
| 820 | } |
| 821 | if (largestBound) |
| 822 | handler_->message(CLP_RIMSTATISTICS3, messages_) |
| 823 | << static_cast<double>(smallestBound) |
| 824 | << static_cast<double>(largestBound) |
| 825 | << static_cast<double>(minimumGap) |
| 826 | << CoinMessageEol; |
| 827 | minimumGap = 1.0e100; |
| 828 | smallestBound = 1.0e100; |
| 829 | largestBound = 0.0; |
| 830 | for (i = 0; i < numberColumns_; i++) { |
| 831 | CoinWorkDouble value; |
| 832 | value = CoinAbs(cost_[i]); |
| 833 | if (value > 1.0e50) { |
| 834 | numberBad++; |
| 835 | if (firstBad < 0) |
| 836 | firstBad = i; |
| 837 | } else if (value) { |
| 838 | if (value > largestObj) |
| 839 | largestObj = value; |
| 840 | if (value < smallestObj) |
| 841 | smallestObj = value; |
| 842 | } |
| 843 | value = upper_[i] - lower_[i]; |
| 844 | if (value < -primalTolerance()) { |
| 845 | numberBad++; |
| 846 | if (firstBad < 0) |
| 847 | firstBad = i; |
| 848 | } else if (value <= fixTolerance) { |
| 849 | if (value) { |
| 850 | // modify |
| 851 | upper_[i] = lower_[i]; |
| 852 | modifiedBounds++; |
| 853 | } |
| 854 | } else { |
| 855 | if (value < minimumGap) |
| 856 | minimumGap = value; |
| 857 | } |
| 858 | if (lower_[i] > -1.0e100 && lower_[i]) { |
| 859 | value = CoinAbs(lower_[i]); |
| 860 | if (value > largestBound) |
| 861 | largestBound = value; |
| 862 | if (value < smallestBound) |
| 863 | smallestBound = value; |
| 864 | } |
| 865 | if (upper_[i] < 1.0e100 && upper_[i]) { |
| 866 | value = CoinAbs(upper_[i]); |
| 867 | if (value > largestBound) |
| 868 | largestBound = value; |
| 869 | if (value < smallestBound) |
| 870 | smallestBound = value; |
| 871 | } |
| 872 | } |
| 873 | char rowcol[] = {'R', 'C'}; |
| 874 | if (numberBad) { |
| 875 | handler_->message(CLP_BAD_BOUNDS, messages_) |
| 876 | << numberBad |
| 877 | << rowcol[isColumn(firstBad)] << sequenceWithin(firstBad) |
| 878 | << CoinMessageEol; |
| 879 | problemStatus_ = 4; |
| 880 | return false; |
| 881 | } |
| 882 | if (modifiedBounds) |
| 883 | handler_->message(CLP_MODIFIEDBOUNDS, messages_) |
| 884 | << modifiedBounds |
| 885 | << CoinMessageEol; |
| 886 | handler_->message(CLP_RIMSTATISTICS1, messages_) |
| 887 | << static_cast<double>(smallestObj) |
| 888 | << static_cast<double>(largestObj) |
| 889 | << CoinMessageEol; |
| 890 | if (largestBound) |
| 891 | handler_->message(CLP_RIMSTATISTICS2, messages_) |
| 892 | << static_cast<double>(smallestBound) |
| 893 | << static_cast<double>(largestBound) |
| 894 | << static_cast<double>(minimumGap) |
| 895 | << CoinMessageEol; |
| 896 | return true; |
| 897 | } |
| 898 | /* Loads a problem (the constraints on the |
| 899 | rows are given by lower and upper bounds). If a pointer is 0 then the |
| 900 | following values are the default: |
| 901 | <ul> |
| 902 | <li> <code>colub</code>: all columns have upper bound infinity |
| 903 | <li> <code>collb</code>: all columns have lower bound 0 |
| 904 | <li> <code>rowub</code>: all rows have upper bound infinity |
| 905 | <li> <code>rowlb</code>: all rows have lower bound -infinity |
| 906 | <li> <code>obj</code>: all variables have 0 objective coefficient |
| 907 | </ul> |
| 908 | */ |
| 909 | void |
| 910 | ClpInterior::loadProblem ( const ClpMatrixBase& matrix, |
| 911 | const double* collb, const double* colub, |
| 912 | const double* obj, |
| 913 | const double* rowlb, const double* rowub, |
| 914 | const double * rowObjective) |
| 915 | { |
| 916 | ClpModel::loadProblem(matrix, collb, colub, obj, rowlb, rowub, |
| 917 | rowObjective); |
| 918 | } |
| 919 | void |
| 920 | ClpInterior::loadProblem ( const CoinPackedMatrix& matrix, |
| 921 | const double* collb, const double* colub, |
| 922 | const double* obj, |
| 923 | const double* rowlb, const double* rowub, |
| 924 | const double * rowObjective) |
| 925 | { |
| 926 | ClpModel::loadProblem(matrix, collb, colub, obj, rowlb, rowub, |
| 927 | rowObjective); |
| 928 | } |
| 929 | |
| 930 | /* Just like the other loadProblem() method except that the matrix is |
| 931 | given in a standard column major ordered format (without gaps). */ |
| 932 | void |
| 933 | ClpInterior::loadProblem ( const int numcols, const int numrows, |
| 934 | const CoinBigIndex* start, const int* index, |
| 935 | const double* value, |
| 936 | const double* collb, const double* colub, |
| 937 | const double* obj, |
| 938 | const double* rowlb, const double* rowub, |
| 939 | const double * rowObjective) |
| 940 | { |
| 941 | ClpModel::loadProblem(numcols, numrows, start, index, value, |
| 942 | collb, colub, obj, rowlb, rowub, |
| 943 | rowObjective); |
| 944 | } |
| 945 | void |
| 946 | ClpInterior::loadProblem ( const int numcols, const int numrows, |
| 947 | const CoinBigIndex* start, const int* index, |
| 948 | const double* value, const int * length, |
| 949 | const double* collb, const double* colub, |
| 950 | const double* obj, |
| 951 | const double* rowlb, const double* rowub, |
| 952 | const double * rowObjective) |
| 953 | { |
| 954 | ClpModel::loadProblem(numcols, numrows, start, index, value, length, |
| 955 | collb, colub, obj, rowlb, rowub, |
| 956 | rowObjective); |
| 957 | } |
| 958 | // Read an mps file from the given filename |
| 959 | int |
| 960 | ClpInterior::readMps(const char *filename, |
| 961 | bool keepNames, |
| 962 | bool ignoreErrors) |
| 963 | { |
| 964 | int status = ClpModel::readMps(filename, keepNames, ignoreErrors); |
| 965 | return status; |
| 966 | } |
| 967 | #ifdef COIN_DO_PDCO |
| 968 | #include "ClpPdco.hpp" |
| 969 | /* Pdco algorithm - see ClpPdco.hpp for method */ |
| 970 | int |
| 971 | ClpInterior::pdco() |
| 972 | { |
| 973 | return ((ClpPdco *) this)->pdco(); |
| 974 | } |
| 975 | // ** Temporary version |
| 976 | int |
| 977 | ClpInterior::pdco( ClpPdcoBase * stuff, Options &options, Info &info, Outfo &outfo) |
| 978 | { |
| 979 | return ((ClpPdco *) this)->pdco(stuff, options, info, outfo); |
| 980 | } |
| 981 | #endif |
| 982 | #include "ClpPredictorCorrector.hpp" |
| 983 | // Primal-Dual Predictor-Corrector barrier |
| 984 | int |
| 985 | ClpInterior::primalDual() |
| 986 | { |
| 987 | return (static_cast<ClpPredictorCorrector *> (this))->solve(); |
| 988 | } |
| 989 | |
| 990 | void |
| 991 | ClpInterior::checkSolution() |
| 992 | { |
| 993 | int iRow, iColumn; |
| 994 | CoinWorkDouble * reducedCost = reinterpret_cast<CoinWorkDouble *>(reducedCost_); |
| 995 | CoinWorkDouble * dual = reinterpret_cast<CoinWorkDouble *>(dual_); |
| 996 | CoinMemcpyN(cost_, numberColumns_, reducedCost); |
| 997 | matrix_->transposeTimes(-1.0, dual, reducedCost); |
| 998 | // Now modify reduced costs for quadratic |
| 999 | CoinWorkDouble quadraticOffset = quadraticDjs(reducedCost, |
| 1000 | solution_, scaleFactor_); |
| 1001 | |
| 1002 | objectiveValue_ = 0.0; |
| 1003 | // now look at solution |
| 1004 | sumPrimalInfeasibilities_ = 0.0; |
| 1005 | sumDualInfeasibilities_ = 0.0; |
| 1006 | CoinWorkDouble dualTolerance = 10.0 * dblParam_[ClpDualTolerance]; |
| 1007 | CoinWorkDouble primalTolerance = dblParam_[ClpPrimalTolerance]; |
| 1008 | CoinWorkDouble primalTolerance2 = 10.0 * dblParam_[ClpPrimalTolerance]; |
| 1009 | worstComplementarity_ = 0.0; |
| 1010 | complementarityGap_ = 0.0; |
| 1011 | |
| 1012 | // Done scaled - use permanent regions for output |
| 1013 | // but internal for bounds |
| 1014 | const CoinWorkDouble * lower = lower_ + numberColumns_; |
| 1015 | const CoinWorkDouble * upper = upper_ + numberColumns_; |
| 1016 | for (iRow = 0; iRow < numberRows_; iRow++) { |
| 1017 | CoinWorkDouble infeasibility = 0.0; |
| 1018 | CoinWorkDouble distanceUp = CoinMin(upper[iRow] - |
| 1019 | rowActivity_[iRow], static_cast<CoinWorkDouble>(1.0e10)); |
| 1020 | CoinWorkDouble distanceDown = CoinMin(rowActivity_[iRow] - |
| 1021 | lower[iRow], static_cast<CoinWorkDouble>(1.0e10)); |
| 1022 | if (distanceUp > primalTolerance2) { |
| 1023 | CoinWorkDouble value = dual[iRow]; |
| 1024 | // should not be negative |
| 1025 | if (value < -dualTolerance) { |
| 1026 | sumDualInfeasibilities_ += -dualTolerance - value; |
| 1027 | value = - value * distanceUp; |
| 1028 | if (value > worstComplementarity_) |
| 1029 | worstComplementarity_ = value; |
| 1030 | complementarityGap_ += value; |
| 1031 | } |
| 1032 | } |
| 1033 | if (distanceDown > primalTolerance2) { |
| 1034 | CoinWorkDouble value = dual[iRow]; |
| 1035 | // should not be positive |
| 1036 | if (value > dualTolerance) { |
| 1037 | sumDualInfeasibilities_ += value - dualTolerance; |
| 1038 | value = value * distanceDown; |
| 1039 | if (value > worstComplementarity_) |
| 1040 | worstComplementarity_ = value; |
| 1041 | complementarityGap_ += value; |
| 1042 | } |
| 1043 | } |
| 1044 | if (rowActivity_[iRow] > upper[iRow]) { |
| 1045 | infeasibility = rowActivity_[iRow] - upper[iRow]; |
| 1046 | } else if (rowActivity_[iRow] < lower[iRow]) { |
| 1047 | infeasibility = lower[iRow] - rowActivity_[iRow]; |
| 1048 | } |
| 1049 | if (infeasibility > primalTolerance) { |
| 1050 | sumPrimalInfeasibilities_ += infeasibility - primalTolerance; |
| 1051 | } |
| 1052 | } |
| 1053 | lower = lower_; |
| 1054 | upper = upper_; |
| 1055 | for (iColumn = 0; iColumn < numberColumns_; iColumn++) { |
| 1056 | CoinWorkDouble infeasibility = 0.0; |
| 1057 | objectiveValue_ += cost_[iColumn] * columnActivity_[iColumn]; |
| 1058 | CoinWorkDouble distanceUp = CoinMin(upper[iColumn] - |
| 1059 | columnActivity_[iColumn], static_cast<CoinWorkDouble>(1.0e10)); |
| 1060 | CoinWorkDouble distanceDown = CoinMin(columnActivity_[iColumn] - |
| 1061 | lower[iColumn], static_cast<CoinWorkDouble>(1.0e10)); |
| 1062 | if (distanceUp > primalTolerance2) { |
| 1063 | CoinWorkDouble value = reducedCost[iColumn]; |
| 1064 | // should not be negative |
| 1065 | if (value < -dualTolerance) { |
| 1066 | sumDualInfeasibilities_ += -dualTolerance - value; |
| 1067 | value = - value * distanceUp; |
| 1068 | if (value > worstComplementarity_) |
| 1069 | worstComplementarity_ = value; |
| 1070 | complementarityGap_ += value; |
| 1071 | } |
| 1072 | } |
| 1073 | if (distanceDown > primalTolerance2) { |
| 1074 | CoinWorkDouble value = reducedCost[iColumn]; |
| 1075 | // should not be positive |
| 1076 | if (value > dualTolerance) { |
| 1077 | sumDualInfeasibilities_ += value - dualTolerance; |
| 1078 | value = value * distanceDown; |
| 1079 | if (value > worstComplementarity_) |
| 1080 | worstComplementarity_ = value; |
| 1081 | complementarityGap_ += value; |
| 1082 | } |
| 1083 | } |
| 1084 | if (columnActivity_[iColumn] > upper[iColumn]) { |
| 1085 | infeasibility = columnActivity_[iColumn] - upper[iColumn]; |
| 1086 | } else if (columnActivity_[iColumn] < lower[iColumn]) { |
| 1087 | infeasibility = lower[iColumn] - columnActivity_[iColumn]; |
| 1088 | } |
| 1089 | if (infeasibility > primalTolerance) { |
| 1090 | sumPrimalInfeasibilities_ += infeasibility - primalTolerance; |
| 1091 | } |
| 1092 | } |
| 1093 | #if COIN_LONG_WORK |
| 1094 | // ok as packs down |
| 1095 | CoinMemcpyN(reducedCost, numberColumns_, reducedCost_); |
| 1096 | #endif |
| 1097 | // add in offset |
| 1098 | objectiveValue_ += 0.5 * quadraticOffset; |
| 1099 | } |
| 1100 | // Set cholesky (and delete present one) |
| 1101 | void |
| 1102 | ClpInterior::setCholesky(ClpCholeskyBase * cholesky) |
| 1103 | { |
| 1104 | delete cholesky_; |
| 1105 | cholesky_ = cholesky; |
| 1106 | } |
| 1107 | /* Borrow model. This is so we dont have to copy large amounts |
| 1108 | of data around. It assumes a derived class wants to overwrite |
| 1109 | an empty model with a real one - while it does an algorithm. |
| 1110 | This is same as ClpModel one. */ |
| 1111 | void |
| 1112 | ClpInterior::borrowModel(ClpModel & otherModel) |
| 1113 | { |
| 1114 | ClpModel::borrowModel(otherModel); |
| 1115 | } |
| 1116 | /* Return model - updates any scalars */ |
| 1117 | void |
| 1118 | ClpInterior::returnModel(ClpModel & otherModel) |
| 1119 | { |
| 1120 | ClpModel::returnModel(otherModel); |
| 1121 | } |
| 1122 | // Return number fixed to see if worth presolving |
| 1123 | int |
| 1124 | ClpInterior::numberFixed() const |
| 1125 | { |
| 1126 | int i; |
| 1127 | int nFixed = 0; |
| 1128 | for (i = 0; i < numberColumns_; i++) { |
| 1129 | if (columnUpper_[i] < 1.0e20 || columnLower_[i] > -1.0e20) { |
| 1130 | if (columnUpper_[i] > columnLower_[i]) { |
| 1131 | if (fixedOrFree(i)) |
| 1132 | nFixed++; |
| 1133 | } |
| 1134 | } |
| 1135 | } |
| 1136 | for (i = 0; i < numberRows_; i++) { |
| 1137 | if (rowUpper_[i] < 1.0e20 || rowLower_[i] > -1.0e20) { |
| 1138 | if (rowUpper_[i] > rowLower_[i]) { |
| 1139 | if (fixedOrFree(i + numberColumns_)) |
| 1140 | nFixed++; |
| 1141 | } |
| 1142 | } |
| 1143 | } |
| 1144 | return nFixed; |
| 1145 | } |
| 1146 | // fix variables interior says should be |
| 1147 | void |
| 1148 | ClpInterior::fixFixed(bool reallyFix) |
| 1149 | { |
| 1150 | // Arrays for change in columns and rhs |
| 1151 | CoinWorkDouble * columnChange = new CoinWorkDouble[numberColumns_]; |
| 1152 | CoinWorkDouble * rowChange = new CoinWorkDouble[numberRows_]; |
| 1153 | CoinZeroN(columnChange, numberColumns_); |
| 1154 | CoinZeroN(rowChange, numberRows_); |
| 1155 | matrix_->times(1.0, columnChange, rowChange); |
| 1156 | int i; |
| 1157 | CoinWorkDouble tolerance = primalTolerance(); |
| 1158 | for (i = 0; i < numberColumns_; i++) { |
| 1159 | if (columnUpper_[i] < 1.0e20 || columnLower_[i] > -1.0e20) { |
| 1160 | if (columnUpper_[i] > columnLower_[i]) { |
| 1161 | if (fixedOrFree(i)) { |
| 1162 | if (columnActivity_[i] - columnLower_[i] < columnUpper_[i] - columnActivity_[i]) { |
| 1163 | CoinWorkDouble change = columnLower_[i] - columnActivity_[i]; |
| 1164 | if (CoinAbs(change) < tolerance) { |
| 1165 | if (reallyFix) |
| 1166 | columnUpper_[i] = columnLower_[i]; |
| 1167 | columnChange[i] = change; |
| 1168 | columnActivity_[i] = columnLower_[i]; |
| 1169 | } |
| 1170 | } else { |
| 1171 | CoinWorkDouble change = columnUpper_[i] - columnActivity_[i]; |
| 1172 | if (CoinAbs(change) < tolerance) { |
| 1173 | if (reallyFix) |
| 1174 | columnLower_[i] = columnUpper_[i]; |
| 1175 | columnChange[i] = change; |
| 1176 | columnActivity_[i] = columnUpper_[i]; |
| 1177 | } |
| 1178 | } |
| 1179 | } |
| 1180 | } |
| 1181 | } |
| 1182 | } |
| 1183 | CoinZeroN(rowChange, numberRows_); |
| 1184 | matrix_->times(1.0, columnChange, rowChange); |
| 1185 | // If makes mess of things then don't do |
| 1186 | CoinWorkDouble newSum = 0.0; |
| 1187 | for (i = 0; i < numberRows_; i++) { |
| 1188 | CoinWorkDouble value = rowActivity_[i] + rowChange[i]; |
| 1189 | if (value > rowUpper_[i] + tolerance) |
| 1190 | newSum += value - rowUpper_[i] - tolerance; |
| 1191 | else if (value < rowLower_[i] - tolerance) |
| 1192 | newSum -= value - rowLower_[i] + tolerance; |
| 1193 | } |
| 1194 | if (newSum > 1.0e-5 + 1.5 * sumPrimalInfeasibilities_) { |
| 1195 | // put back and skip changes |
| 1196 | for (i = 0; i < numberColumns_; i++) |
| 1197 | columnActivity_[i] -= columnChange[i]; |
| 1198 | } else { |
| 1199 | CoinZeroN(rowActivity_, numberRows_); |
| 1200 | matrix_->times(1.0, columnActivity_, rowActivity_); |
| 1201 | if (reallyFix) { |
| 1202 | for (i = 0; i < numberRows_; i++) { |
| 1203 | if (rowUpper_[i] < 1.0e20 || rowLower_[i] > -1.0e20) { |
| 1204 | if (rowUpper_[i] > rowLower_[i]) { |
| 1205 | if (fixedOrFree(i + numberColumns_)) { |
| 1206 | if (rowActivity_[i] - rowLower_[i] < rowUpper_[i] - rowActivity_[i]) { |
| 1207 | CoinWorkDouble change = rowLower_[i] - rowActivity_[i]; |
| 1208 | if (CoinAbs(change) < tolerance) { |
| 1209 | if (reallyFix) |
| 1210 | rowUpper_[i] = rowLower_[i]; |
| 1211 | rowActivity_[i] = rowLower_[i]; |
| 1212 | } |
| 1213 | } else { |
| 1214 | CoinWorkDouble change = rowLower_[i] - rowActivity_[i]; |
| 1215 | if (CoinAbs(change) < tolerance) { |
| 1216 | if (reallyFix) |
| 1217 | rowLower_[i] = rowUpper_[i]; |
| 1218 | rowActivity_[i] = rowUpper_[i]; |
| 1219 | } |
| 1220 | } |
| 1221 | } |
| 1222 | } |
| 1223 | } |
| 1224 | } |
| 1225 | } |
| 1226 | } |
| 1227 | delete [] rowChange; |
| 1228 | delete [] columnChange; |
| 1229 | } |
| 1230 | /* Modifies djs to allow for quadratic. |
| 1231 | returns quadratic offset */ |
| 1232 | CoinWorkDouble |
| 1233 | ClpInterior::quadraticDjs(CoinWorkDouble * djRegion, const CoinWorkDouble * solution, |
| 1234 | CoinWorkDouble scaleFactor) |
| 1235 | { |
| 1236 | CoinWorkDouble quadraticOffset = 0.0; |
| 1237 | #ifndef NO_RTTI |
| 1238 | ClpQuadraticObjective * quadraticObj = (dynamic_cast< ClpQuadraticObjective*>(objective_)); |
| 1239 | #else |
| 1240 | ClpQuadraticObjective * quadraticObj = NULL; |
| 1241 | if (objective_->type() == 2) |
| 1242 | quadraticObj = (static_cast< ClpQuadraticObjective*>(objective_)); |
| 1243 | #endif |
| 1244 | if (quadraticObj) { |
| 1245 | CoinPackedMatrix * quadratic = quadraticObj->quadraticObjective(); |
| 1246 | const int * columnQuadratic = quadratic->getIndices(); |
| 1247 | const CoinBigIndex * columnQuadraticStart = quadratic->getVectorStarts(); |
| 1248 | const int * columnQuadraticLength = quadratic->getVectorLengths(); |
| 1249 | double * quadraticElement = quadratic->getMutableElements(); |
| 1250 | int numberColumns = quadratic->getNumCols(); |
| 1251 | for (int iColumn = 0; iColumn < numberColumns; iColumn++) { |
| 1252 | CoinWorkDouble value = 0.0; |
| 1253 | for (CoinBigIndex j = columnQuadraticStart[iColumn]; |
| 1254 | j < columnQuadraticStart[iColumn] + columnQuadraticLength[iColumn]; j++) { |
| 1255 | int jColumn = columnQuadratic[j]; |
| 1256 | CoinWorkDouble valueJ = solution[jColumn]; |
| 1257 | CoinWorkDouble elementValue = quadraticElement[j]; |
| 1258 | //value += valueI*valueJ*elementValue; |
| 1259 | value += valueJ * elementValue; |
| 1260 | quadraticOffset += solution[iColumn] * valueJ * elementValue; |
| 1261 | } |
| 1262 | djRegion[iColumn] += scaleFactor * value; |
| 1263 | } |
| 1264 | } |
| 1265 | return quadraticOffset; |
| 1266 | } |
| 1267 | |