00001
00002
00003
00004 #include "CoinPragma.hpp"
00005
00006 #include <math.h>
00007
00008 #include "CoinHelperFunctions.hpp"
00009 #include "ClpSimplexPrimalQuadratic.hpp"
00010 #include "ClpPrimalQuadraticDantzig.hpp"
00011 #include "ClpPrimalColumnDantzig.hpp"
00012 #include "ClpQuadraticObjective.hpp"
00013 #include "ClpFactorization.hpp"
00014 #include "ClpNonLinearCost.hpp"
00015 #include "ClpPackedMatrix.hpp"
00016 #include "CoinIndexedVector.hpp"
00017 #include "CoinWarmStartBasis.hpp"
00018 #include "CoinMpsIO.hpp"
00019 #include "ClpPrimalColumnPivot.hpp"
00020 #include "ClpMessage.hpp"
00021 #include <cfloat>
00022 #include <cassert>
00023 #include <string>
00024 #include <stdio.h>
00025 #include <iostream>
00026 class tempMessage :
00027 public CoinMessageHandler {
00028
00029 public:
00030 virtual int print() ;
00031 tempMessage(ClpSimplex * model);
00032 ClpSimplex * model_;
00033 };
00034
00035
00036 tempMessage::tempMessage(ClpSimplex * model)
00037 : CoinMessageHandler(),
00038 model_(model)
00039 {
00040 }
00041 int
00042 tempMessage::print()
00043 {
00044 static int numberFeasible=0;
00045 if (currentSource()=="Clp") {
00046 if (currentMessage().externalNumber()==5) {
00047 if (!numberFeasible&&!model_->nonLinearCost()->numberInfeasibilities()) {
00048 numberFeasible++;
00049 model_->setMaximumIterations(0);
00050 }
00051 }
00052 }
00053 return CoinMessageHandler::print();
00054 }
00055
00056
00057 int
00058 ClpSimplexPrimalQuadratic::primalSLP(int numberPasses, double deltaTolerance)
00059 {
00060
00061 double whichWay=optimizationDirection();
00062 if (whichWay<0.0)
00063 whichWay=-1.0;
00064 else if (whichWay>0.0)
00065 whichWay=1.0;
00066
00067
00068
00069 int numberColumns = this->numberColumns();
00070 int numberRows = this->numberRows();
00071 double * columnLower = this->columnLower();
00072 double * columnUpper = this->columnUpper();
00073 double * objective = this->objective();
00074 double * solution = this->primalColumnSolution();
00075
00076
00077
00078 double * saveObjective = new double [numberColumns];
00079 memcpy(saveObjective,objective,numberColumns*sizeof(double));
00080
00081
00082 ClpQuadraticObjective * quadraticObj = (dynamic_cast< ClpQuadraticObjective*>(objective_));
00083 CoinPackedMatrix * quadratic = NULL;
00084 if (quadraticObj)
00085 quadratic = quadraticObj->quadraticObjective();
00086 if (!quadratic) {
00087
00088 return primal(0);
00089 }
00090 int numberNonLinearColumns = 0;
00091 int iColumn;
00092 int * listNonLinearColumn = new int[numberColumns];
00093 memset(listNonLinearColumn,0,numberColumns*sizeof(int));
00094 const int * columnQuadratic = quadratic->getIndices();
00095 const int * columnQuadraticStart = quadratic->getVectorStarts();
00096 const int * columnQuadraticLength = quadratic->getVectorLengths();
00097 const double * quadraticElement = quadratic->getElements();
00098 for (iColumn=0;iColumn<numberColumns;iColumn++) {
00099 int j;
00100 for (j=columnQuadraticStart[iColumn];
00101 j<columnQuadraticStart[iColumn]+columnQuadraticLength[iColumn];j++) {
00102 int jColumn = columnQuadratic[j];
00103 listNonLinearColumn[jColumn]=1;
00104 listNonLinearColumn[iColumn]=1;
00105 }
00106 }
00107 for (iColumn=0;iColumn<numberColumns;iColumn++) {
00108 if(listNonLinearColumn[iColumn])
00109 listNonLinearColumn[numberNonLinearColumns++]=iColumn;
00110 }
00111
00112 if (!numberNonLinearColumns) {
00113 delete [] listNonLinearColumn;
00114
00115 return primal(0);
00116 }
00117
00118
00119 if (!this->status()||numberPrimalInfeasibilities())
00120 primal(1);
00121
00122 if (numberPrimalInfeasibilities())
00123 return 0;
00124
00125 int jNon;
00126 int * last[3];
00127
00128 double * trust = new double[numberNonLinearColumns];
00129 double * trueLower = new double[numberNonLinearColumns];
00130 double * trueUpper = new double[numberNonLinearColumns];
00131 for (jNon=0;jNon<numberNonLinearColumns;jNon++) {
00132 iColumn=listNonLinearColumn[jNon];
00133 trust[jNon]=0.5;
00134 trueLower[jNon]=columnLower[iColumn];
00135 trueUpper[jNon]=columnUpper[iColumn];
00136 if (solution[iColumn]<trueLower[jNon])
00137 solution[iColumn]=trueLower[jNon];
00138 else if (solution[iColumn]>trueUpper[jNon])
00139 solution[iColumn]=trueUpper[jNon];
00140 }
00141 int iPass;
00142 double lastObjective=1.0e31;
00143 double * saveSolution = new double [numberColumns];
00144 double * savePi = new double [numberRows];
00145 unsigned char * saveStatus = new unsigned char[numberRows+numberColumns];
00146 double targetDrop=1.0e31;
00147 double objectiveOffset;
00148 getDblParam(ClpObjOffset,objectiveOffset);
00149
00150 for (iPass=0;iPass<3;iPass++) {
00151 last[iPass]=new int[numberNonLinearColumns];
00152 for (jNon=0;jNon<numberNonLinearColumns;jNon++)
00153 last[iPass][jNon]=0;
00154 }
00155
00156 int goodMove=-2;
00157 char * statusCheck = new char[numberColumns];
00158 for (iPass=0;iPass<numberPasses;iPass++) {
00159
00160 double offset=0.0;
00161 double objValue=-objectiveOffset;
00162 double lambda=-1.0;
00163 if (goodMove>=0) {
00164
00165 double coeff0=-objectiveOffset,coeff1=0.0,coeff2=0.0;
00166 for (iColumn=0;iColumn<numberColumns;iColumn++) {
00167 coeff0 += saveObjective[iColumn]*solution[iColumn];
00168 coeff1 += saveObjective[iColumn]*(saveSolution[iColumn]-solution[iColumn]);
00169 }
00170 for (jNon=0;jNon<numberNonLinearColumns;jNon++) {
00171 iColumn=listNonLinearColumn[jNon];
00172 double valueI = solution[iColumn];
00173 double valueISave = saveSolution[iColumn];
00174 int j;
00175 for (j=columnQuadraticStart[iColumn];
00176 j<columnQuadraticStart[iColumn]+columnQuadraticLength[iColumn];j++) {
00177 int jColumn = columnQuadratic[j];
00178 double valueJ = solution[jColumn];
00179 double valueJSave = saveSolution[jColumn];
00180 double elementValue = 0.5*quadraticElement[j];
00181 coeff0 += valueI*valueJ*elementValue;
00182 coeff1 += (valueI*valueJSave+valueISave*valueJ-2.0*valueI*valueJ)*elementValue;
00183 coeff2 += (valueISave*valueJSave+valueI*valueJ-valueISave*valueJ-valueI*valueJSave)*elementValue;
00184 }
00185 }
00186 double lambdaValue;
00187 if (fabs(coeff2)<1.0e-9) {
00188 if (coeff1+coeff2>=0.0)
00189 lambda = 0.0;
00190 else
00191 lambda = 1.0;
00192 } else {
00193 lambda = -(0.5*coeff1)/coeff2;
00194 if (lambda>1.0||lambda<0.0) {
00195 if (coeff1+coeff2>=0.0)
00196 lambda = 0.0;
00197 else
00198 lambda = 1.0;
00199 }
00200 }
00201 lambdaValue = lambda*lambda*coeff2+lambda*coeff1+coeff0;
00202 printf("coeffs %g %g %g - lastobj %g\n",coeff0,coeff1,coeff2,lastObjective);
00203 printf("obj at saved %g, obj now %g zero deriv at %g - value %g\n",
00204 coeff0+coeff1+coeff2,coeff0,lambda,lambdaValue);
00205 if (!iPass) lambda=0.0;
00206 if (lambda>0.0&&lambda<=1.0) {
00207
00208 for (iColumn=0;iColumn<numberColumns;iColumn++)
00209 solution[iColumn] = lambda * saveSolution[iColumn]
00210 + (1.0-lambda) * solution[iColumn];
00211 if (lambda>0.999) {
00212 memcpy(this->dualRowSolution(),savePi,numberRows*sizeof(double));
00213 memcpy(status_,saveStatus,numberRows+numberColumns);
00214 }
00215 if (lambda>0.99999&&fabs(coeff1+coeff2)>1.0e-2) {
00216
00217 goodMove=-1;
00218 }
00219 }
00220 }
00221 memcpy(objective,saveObjective,numberColumns*sizeof(double));
00222 for (iColumn=0;iColumn<numberColumns;iColumn++)
00223 objValue += objective[iColumn]*solution[iColumn];
00224 for (jNon=0;jNon<numberNonLinearColumns;jNon++) {
00225 iColumn=listNonLinearColumn[jNon];
00226 if (getColumnStatus(iColumn)==basic) {
00227 if (solution[iColumn]<columnLower[iColumn]+1.0e-8)
00228 statusCheck[iColumn]='l';
00229 else if (solution[iColumn]>columnUpper[iColumn]-1.0e-8)
00230 statusCheck[iColumn]='u';
00231 else
00232 statusCheck[iColumn]='B';
00233 } else {
00234 if (solution[iColumn]<columnLower[iColumn]+1.0e-8)
00235 statusCheck[iColumn]='L';
00236 else
00237 statusCheck[iColumn]='U';
00238 }
00239 double valueI = solution[iColumn];
00240 int j;
00241 for (j=columnQuadraticStart[iColumn];
00242 j<columnQuadraticStart[iColumn]+columnQuadraticLength[iColumn];j++) {
00243 int jColumn = columnQuadratic[j];
00244 double valueJ = solution[jColumn];
00245 double elementValue = quadraticElement[j];
00246 elementValue *= 0.5;
00247 objValue += valueI*valueJ*elementValue;
00248 offset += valueI*valueJ*elementValue;
00249 double gradientI = valueJ*elementValue;
00250 double gradientJ = valueI*elementValue;
00251 offset -= gradientI*valueI;
00252 objective[iColumn] += gradientI;
00253 offset -= gradientJ*valueJ;
00254 objective[jColumn] += gradientJ;
00255 }
00256 }
00257 printf("objective %g, objective offset %g\n",objValue,offset);
00258 setDblParam(ClpObjOffset,objectiveOffset-offset);
00259 objValue *= whichWay;
00260 int * temp=last[2];
00261 last[2]=last[1];
00262 last[1]=last[0];
00263 last[0]=temp;
00264 for (jNon=0;jNon<numberNonLinearColumns;jNon++) {
00265 iColumn=listNonLinearColumn[jNon];
00266 double change = solution[iColumn]-saveSolution[iColumn];
00267 if (change<-1.0e-5) {
00268 if (fabs(change+trust[jNon])<1.0e-5)
00269 temp[jNon]=-1;
00270 else
00271 temp[jNon]=-2;
00272 } else if(change>1.0e-5) {
00273 if (fabs(change-trust[jNon])<1.0e-5)
00274 temp[jNon]=1;
00275 else
00276 temp[jNon]=2;
00277 } else {
00278 temp[jNon]=0;
00279 }
00280 }
00281
00282 double maxDelta=0.0;
00283 if (goodMove>=0) {
00284 if (objValue<=lastObjective)
00285 goodMove=1;
00286 else
00287 goodMove=0;
00288 } else {
00289 maxDelta=1.0e10;
00290 }
00291 double maxGap=0.0;
00292 for (jNon=0;jNon<numberNonLinearColumns;jNon++) {
00293 iColumn=listNonLinearColumn[jNon];
00294 maxDelta = max(maxDelta,
00295 fabs(solution[iColumn]-saveSolution[iColumn]));
00296 if (goodMove>0) {
00297 if (last[0][jNon]*last[1][jNon]<0) {
00298
00299 trust[jNon] *= 0.5;
00300 } else {
00301 if (last[0][jNon]==last[1][jNon]&&
00302 last[0][jNon]==last[2][jNon])
00303 trust[jNon] *= 1.5;
00304 }
00305 } else if (goodMove!=-2&&trust[jNon]>10.0*deltaTolerance) {
00306 trust[jNon] *= 0.2;
00307 }
00308 maxGap = max(maxGap,trust[jNon]);
00309 }
00310 std::cout<<"largest gap is "<<maxGap<<std::endl;
00311 if (iPass>10000) {
00312 for (jNon=0;jNon<numberNonLinearColumns;jNon++)
00313 trust[jNon] *=0.0001;
00314 }
00315 if (goodMove>0) {
00316 double drop = lastObjective-objValue;
00317 std::cout<<"True drop was "<<drop<<std::endl;
00318 std::cout<<"largest delta is "<<maxDelta<<std::endl;
00319 if (maxDelta<deltaTolerance&&drop<1.0e-4&&goodMove&&lambda<0.99999) {
00320 std::cout<<"Exiting"<<std::endl;
00321 break;
00322 }
00323 }
00324 if (!iPass)
00325 goodMove=1;
00326 targetDrop=0.0;
00327 double * r = this->dualColumnSolution();
00328 for (jNon=0;jNon<numberNonLinearColumns;jNon++) {
00329 iColumn=listNonLinearColumn[jNon];
00330 columnLower[iColumn]=max(solution[iColumn]
00331 -trust[jNon],
00332 trueLower[jNon]);
00333 columnUpper[iColumn]=min(solution[iColumn]
00334 +trust[jNon],
00335 trueUpper[jNon]);
00336 }
00337 if (iPass) {
00338
00339 this->matrix()->transposeTimes(savePi,
00340 this->dualColumnSolution());
00341 for (jNon=0;jNon<numberNonLinearColumns;jNon++) {
00342 iColumn=listNonLinearColumn[jNon];
00343 double dj = objective[iColumn]-r[iColumn];
00344 r[iColumn]=dj;
00345 if (dj<0.0)
00346 targetDrop -= dj*(columnUpper[iColumn]-solution[iColumn]);
00347 else
00348 targetDrop -= dj*(columnLower[iColumn]-solution[iColumn]);
00349 }
00350 } else {
00351 memset(r,0,numberColumns*sizeof(double));
00352 }
00353 #if 0
00354 for (jNon=0;jNon<numberNonLinearColumns;jNon++) {
00355 iColumn=listNonLinearColumn[jNon];
00356 if (statusCheck[iColumn]=='L'&&r[iColumn]<-1.0e-4) {
00357 columnLower[iColumn]=max(solution[iColumn],
00358 trueLower[jNon]);
00359 columnUpper[iColumn]=min(solution[iColumn]
00360 +trust[jNon],
00361 trueUpper[jNon]);
00362 } else if (statusCheck[iColumn]=='U'&&r[iColumn]>1.0e-4) {
00363 columnLower[iColumn]=max(solution[iColumn]
00364 -trust[jNon],
00365 trueLower[jNon]);
00366 columnUpper[iColumn]=min(solution[iColumn],
00367 trueUpper[jNon]);
00368 } else {
00369 columnLower[iColumn]=max(solution[iColumn]
00370 -trust[jNon],
00371 trueLower[jNon]);
00372 columnUpper[iColumn]=min(solution[iColumn]
00373 +trust[jNon],
00374 trueUpper[jNon]);
00375 }
00376 }
00377 #endif
00378 if (goodMove) {
00379 memcpy(saveSolution,solution,numberColumns*sizeof(double));
00380 memcpy(savePi,this->dualRowSolution(),numberRows*sizeof(double));
00381 memcpy(saveStatus,status_,numberRows+numberColumns);
00382
00383 std::cout<<"Pass - "<<iPass
00384 <<", target drop is "<<targetDrop
00385 <<std::endl;
00386 lastObjective = objValue;
00387 if (targetDrop<1.0e-5&&goodMove&&iPass) {
00388 printf("Exiting on target drop %g\n",targetDrop);
00389 break;
00390 }
00391 {
00392 double * r = this->dualColumnSolution();
00393 for (jNon=0;jNon<numberNonLinearColumns;jNon++) {
00394 iColumn=listNonLinearColumn[jNon];
00395 printf("Trust %d %g - solution %d %g obj %g dj %g state %c - bounds %g %g\n",
00396 jNon,trust[jNon],iColumn,solution[iColumn],objective[iColumn],
00397 r[iColumn],statusCheck[iColumn],columnLower[iColumn],
00398 columnUpper[iColumn]);
00399 }
00400 }
00401 setLogLevel(63);
00402 this->scaling(false);
00403 this->primal(1);
00404 if (this->status()) {
00405 CoinMpsIO writer;
00406 writer.setMpsData(*matrix(), COIN_DBL_MAX,
00407 getColLower(), getColUpper(),
00408 getObjCoefficients(),
00409 (const char*) 0 ,
00410 getRowLower(), getRowUpper(),
00411 NULL,NULL);
00412 writer.writeMps("xx.mps");
00413 }
00414 assert (!this->status());
00415 goodMove=1;
00416 } else {
00417
00418 printf("Backtracking\n");
00419 memcpy(solution,saveSolution,numberColumns*sizeof(double));
00420 memcpy(this->dualRowSolution(),savePi,numberRows*sizeof(double));
00421 memcpy(status_,saveStatus,numberRows+numberColumns);
00422 iPass--;
00423 goodMove=-1;
00424 }
00425 }
00426
00427 memcpy(solution,saveSolution,numberColumns*sizeof(double));
00428 for (jNon=0;jNon<numberNonLinearColumns;jNon++) {
00429 iColumn=listNonLinearColumn[jNon];
00430 columnLower[iColumn]=max(solution[iColumn],
00431 trueLower[jNon]);
00432 columnUpper[iColumn]=min(solution[iColumn],
00433 trueUpper[jNon]);
00434 }
00435 delete [] statusCheck;
00436 delete [] savePi;
00437 delete [] saveStatus;
00438
00439 double offset=0.0;
00440 double objValue=-objectiveOffset;
00441 memcpy(objective,saveObjective,numberColumns*sizeof(double));
00442 for (iColumn=0;iColumn<numberColumns;iColumn++)
00443 objValue += objective[iColumn]*solution[iColumn];
00444 for (jNon=0;jNon<numberNonLinearColumns;jNon++) {
00445 iColumn=listNonLinearColumn[jNon];
00446 double valueI = solution[iColumn];
00447 int j;
00448 for (j=columnQuadraticStart[iColumn];
00449 j<columnQuadraticStart[iColumn]+columnQuadraticLength[iColumn];j++) {
00450 int jColumn = columnQuadratic[j];
00451 double valueJ = solution[jColumn];
00452 double elementValue = quadraticElement[j];
00453 objValue += 0.5*valueI*valueJ*elementValue;
00454 offset += 0.5*valueI*valueJ*elementValue;
00455 double gradientI = valueJ*elementValue;
00456 double gradientJ = valueI*elementValue;
00457 offset -= gradientI*valueI;
00458 objective[iColumn] += gradientI;
00459 offset -= gradientJ*valueJ;
00460 objective[jColumn] += gradientJ;
00461 }
00462 }
00463 printf("objective %g, objective offset %g\n",objValue,offset);
00464 setDblParam(ClpObjOffset,objectiveOffset-offset);
00465 this->primal(1);
00466
00467 setDblParam(ClpObjOffset,objectiveOffset);
00468 objectiveValue_ += whichWay*offset;
00469 for (jNon=0;jNon<numberNonLinearColumns;jNon++) {
00470 iColumn=listNonLinearColumn[jNon];
00471 columnLower[iColumn]= trueLower[jNon];
00472 columnUpper[iColumn]= trueUpper[jNon];
00473 }
00474 memcpy(objective,saveObjective,numberColumns*sizeof(double));
00475 delete [] saveSolution;
00476 for (iPass=0;iPass<3;iPass++)
00477 delete [] last[iPass];
00478 delete [] trust;
00479 delete [] trueUpper;
00480 delete [] trueLower;
00481 delete [] saveObjective;
00482 delete [] listNonLinearColumn;
00483 return 0;
00484 }
00485
00486 int
00487 ClpSimplexPrimalQuadratic::primalQuadratic(int phase)
00488 {
00489
00490 if (numberPrimalInfeasibilities())
00491 primal(1);
00492
00493 if (numberPrimalInfeasibilities())
00494 return 1;
00495 ClpQuadraticInfo info;
00496 ClpSimplexPrimalQuadratic * model2 = makeQuadratic(info);
00497 if (!model2) {
00498 printf("** Not quadratic\n");
00499 primal(1);
00500 return 0;
00501 }
00502 #if 0
00503 CoinMpsIO writer;
00504 writer.setMpsData(*model2->matrix(), COIN_DBL_MAX,
00505 model2->getColLower(), model2->getColUpper(),
00506 model2->getObjCoefficients(),
00507 (const char*) 0 ,
00508 model2->getRowLower(), model2->getRowUpper(),
00509 NULL,NULL);
00510 writer.writeMps("xx.mps");
00511 #endif
00512
00513
00514 ClpPrimalColumnDantzig dantzigP;
00515 model2->setPrimalColumnPivotAlgorithm(dantzigP);
00516 model2->messageHandler()->setLogLevel(63);
00517 model2->primalQuadratic2(&info,phase);
00518 endQuadratic(model2,info);
00519 return 0;
00520 }
00521 int ClpSimplexPrimalQuadratic::primalQuadratic2 (ClpQuadraticInfo * info,
00522 int phase)
00523 {
00524
00525 algorithm_ = +2;
00526
00527
00528 ClpDataSave data = saveData();
00529
00530 assert ((dynamic_cast< ClpPackedMatrix*>(matrix_)));
00531
00532
00533
00534 int numberXColumns = info->numberXColumns();
00535 int numberXRows = info->numberXRows();
00536
00537 ClpObjective * saveObj = objectiveAsObject();
00538 setObjectivePointer(info->originalObjective());
00539 factorization_->setBiasLU(0);
00540 if (!startup(1)) {
00541
00542
00543
00544 info->setCurrentPhase(phase);
00545 int lastCleaned=0;
00546 info->setSequenceIn(-1);
00547 info->setCrucialSj(-1);
00548 bool deleteCosts=false;
00549 if (scalingFlag_>0) {
00550
00551 CoinPackedMatrix * quadratic = info->quadraticObjective();
00552 double * objective = info->linearObjective();
00553
00554 double * newElement = new double[numberXColumns];
00555
00556
00557 const int * row = quadratic->getIndices();
00558 const CoinBigIndex * columnStart = quadratic->getVectorStarts();
00559 const int * columnLength = quadratic->getVectorLengths();
00560 const double * elementByColumn = quadratic->getElements();
00561 double direction = optimizationDirection_;
00562
00563 if (direction)
00564 direction = 1.0/direction;
00565 int iColumn;
00566 for (iColumn=0;iColumn<numberXColumns;iColumn++) {
00567 int j;
00568 double scale = columnScale_[iColumn]*direction;
00569 const double * elementsInThisColumn = elementByColumn + columnStart[iColumn];
00570 const int * columnsInThisColumn = row + columnStart[iColumn];
00571 int number = columnLength[iColumn];
00572 assert (number<=numberXColumns);
00573 for (j=0;j<number;j++) {
00574 int iColumn2 = columnsInThisColumn[j];
00575 newElement[j] = elementsInThisColumn[j]*scale*rowScale_[iColumn2+numberXRows];
00576 }
00577 quadratic->replaceVector(iColumn,number,newElement);
00578 objective[iColumn] *= direction*columnScale_[iColumn];
00579 }
00580 delete [] newElement;
00581 deleteCosts=true;
00582 } else if (optimizationDirection_!=1.0) {
00583 CoinPackedMatrix * quadratic = info->quadraticObjective();
00584 double * objective = info->linearObjective();
00585
00586 double * newElement = new double[numberXColumns];
00587
00588 const CoinBigIndex * columnStart = quadratic->getVectorStarts();
00589 const int * columnLength = quadratic->getVectorLengths();
00590 const double * elementByColumn = quadratic->getElements();
00591 double direction = optimizationDirection_;
00592
00593 if (direction)
00594 direction = 1.0/direction;
00595 int iColumn;
00596 for (iColumn=0;iColumn<numberXColumns;iColumn++) {
00597 int j;
00598 const double * elementsInThisColumn = elementByColumn + columnStart[iColumn];
00599 int number = columnLength[iColumn];
00600 assert (number<=numberXColumns);
00601 for (j=0;j<number;j++) {
00602 newElement[j] = elementsInThisColumn[j]*direction;
00603 }
00604 quadratic->replaceVector(iColumn,number,newElement);
00605 objective[iColumn] *= direction;
00606 }
00607 delete [] newElement;
00608 deleteCosts=true;
00609 }
00610
00611
00612 pivotRow_=-2;
00613
00614
00615 int factorType=0;
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627 while (problemStatus_<0) {
00628 int iRow,iColumn;
00629
00630 for (iRow=0;iRow<4;iRow++) {
00631 rowArray_[iRow]->clear();
00632 }
00633
00634 for (iColumn=0;iColumn<2;iColumn++) {
00635 columnArray_[iColumn]->clear();
00636 }
00637
00638
00639
00640 matrix_->refresh(this);
00641
00642 if (lastGoodIteration_==numberIterations_)
00643 factorType=3;
00644
00645 statusOfProblemInPrimal(lastCleaned,factorType,progress_,info);
00646 if (problemStatus_>=0)
00647 break;
00648
00649 checkComplementarity (info,rowArray_[0],rowArray_[1]);
00650
00651
00652 factorType=1;
00653
00654
00655 pivotRow_=-2;
00656
00657
00658 if (info->currentSolution()&&info->sequenceIn()<0) {
00659 phase=0;
00660 int nextSequenceIn=-1;
00661 int numberQuadraticRows = info->numberQuadraticRows();
00662 for (iColumn=0;iColumn<numberXColumns;iColumn++) {
00663 double value = solution_[iColumn];
00664 double lower = lower_[iColumn];
00665 double upper = upper_[iColumn];
00666 if ((value>lower+primalTolerance_&&value<upper-primalTolerance_)
00667 ||getColumnStatus(iColumn)==superBasic) {
00668 if (getColumnStatus(iColumn)!=basic&&!flagged(iColumn)) {
00669 if (fabs(dj_[iColumn])>10.0*dualTolerance_||
00670 getColumnStatus(iColumn+numberXColumns+numberQuadraticRows)==basic) {
00671 if (phase!=2) {
00672 phase=2;
00673 nextSequenceIn=iColumn;
00674 }
00675 }
00676 }
00677 }
00678 }
00679 for (iColumn=numberColumns_;iColumn<numberColumns_+numberXRows;iColumn++) {
00680 double value = solution_[iColumn];
00681 double lower = lower_[iColumn];
00682 double upper = upper_[iColumn];
00683 if ((value>lower+primalTolerance_&&value<upper-primalTolerance_)
00684 ||getColumnStatus(iColumn)==superBasic) {
00685 if (getColumnStatus(iColumn)!=basic&&!flagged(iColumn)&&fabs(dj_[iColumn])>10.0*dualTolerance_) {
00686 if (phase!=2) {
00687 phase=2;
00688 nextSequenceIn=iColumn;
00689 }
00690 }
00691 }
00692 }
00693 info->setSequenceIn(nextSequenceIn);
00694 info->setCurrentPhase(phase);
00695 }
00696
00697
00698 dualIn_=0.0;
00699 if (!info->currentPhase()&&info->sequenceIn()<0&&primalColumnPivot_->pivotColumn(rowArray_[1],
00700 rowArray_[2],rowArray_[3],
00701 columnArray_[0],
00702 columnArray_[1]) < 0) {
00703 problemStatus_=0;
00704 break;
00705 }
00706
00707
00708 problemStatus_=-1;
00709 whileIterating(info);
00710 }
00711 if (deleteCosts) {
00712
00713 delete info->originalObjective();
00714 }
00715 }
00716 setObjectivePointer(saveObj);
00717
00718 finish();
00719 restoreData(data);
00720 return problemStatus_;
00721 }
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732 int
00733 ClpSimplexPrimalQuadratic::whileIterating(
00734 ClpQuadraticInfo * info)
00735 {
00736 checkComplementarity (info,rowArray_[0],rowArray_[1]);
00737 int crucialSj = info->crucialSj();
00738 if (info->crucialSj()>=0) {
00739 printf("after inv %d Sj value %g\n",crucialSj,solution_[info->crucialSj()]);
00740 }
00741 int returnCode=-1;
00742 int phase = info->currentPhase();
00743 double saveObjective = objectiveValue_;
00744 int numberXColumns = info->numberXColumns();
00745 int numberXRows = info->numberXRows();
00746 int numberQuadraticRows = info->numberQuadraticRows();
00747
00748
00749 {
00750 int * impliedSj = info->impliedSj();
00751 int i;
00752 for (i=numberRows_;i<numberColumns_;i++) {
00753 if (getColumnStatus(i)==basic)
00754 impliedSj[i-numberRows_]=i;
00755 else
00756 impliedSj[i-numberRows_]=-1;
00757 }
00758 int * basicRow = info->basicRow();
00759 for (i=0;i<numberRows_+numberColumns_;i++)
00760 basicRow[i]=-1;
00761 for (i=0;i<numberRows_;i++)
00762 basicRow[pivotVariable_[i]]=i;
00763 }
00764 int nextSequenceIn=info->sequenceIn();
00765 int oldSequenceIn=nextSequenceIn;
00766 int saveSequenceIn = sequenceIn_;
00767
00768
00769 while (problemStatus_==-1) {
00770 if (info->crucialSj()<0&&factorization_->pivots()>=10) {
00771 returnCode =-2;
00772 break;
00773 }
00774 #ifdef CLP_DEBUG
00775 {
00776 int i;
00777
00778 for (i=0;i<4;i++) {
00779 if (i!=1)
00780 rowArray_[i]->checkClear();
00781 }
00782 for (i=0;i<2;i++) {
00783 columnArray_[i]->checkClear();
00784 }
00785 }
00786 #endif
00787
00788
00789
00790
00791
00792
00793
00794 int cleanupIteration;
00795 if (nextSequenceIn<0) {
00796 cleanupIteration=0;
00797 if (phase==2) {
00798
00799
00800 int iColumn;
00801 int iStart = oldSequenceIn+1;
00802 for (iColumn=iStart;iColumn<numberXColumns;iColumn++) {
00803 double value = solution_[iColumn];
00804 double lower = lower_[iColumn];
00805 double upper = upper_[iColumn];
00806 if (value>lower+primalTolerance_&&value<upper-primalTolerance_) {
00807 if (getColumnStatus(iColumn)!=basic&&!flagged(iColumn)) {
00808 if (fabs(dj_[iColumn])>10.0*dualTolerance_||
00809 getColumnStatus(iColumn+numberXColumns+numberQuadraticRows)==basic) {
00810 nextSequenceIn=iColumn;
00811 break;
00812 }
00813 }
00814 }
00815 }
00816 if (nextSequenceIn<0) {
00817 iStart=max(iStart,numberColumns_);
00818 int numberXRows = info->numberXRows();
00819 for (iColumn=iStart;iColumn<numberColumns_+numberXRows;
00820 iColumn++) {
00821 double value = solution_[iColumn];
00822 double lower = lower_[iColumn];
00823 double upper = upper_[iColumn];
00824 if (value>lower+primalTolerance_&&value<upper-primalTolerance_) {
00825 if (getColumnStatus(iColumn)!=basic&&!flagged(iColumn)&&fabs(dj_[iColumn])>10.0*dualTolerance_) {
00826 nextSequenceIn=iColumn;
00827 break;
00828 }
00829 }
00830 }
00831 }
00832 oldSequenceIn=nextSequenceIn;
00833 saveSequenceIn=sequenceIn_;
00834 sequenceIn_ = nextSequenceIn;
00835 } else {
00836 saveSequenceIn=sequenceIn_;
00837 createDjs(info,rowArray_[3],rowArray_[2]);
00838 dualIn_=0.0;
00839 rowArray_[1]->clear();
00840 primalColumn(rowArray_[1],rowArray_[2],rowArray_[3],
00841 columnArray_[0],columnArray_[1]);
00842 }
00843 } else {
00844 saveSequenceIn=sequenceIn_;
00845 sequenceIn_ = nextSequenceIn;
00846 if (phase==2) {
00847 if ((sequenceIn_<numberXColumns||sequenceIn_>=numberColumns_)&&info->crucialSj()<0)
00848 cleanupIteration=0;
00849 else
00850 cleanupIteration=1;
00851 } else {
00852 cleanupIteration=1;
00853 }
00854 }
00855 pivotRow_=-1;
00856 sequenceOut_=-1;
00857 rowArray_[1]->clear();
00858 if (sequenceIn_>=0) {
00859 nextSequenceIn=-1;
00860
00861 int chosen = sequenceIn_;
00862
00863 while (chosen>=0) {
00864 int saveSequenceInInfo=chosen;
00865 int saveCrucialSjInfo=info->crucialSj();
00866 rowArray_[1]->clear();
00867 checkComplementarity (info,rowArray_[3],rowArray_[1]);
00868 printf("True objective is %g, infeas cost %g, sum %g\n",
00869 objectiveValue_,info->infeasCost(),objectiveValue_+info->infeasCost());
00870 objectiveValue_=saveObjective;
00871 returnCode=-1;
00872 pivotRow_=-1;
00873 sequenceOut_=-1;
00874
00875
00876 sequenceIn_=chosen;
00877 chosen=-1;
00878 unpack(rowArray_[1]);
00879
00880 {
00881 info->createGradient(this);
00882 double * gradient = info->gradient();
00883 dualIn_=gradient[sequenceIn_];
00884 int j;
00885 const double * element = rowArray_[1]->denseVector();
00886 int numberNonZero=rowArray_[1]->getNumElements();
00887 const int * whichRow = rowArray_[1]->getIndices();
00888 bool packed = rowArray_[1]->packedMode();
00889 if (packed) {
00890 for (j=0;j<numberNonZero; j++) {
00891 int iRow = whichRow[j];
00892 dualIn_ -= element[j]*dual_[iRow];
00893 }
00894 } else {
00895 for (j=0;j<numberNonZero; j++) {
00896 int iRow = whichRow[j];
00897 dualIn_ -= element[iRow]*dual_[iRow];
00898 }
00899 }
00900 }
00901 if ((!cleanupIteration&&sequenceIn_<numberXColumns)||
00902 (cleanupIteration&&info->crucialSj()<numberColumns_&&info->crucialSj()>=numberRows_)) {
00903 int iSequence;
00904 if (!cleanupIteration)
00905 iSequence=sequenceIn_;
00906 else
00907 iSequence=info->crucialSj()-numberRows_;
00908
00909 int * impliedSj = info->impliedSj();
00910 if (impliedSj[iSequence]>=0) {
00911
00912 impliedSj[iSequence]=-1;
00913 ClpPackedMatrix* rowCopy =
00914 dynamic_cast< ClpPackedMatrix*>(rowCopy_);
00915 assert(rowCopy);
00916 const int * column = rowCopy->getIndices();
00917 const CoinBigIndex * rowStart = rowCopy->getVectorStarts();
00918 const double * rowElement = rowCopy->getElements();
00919 int iRow=iSequence+numberXRows;
00920 int i;
00921 int * index = rowArray_[2]->getIndices();
00922 double * element = rowArray_[2]->denseVector();
00923 int n=0;
00924 int * basicRow = info->basicRow();
00925 int * permute = factorization_->pivotColumn();
00926 for (i=rowStart[iRow];i<rowStart[iRow+1];i++) {
00927 int iColumn = column[i];
00928 iColumn = basicRow[iColumn];
00929 if (iColumn>=0&&iColumn!=iRow) {
00930 index[n]=permute[iColumn];
00931 element[n++]=rowElement[i];
00932 }
00933 }
00934 factorization_->replaceRow(permute[iRow],n,index,element);
00935 memset(element,0,n*sizeof(double));
00936 }
00937 }
00938
00939 if (1) {
00940 int n=rowArray_[1]->getNumElements();
00941 int * index = rowArray_[1]->getIndices();
00942 double * element = rowArray_[1]->denseVector();
00943 int i;
00944 int * impliedSj = info->impliedSj();
00945 int n2=0;
00946 for (i=0;i<n;i++) {
00947 int iRow=index[i]-numberXRows;
00948 if (iRow<0||impliedSj[iRow]<0) {
00949 index[n2++]=iRow+numberXRows;
00950 } else {
00951 element[iRow+numberXRows]=0.0;
00952 }
00953 }
00954 rowArray_[1]->setNumElements(n2);
00955 }
00956 factorization_->updateColumnFT(rowArray_[2],rowArray_[1]);
00957 if (cleanupIteration) {
00958
00959 valueIn_=solution_[sequenceIn_];
00960
00961 int iSjRow=-1;
00962 if (crucialSj>=0) {
00963 double * work=rowArray_[1]->denseVector();
00964 int number=rowArray_[1]->getNumElements();
00965 int * which=rowArray_[1]->getIndices();
00966 double tj = 0.0;
00967 int iIndex;
00968 for (iIndex=0;iIndex<number;iIndex++) {
00969 int iRow = which[iIndex];
00970 double alpha = work[iRow];
00971 int iPivot=pivotVariable_[iRow];
00972 if (iPivot==crucialSj) {
00973 tj = alpha;
00974 iSjRow = iRow;
00975 double d2 = solution_[crucialSj]/tj;
00976 if (fabs(solution_[crucialSj])<1.0e-8)
00977 printf("zero crucialSj - pivot out - get right way\n");
00978
00979 if (d2>0)
00980 dj_[sequenceIn_]= -1.0;
00981 else
00982 dj_[sequenceIn_]= 1.0;
00983 break;
00984 }
00985 }
00986 if (!tj) {
00987 printf("trouble\n");
00988 assert (sequenceIn_>numberXColumns&&sequenceIn_<numberColumns_);
00989 dj_[sequenceIn_]=solution_[sequenceIn_];
00990
00991 }
00992 }
00993
00994 dualIn_=dj_[sequenceIn_];
00995 lowerIn_=lower_[sequenceIn_];
00996 upperIn_=upper_[sequenceIn_];
00997 if (dualIn_>0.0)
00998 directionIn_ = -1;
00999 else
01000 directionIn_ = 1;
01001 } else {
01002
01003 lowerIn_=lower_[sequenceIn_];
01004 upperIn_=upper_[sequenceIn_];
01005 dualIn_=dj_[sequenceIn_];
01006 valueIn_=solution_[sequenceIn_];
01007 if (dualIn_>0.0)
01008 directionIn_ = -1;
01009 else
01010 directionIn_ = 1;
01011 if (sequenceIn_<numberColumns_) {
01012
01013 crucialSj = sequenceIn_+ numberQuadraticRows+numberXColumns;
01014 } else {
01015
01016 int iRow = sequenceIn_-numberColumns_;
01017 crucialSj = iRow+numberXColumns;
01018 }
01019 if (crucialSj>=0&&getColumnStatus(crucialSj)!=basic)
01020 crucialSj=-1;
01021 info->setCrucialSj(crucialSj);
01022 }
01023 double oldSj=1.0e30;
01024 if (info->crucialSj()>=0&&cleanupIteration)
01025 oldSj= solution_[info->crucialSj()];
01026
01027
01028
01029
01030 int result=primalRow(rowArray_[1],rowArray_[3],
01031 rowArray_[2],rowArray_[0],
01032 info,
01033 cleanupIteration);
01034 if (pivotRow_==-1&&(phase==2||cleanupIteration)&&fabs(dualIn_)<1.0e-3) {
01035
01036 dualIn_=-dualIn_;
01037 directionIn_=-directionIn_;
01038 if (info->crucialSj()>=0)
01039 setColumnStatus(info->crucialSj(),basic);
01040 result=primalRow(rowArray_[1],rowArray_[3],
01041 rowArray_[2],rowArray_[0],
01042 info,
01043 cleanupIteration);
01044 }
01045 saveObjective = objectiveValue_;
01046 if (pivotRow_>=0) {
01047
01048
01049 int updateStatus = 0;
01050 if (result<20) {
01051 double saveCheck = factorization_->getAccuracyCheck();
01052 if (cleanupIteration)
01053 factorization_->relaxAccuracyCheck(1.0e3*saveCheck);
01054 updateStatus=factorization_->replaceColumn(rowArray_[2],
01055 pivotRow_,
01056 alpha_);
01057 factorization_->relaxAccuracyCheck(saveCheck);
01058 }
01059 if (result>=10) {
01060 updateStatus = max(updateStatus,result/10);
01061 result = result%10;
01062 if (updateStatus>1) {
01063 alpha_=0.0;
01064 info->setSequenceIn(sequenceIn_);
01065 }
01066 }
01067
01068 if (updateStatus==2&&
01069 lastGoodIteration_==numberIterations_&&fabs(alpha_)>1.0e-5)
01070 updateStatus=4;
01071 if (updateStatus==1||updateStatus==4) {
01072
01073 if (factorization_->pivots()>5||updateStatus==4) {
01074 returnCode=-3;
01075 }
01076 } else if (updateStatus==2) {
01077
01078
01079
01080 nextSequenceIn=saveSequenceInInfo;
01081 info->setCrucialSj(saveCrucialSjInfo);
01082 if (saveCrucialSjInfo<0&&!phase)
01083 nextSequenceIn=-1;
01084 pivotRow_=-1;
01085
01086 factorization_->zeroTolerance(1.0e-15);
01087 int maxFactor = factorization_->maximumPivots();
01088 if (maxFactor>10) {
01089 if (forceFactorization_<0)
01090 forceFactorization_= maxFactor;
01091 forceFactorization_ = max (1,(forceFactorization_>>1));
01092 }
01093
01094 if(lastGoodIteration_ != numberIterations_||factorization_->pivots()) {
01095 rowArray_[1]->clear();
01096 pivotRow_=-1;
01097 returnCode=-4;
01098
01099 if (info->crucialSj()>=0)
01100 nextSequenceIn = sequenceIn_;
01101 break;
01102 } else {
01103
01104 char x = isColumn(sequenceIn_) ? 'C' :'R';
01105 handler_->message(CLP_SIMPLEX_FLAG,messages_)
01106 <<x<<sequenceWithin(sequenceIn_)
01107 <<CoinMessageEol;
01108 setFlagged(sequenceIn_);
01109 lastBadIteration_ = numberIterations_;
01110 rowArray_[1]->clear();
01111 pivotRow_=-1;
01112 returnCode = -5;
01113 break;
01114
01115 }
01116 } else if (updateStatus==3) {
01117
01118
01119 if (factorization_->pivots()<
01120 0.5*factorization_->maximumPivots()&&
01121 factorization_->pivots()<200)
01122 factorization_->areaFactor(
01123 factorization_->areaFactor() * 1.1);
01124 returnCode =-2;
01125 }
01126
01127 primalColumnPivot_->updateWeights(rowArray_[1]);
01128 } else {
01129 if (pivotRow_==-1) {
01130
01131 rowArray_[0]->clear();
01132 if (!factorization_->pivots()) {
01133 returnCode = 2;
01134
01135 primalRay(rowArray_[1]);
01136 } else {
01137 returnCode = 4;
01138 }
01139 break;
01140 } else {
01141
01142 }
01143 }
01144
01145
01146
01147
01148 double objectiveChange=0.0;
01149
01150 double oldCost=0.0;
01151 if (pivotRow_>=0)
01152 oldCost = cost(pivotVariable_[pivotRow_]);
01153
01154 updatePrimalsInPrimal(rowArray_[1],theta_, objectiveChange,1);
01155 if (pivotRow_>=0)
01156 dualIn_ += (oldCost-cost(pivotVariable_[pivotRow_]));
01157 double oldValue = valueIn_;
01158 if (directionIn_==-1) {
01159
01160 if (sequenceIn_!=sequenceOut_) {
01161
01162 valueIn_ -= fabs(theta_);
01163 } else {
01164 valueIn_=lowerIn_;
01165 }
01166 } else {
01167
01168 if (sequenceIn_!=sequenceOut_) {
01169
01170 valueIn_ += fabs(theta_);
01171 } else {
01172 valueIn_=upperIn_;
01173 }
01174 }
01175 objectiveChange += dualIn_*(valueIn_-oldValue);
01176
01177 if (sequenceIn_!=sequenceOut_) {
01178 if (directionOut_>0) {
01179 valueOut_ = lowerOut_;
01180 } else {
01181 valueOut_ = upperOut_;
01182 }
01183 double lowerValue = lower_[sequenceOut_];
01184 double upperValue = upper_[sequenceOut_];
01185 if (sequenceOut_>=numberXColumns&&sequenceOut_<numberColumns_) {
01186
01187 lowerValue=0.0;
01188 upperValue=0.0;
01189 }
01190 assert(valueOut_>=lowerValue-primalTolerance_&&
01191 valueOut_<=upperValue+primalTolerance_);
01192
01193 #if 1
01194
01195 double useValue=valueOut_;
01196 if (valueOut_<=lowerValue+primalTolerance_) {
01197 directionOut_=1;
01198 useValue= lower_[sequenceOut_];
01199 } else if (valueOut_>=upperValue-primalTolerance_) {
01200 directionOut_=-1;
01201 useValue= upper_[sequenceOut_];
01202 } else {
01203 printf("*** variable wandered off bound %g %g %g!\n",
01204 lowerValue,valueOut_,upperValue);
01205 if (valueOut_-lowerValue<=upperValue-valueOut_) {
01206 useValue= lower_[sequenceOut_];
01207 valueOut_=lowerValue;
01208 directionOut_=1;
01209 } else {
01210 useValue= upper_[sequenceOut_];
01211 valueOut_=upperValue;
01212 directionOut_=-1;
01213 }
01214 }
01215 solution_[sequenceOut_]=valueOut_;
01216 nonLinearCost_->setOne(sequenceOut_,useValue);
01217 #else
01218 directionOut_=nonLinearCost_->setOneOutgoing(sequenceOut_,valueOut_);
01219 solution_[sequenceOut_]=valueOut_;
01220 #endif
01221 }
01222
01223 if (sequenceIn_==sequenceOut_&&(lowerOut_!=lowerIn_||upperOut_!=upperIn_)) {
01224
01225 setStatus(sequenceOut_,superBasic);
01226 }
01227 nonLinearCost_->setOne(sequenceIn_,valueIn_);
01228 int whatNext=housekeeping(objectiveChange);
01229
01230 if (sequenceIn_==sequenceOut_&&(lowerOut_!=lowerIn_||upperOut_!=upperIn_)) {
01231
01232 setStatus(sequenceOut_,superBasic);
01233 }
01234
01235 if (sequenceIn_!=sequenceOut_) {
01236 int * basicRow = info->basicRow();
01237 basicRow[sequenceOut_]=-1;
01238 basicRow[sequenceIn_]=pivotRow_;
01239 }
01240 if (info->crucialSj()>=0) {
01241 assert(fabs(oldSj)>= fabs(solution_[info->crucialSj()]));
01242 printf("%d Sj value went from %g to %g\n",crucialSj,oldSj,solution_[info->crucialSj()]);
01243 }
01244 checkComplementarity (info,rowArray_[2],rowArray_[3]);
01245 printf("After Housekeeping True objective is %g, infeas cost %g, sum %g\n",
01246 objectiveValue_,info->infeasCost(),objectiveValue_+info->infeasCost());
01247 if (sequenceOut_>=numberXColumns&&sequenceOut_<numberColumns_) {
01248
01249 setStatus(sequenceOut_,isFree);
01250 if (sequenceOut_==info->crucialSj())
01251 info->setCrucialSj(-1);
01252 } else if (info->crucialSj()>=0) {
01253
01254 int crucialSj=info->crucialSj();
01255 if (crucialSj>=numberXColumns+numberQuadraticRows) {
01256 if (sequenceOut_==crucialSj-numberXColumns-numberQuadraticRows)
01257 info->setCrucialSj(-1);
01258 } else {
01259 if (sequenceOut_-numberColumns_==crucialSj-numberXColumns)
01260 info->setCrucialSj(-1);
01261 }
01262 }
01263 if (info->crucialSj()<0)
01264 result=0;
01265 if (whatNext==1) {
01266 returnCode =-2;
01267 } else if (whatNext==2) {
01268
01269 returnCode=3;
01270 } else if(numberIterations_ == lastGoodIteration_
01271 + 2 * factorization_->maximumPivots()) {
01272
01273 returnCode =-2;
01274 }
01275
01276 cleanupIteration = 1;
01277
01278 if (result&&(returnCode==-1||returnCode==-2||returnCode==-3)) {
01279 int crucialSj=info->crucialSj();
01280 if (sequenceOut_<numberXColumns) {
01281 chosen =sequenceOut_ + numberQuadraticRows + numberXColumns;
01282 } else if (sequenceOut_>=numberColumns_) {
01283
01284 int iRow = sequenceOut_-numberColumns_;
01285 if (iRow<numberXRows) {
01286 chosen=iRow+numberXColumns;
01287 } else {
01288 printf("Row %d is in column part\n",iRow);
01289 abort();
01290 }
01291 } else if (sequenceOut_<numberQuadraticRows+numberXColumns) {
01292
01293 chosen = sequenceOut_-numberXColumns+numberColumns_;
01294 } else {
01295
01296 chosen = sequenceOut_-numberQuadraticRows-numberXColumns;
01297 }
01298
01299 if (chosen==crucialSj) {
01300 chosen=-1;
01301 break;
01302 }
01303 rowArray_[0]->clear();
01304 columnArray_[0]->clear();
01305 if (returnCode==-2) {
01306
01307 nextSequenceIn = chosen;
01308 break;
01309 }
01310 } else {
01311 break;
01312 }
01313 }
01314 if (returnCode<-1&&returnCode>-5) {
01315 problemStatus_=-2;
01316 } else if (returnCode==-5) {
01317
01318 } else if (returnCode==2) {
01319 problemStatus_=-5;
01320 } else if (returnCode==4) {
01321 problemStatus_=-2;
01322 } else if (returnCode!=-1) {
01323 assert(returnCode==3);
01324 problemStatus_=3;
01325 }
01326 } else {
01327
01328 #ifdef CLP_DEBUG
01329 if (handler_->logLevel()&32)
01330 printf("** no column pivot\n");
01331 #endif
01332 if (nonLinearCost_->numberInfeasibilities())
01333 problemStatus_=-4;
01334 returnCode=0;
01335 break;
01336 }
01337 }
01338 info->setSequenceIn(nextSequenceIn);
01339 return returnCode;
01340 }
01341
01342
01343
01344
01345
01346
01347
01348 int
01349 ClpSimplexPrimalQuadratic::primalRow(CoinIndexedVector * rowArray,
01350 CoinIndexedVector * rhsArray,
01351 CoinIndexedVector * spareArray,
01352 CoinIndexedVector * spareArray2,
01353 ClpQuadraticInfo * info,
01354 int cleanupIteration)
01355 {
01356 int result=1;
01357
01358
01359 pivotRow_=-1;
01360 int numberSwapped=0;
01361 int numberRemaining=0;
01362 int crucialSj = info->crucialSj();
01363 if (crucialSj<0)
01364 result=0;
01365 int numberThru =0;
01366 int lastThru =0;
01367
01368 double totalThru=0.0;
01369 double acceptablePivot=1.0e-7;
01370 if (factorization_->pivots())
01371 acceptablePivot=1.0e-5;
01372 double bestEverPivot=acceptablePivot;
01373 int lastPivotRow = -1;
01374 double lastPivot=0.0;
01375 double lastTheta=1.0e50;
01376 int lastNumberSwapped=0;
01377
01378
01379
01380
01381
01382
01383
01384
01385 int maximumSwapped=0;
01386
01387 double * spare;
01388
01389 int * index, * indexSwapped;
01390 int * saveSwapped;
01391 spareArray->clear();
01392 spareArray2->clear();
01393 spare = spareArray->denseVector();
01394 index = spareArray->getIndices();
01395 saveSwapped = (int *) spareArray2->denseVector();
01396 indexSwapped = spareArray2->getIndices();
01397
01398
01399 double * rhs=rhsArray->denseVector();
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414 double * work=rowArray->denseVector();
01415 int number=rowArray->getNumElements();
01416 int * which=rowArray->getIndices();
01417
01418
01419 double way = directionIn_;
01420 double maximumMovement;
01421 if (way>0.0)
01422 maximumMovement = min(1.0e30,upperIn_-valueIn_);
01423 else
01424 maximumMovement = min(1.0e30,valueIn_-lowerIn_);
01425
01426 int iIndex;
01427
01428
01429
01430 const CoinPackedMatrix * quadratic = info->quadraticObjective();
01431 const int * columnQuadratic = quadratic->getIndices();
01432 const int * columnQuadraticStart = quadratic->getVectorStarts();
01433 const int * columnQuadraticLength = quadratic->getVectorLengths();
01434 const double * quadraticElement = quadratic->getElements();
01435
01436
01437 rhsArray->clear();
01438 int * index2 = rhsArray->getIndices();
01439 int numberXColumns = info->numberXColumns();
01440 int number2=0;
01441
01442
01443 int iSjRow=-1;
01444
01445 int iSjRow2=-1,crucialSj2=-1;
01446 if (sequenceIn_<numberXColumns) {
01447 crucialSj2 = sequenceIn_;
01448 crucialSj2 += numberRows_;
01449 } else if (sequenceIn_>=numberColumns_) {
01450 int iRow=sequenceIn_-numberColumns_;
01451 crucialSj2 = iRow;
01452 crucialSj2 += numberXColumns;
01453 }
01454 double tj = 0.0;
01455
01456 double coeff1 = 0.0;
01457 double coeff2 = 0.0;
01458 double coeffSlack=0.0;
01459 for (iIndex=0;iIndex<number;iIndex++) {
01460 int iRow = which[iIndex];
01461 double alpha = -work[iRow]*way;
01462 int iPivot=pivotVariable_[iRow];
01463 if (numberIterations_==17)
01464 printf("row %d col %d alpha %g solution %g\n",iRow,iPivot,alpha,solution_[iPivot]);
01465 if (iPivot<numberXColumns) {
01466 index2[number2++]=iPivot;
01467 rhs[iPivot]=alpha;
01468 coeff1 += alpha*cost_[iPivot];
01469
01470
01471 } else {
01472 if (iPivot>=numberColumns_) {
01473
01474 assert (iPivot!=crucialSj);
01475 coeffSlack += alpha*cost_[iPivot];
01476 } else if (iPivot<numberRows_) {
01477
01478 if (iPivot==crucialSj) {
01479 tj = alpha;
01480 iSjRow = iRow;
01481 }
01482 } else {
01483 if (iPivot==crucialSj) {
01484 tj = alpha;
01485 iSjRow = iRow;
01486 }
01487 }
01488 }
01489 if (iPivot==crucialSj2)
01490 iSjRow2=iRow;
01491 }
01492
01493 if (sequenceIn_<numberXColumns) {
01494 index2[number2++]=sequenceIn_;
01495 rhs[sequenceIn_]=way;
01496
01497
01498 coeff1 += way*cost_[sequenceIn_];
01499 } else {
01500
01501 coeffSlack += way*cost_[sequenceIn_];
01502 }
01503 printf("coeff1 now %g\n",coeff1);
01504 rhsArray->setNumElements(number2);
01505 double largestCoeff1=1.0e-20;
01506 for (iIndex=0;iIndex<number2;iIndex++) {
01507 int iColumn=index2[iIndex];
01508
01509 double alphaI = rhs[iColumn];
01510 int j;
01511 for (j=columnQuadraticStart[iColumn];
01512 j<columnQuadraticStart[iColumn]+columnQuadraticLength[iColumn];j++) {
01513 int jColumn = columnQuadratic[j];
01514 double valueJ = solution_[jColumn];
01515 double alphaJ = rhs[jColumn];
01516 double elementValue = quadraticElement[j];
01517 double addValue = (valueJ*alphaI)*elementValue;
01518 largestCoeff1 = max(largestCoeff1,fabs(addValue));
01519 coeff1 += addValue;
01520 coeff2 += (alphaI*alphaJ)*elementValue;
01521 }
01522 }
01523 coeff2 *= 0.5;
01524 if (coeffSlack)
01525 printf("slack has non-zero cost - trouble?\n");
01526 coeff1 += coeffSlack;
01527
01528 int accuracyFlag=0;
01529 if (!cleanupIteration) {
01530 if (fabs(dualIn_)<dualTolerance_&&fabs(coeff1)<dualTolerance_) {
01531 dualIn_=0.0;
01532 coeff1=0.0;
01533 }
01534 if (fabs(way*coeff1-dualIn_)>1.0e-2*(1.0+fabs(dualIn_)))
01535 printf("primal error %g, largest %g, coeff1 %g, dualin %g\n",
01536 largestPrimalError_,largestCoeff1,way*coeff1,dualIn_);
01537 assert (fabs(way*coeff1-dualIn_)<1.0e-1*(1.0+fabs(dualIn_)));
01538 assert (way*coeff1*dualIn_>=0.0);
01539 if (way*coeff1*dualIn_<0.0) {
01540
01541 accuracyFlag=2;
01542 } else if (fabs(way*coeff1-dualIn_)>1.0e-3*(1.0+fabs(dualIn_))) {
01543
01544 accuracyFlag=1;
01545 }
01546 if (crucialSj>=0) {
01547 solution_[crucialSj]=way*coeff1;
01548 }
01549 } else if (dualIn_<0.0&&way*coeff1>1.0e-2) {
01550 printf("bad pair\n");
01551 accuracyFlag=1;
01552 } else if (dualIn_>0.0&&way*coeff1<-1.0e-2) {
01553 accuracyFlag=1;
01554 printf("bad pair\n");
01555 }
01556
01557 double d1,d2=1.0e50;
01558 if (fabs(coeff2)>1.0e-9)
01559 d1 = - 0.5*coeff1/coeff2;
01560 else if (coeff1<=1.0e-6)
01561 d1 = maximumMovement;
01562 else
01563 d1 = 0.0;
01564 if (fabs(tj)<1.0e-7||!cleanupIteration) {
01565
01566
01567
01568 } else {
01569 d2 = -solution_[crucialSj]/tj;
01570 if (d2<0.0) {
01571 printf("d2 would be negative at %g\n",d2);
01572 d2=1.0e50;
01573 }
01574 }
01575 if (d1>1.0e10&&d2>1.0e10) {
01576
01577
01578
01579 }
01580 handler_->message(CLP_QUADRATIC_PRIMAL_DETAILS,messages_)
01581 <<coeff1<<coeff2<<coeffSlack<<dualIn_<<d1<<d2
01582 <<CoinMessageEol;
01583
01584 {
01585 if (crucialSj2>=0) {
01586
01587 if (getColumnStatus(crucialSj2)==basic) {
01588 if (iSjRow2>=0) {
01589
01590 double alpha=work[iSjRow2];
01591 printf("Sj alpha %g sol %g ratio %g\n",alpha,solution_[crucialSj2],solution_[crucialSj2]/alpha);
01592 if (fabs(fabs(d1)-fabs(solution_[crucialSj2]/alpha))>1.0e-3*(1.0+fabs(d1))) {
01593 printf("bad test\n");
01594 if (factorization_->pivots())
01595 accuracyFlag=2;
01596 }
01597 d1=fabs(solution_[crucialSj2]/alpha);
01598 } else {
01599 printf("Sj basic but no alpha\n");
01600 }
01601 } else {
01602 printf("Sj not basic\n");
01603 }
01604 }
01605 }
01606
01607
01608 double mind1d2=1.0e50;
01609 if (cleanupIteration) {
01610
01611 mind1d2 = min(maximumMovement,d2);
01612
01613
01614 } else {
01615
01616 if (d1>1.0e-5) {
01617 mind1d2 = min(maximumMovement,d1);
01618
01619 }
01620 }
01621 maximumMovement = min(maximumMovement,mind1d2);
01622 double trueMaximumMovement;
01623 if (way>0.0)
01624 trueMaximumMovement = min(1.0e30,upperIn_-valueIn_);
01625 else
01626 trueMaximumMovement = min(1.0e30,valueIn_-lowerIn_);
01627 rhsArray->clear();
01628 double tentativeTheta = maximumMovement;
01629 double upperTheta = maximumMovement;
01630 bool throwAway=false;
01631 if (numberIterations_==1750) {
01632 printf("Bad iteration coming up after iteration %d\n",numberIterations_);
01633 }
01634
01635 double minimumAny=1.0e50;
01636 int whichMinimum=-1;
01637 double minimumAlpha=0.0;
01638 for (iIndex=0;iIndex<number;iIndex++) {
01639
01640 int iRow = which[iIndex];
01641 double alpha = work[iRow];
01642 int iPivot=pivotVariable_[iRow];
01643 alpha *= way;
01644 double oldValue = solution(iPivot);
01645
01646 if (alpha>0.0) {
01647
01648 double bound = lower(iPivot);
01649 oldValue -= bound;
01650 } else if (alpha<0.0) {
01651
01652 double bound = upper(iPivot);
01653 oldValue = bound-oldValue;
01654 }
01655 if (iPivot>=numberXColumns&&iPivot<numberColumns_) {
01656 double bound=0.0;
01657 double oldValue2 = solution(iPivot);
01658 if (alpha>0.0) {
01659
01660 oldValue2 -= bound;
01661 } else if (alpha<0.0) {
01662
01663 oldValue2 = bound-oldValue;
01664 }
01665 double value = oldValue2-minimumAny*fabs(alpha);
01666 if (value*oldValue2<0.0) {
01667 double ratio = fabs(oldValue2/alpha);
01668 if (ratio<minimumAny&&fabs(alpha)>1.0e2*acceptablePivot) {
01669 minimumAny = ratio;
01670 whichMinimum = iRow;
01671 minimumAlpha= fabs(alpha);
01672 }
01673 }
01674 }
01675 double value = oldValue-tentativeTheta*fabs(alpha);
01676 assert (oldValue>=-primalTolerance_*1.0001);
01677 if (value<-primalTolerance_) {
01678
01679 spare[numberRemaining]=alpha;
01680 rhs[iRow]=oldValue;
01681 index[numberRemaining++]=iRow;
01682 double value=oldValue-upperTheta*fabs(alpha);
01683 if (value<-primalTolerance_&&fabs(alpha)>=acceptablePivot)
01684 upperTheta = (oldValue+primalTolerance_)/fabs(alpha);
01685 }
01686 }
01687
01688
01689 int numberInRhs=numberRemaining;
01690 memcpy(rhsArray->getIndices(),index,numberInRhs*sizeof(int));
01691 rhsArray->setNumElements(numberInRhs);
01692
01693 theta_=maximumMovement;
01694
01695 bool goBackOne = false;
01696 double fake=1.0e-2;
01697
01698 if (numberRemaining) {
01699
01700
01701
01702 tentativeTheta = max(10.0*upperTheta,1.0e-7);
01703 tentativeTheta = min(tentativeTheta,maximumMovement);
01704
01705
01706
01707 while (tentativeTheta <= maximumMovement) {
01708 double bestPivotBeforeInteresting=0.0;
01709 double thruThis = 0.0;
01710
01711 double bestPivot=acceptablePivot;
01712 pivotRow_ = -1;
01713
01714 numberSwapped = 0;
01715
01716 upperTheta = maximumMovement;
01717
01718 for (iIndex=0;iIndex<numberRemaining;iIndex++) {
01719
01720 int iRow = index[iIndex];
01721 double alpha = spare[iIndex];
01722 double oldValue = rhs[iRow];
01723 double value = oldValue-tentativeTheta*fabs(alpha);
01724
01725 if (value<-primalTolerance_) {
01726
01727 thruThis += alpha*
01728 nonLinearCost_->changeInCost(pivotVariable_[iRow],alpha);
01729
01730 indexSwapped[numberSwapped++]=iRow;
01731 if (fabs(alpha)>bestPivot) {
01732 bestPivot=fabs(alpha);
01733 pivotRow_ = iRow;
01734 theta_ = oldValue/bestPivot;
01735 }
01736 } else {
01737 value = oldValue-upperTheta*fabs(alpha);
01738 if (value<-primalTolerance_ && fabs(alpha)>=acceptablePivot)
01739 upperTheta = (oldValue+primalTolerance_)/fabs(alpha);
01740 }
01741 }
01742
01743 maximumSwapped = max(maximumSwapped,numberSwapped);
01744 bestPivotBeforeInteresting=bestPivot;
01745
01746
01747 double dualCheck = - 2.0*coeff2*tentativeTheta - coeff1;
01748
01749
01750
01751
01752 if ((totalThru+thruThis>=dualCheck&&bestPivot>acceptablePivot)||fake*bestPivot>1.0e-3) {
01753
01754
01755
01756 int saveNumber = numberRemaining;
01757 numberRemaining=0;
01758 for (iIndex=0;iIndex<numberSwapped;iIndex++) {
01759 int iRow = indexSwapped[iIndex];
01760 spare[numberRemaining]=way*work[iRow];
01761 index[numberRemaining++]=iRow;
01762 }
01763 memset(spare+numberRemaining,0,
01764 (saveNumber-numberRemaining)*sizeof(double));
01765 double lastThru = totalThru;
01766 int iTry;
01767 #define MAXTRY 100
01768
01769 for (iTry=0;iTry<MAXTRY;iTry++) {
01770
01771 upperTheta=maximumMovement;
01772 numberSwapped = 0;
01773
01774 for (iIndex=0;iIndex<numberRemaining;iIndex++) {
01775
01776 int iRow = index[iIndex];
01777 double alpha = fabs(spare[iIndex]);
01778 double oldValue = rhs[iRow];
01779 double value = oldValue-upperTheta*alpha;
01780
01781 if (value<-primalTolerance_ && alpha>=acceptablePivot)
01782 upperTheta = (oldValue+primalTolerance_)/alpha;
01783
01784 }
01785
01786
01787 bestPivot=acceptablePivot;
01788 pivotRow_=-1;
01789 for (iIndex=0;iIndex<numberRemaining;iIndex++) {
01790
01791 int iRow = index[iIndex];
01792 double alpha = spare[iIndex];
01793 double oldValue = rhs[iRow];
01794 double value = oldValue-upperTheta*fabs(alpha);
01795
01796 if (value<=0) {
01797
01798 totalThru += alpha*
01799 nonLinearCost_->changeInCost(pivotVariable_[iRow],alpha);
01800
01801 indexSwapped[numberSwapped++]=iRow;
01802 if (fabs(alpha)>bestPivot) {
01803 bestPivot=fabs(alpha);
01804 theta_ = oldValue/bestPivot;
01805 pivotRow_=iRow;
01806 }
01807 } else {
01808 value = oldValue-upperTheta*fabs(alpha);
01809 if (value<-primalTolerance_ && fabs(alpha)>=acceptablePivot)
01810 upperTheta = (oldValue+primalTolerance_)/fabs(alpha);
01811 }
01812 }
01813
01814 maximumSwapped = max(maximumSwapped,numberSwapped);
01815 if (bestPivot<0.1*bestEverPivot&&
01816 bestEverPivot>1.0e-6&&bestPivot<1.0e-3) {
01817
01818 goBackOne = true;
01819 break;
01820 } else if (pivotRow_==-1&&upperTheta>largeValue_) {
01821 if (lastPivot>acceptablePivot) {
01822
01823 goBackOne = true;
01824
01825 } else {
01826
01827 }
01828 break;
01829 } else {
01830 dualCheck = - 2.0*coeff2*theta_ - coeff1;
01831 if (bestPivotBeforeInteresting>1.0e-4&&bestPivot<1.0e-6)
01832 dualCheck=1.0e7;
01833 if ((totalThru>=dualCheck||fake*bestPivot>1.0e-3)
01834 &&(sequenceIn_<numberXColumns||sequenceIn_>=numberColumns_)) {
01835 if (!cleanupIteration) {
01836
01837 if (upperTheta==maximumMovement) {
01838 printf("figures\n");
01839 } else if (iSjRow2>=0) {
01840 if (lastThru>=dualCheck&&theta_<trueMaximumMovement) {
01841 printf("totalThru %g, lastThru %g - taking sj to zero?\n",totalThru,lastThru);
01842
01843 mind1d2=1.0;
01844 maximumMovement=1.0;
01845 d2=0.0;
01846 pivotRow_=-1;
01847 }
01848 }
01849 } else {
01850 if (pivotRow_<0&&lastPivotRow<0)
01851 throwAway=true;
01852 }
01853 break;
01854 } else if (totalThru>=dualCheck||fake*bestPivot>1.0e-3||upperTheta==maximumMovement) {
01855 break;
01856 } else {
01857
01858 nonLinearCost_->goThru(numberSwapped,way,indexSwapped, work,rhs);
01859 lastPivotRow=pivotRow_;
01860 lastTheta = theta_;
01861 lastThru = numberThru;
01862 numberThru += numberSwapped;
01863 lastNumberSwapped = numberSwapped;
01864 memcpy(saveSwapped,indexSwapped,lastNumberSwapped*sizeof(int));
01865 if (bestPivot>bestEverPivot)
01866 bestEverPivot=bestPivot;
01867 lastThru = totalThru;
01868 }
01869 }
01870 }
01871 break;
01872 } else {
01873
01874 nonLinearCost_->goThru(numberSwapped,way,indexSwapped, work,rhs);
01875 lastPivotRow=pivotRow_;
01876 lastTheta = theta_;
01877 lastThru = numberThru;
01878 numberThru += numberSwapped;
01879 lastNumberSwapped = numberSwapped;
01880 memcpy(saveSwapped,indexSwapped,lastNumberSwapped*sizeof(int));
01881 if (bestPivot>bestEverPivot)
01882 bestEverPivot=bestPivot;
01883 totalThru += thruThis;
01884 tentativeTheta = 2.0*upperTheta;
01885 }
01886 }
01887
01888 if (goBackOne||(pivotRow_<0&&lastPivotRow>=0)) {
01889
01890 pivotRow_=lastPivotRow;
01891 theta_ = lastTheta;
01892
01893 nonLinearCost_->goBack(lastNumberSwapped,saveSwapped,rhs);
01894 memcpy(indexSwapped,saveSwapped,lastNumberSwapped*sizeof(int));
01895 numberSwapped = lastNumberSwapped;
01896 }
01897 }
01898 if (0&&minimumAny<theta_&&cleanupIteration&&bestEverPivot<1.0e-2
01899 &&minimumAlpha>bestEverPivot*1.0e2&&minimumAny>1.0e-1&&info->currentPhase()==0) {
01900 printf("Possible other pivot %d %g %g - alpha %g\n",
01901 whichMinimum,minimumAny,theta_,minimumAlpha);
01902 pivotRow_ = whichMinimum;
01903 alpha_ = work[pivotRow_];
01904
01905 sequenceOut_ = pivotVariable_[pivotRow_];
01906 valueOut_ = solution(sequenceOut_);
01907 lowerOut_=0.0;
01908 upperOut_=0.0;
01909 theta_= fabs(valueOut_/alpha_);
01910
01911 if (way<0.0)
01912 theta_ = - theta_;
01913 if (alpha_*way<0.0) {
01914 directionOut_=-1;
01915 } else {
01916 directionOut_=1;
01917 }
01918 dualOut_ = reducedCost(sequenceOut_);
01919 } else {
01920
01921 if (pivotRow_>=0) {
01922 if (0) {
01923 double move = coeff1*theta_+coeff2*theta_*theta_;
01924 printf("Predicted change in obj is %g %g %g\n",
01925 move,objectiveValue_-move,objectiveValue_+move);
01926 }
01927 #define MINIMUMTHETA 1.0e-12
01928
01929 #ifdef CLP_DEBUG
01930 bool found=false;
01931 #endif
01932 double largestInfeasibility = primalTolerance_;
01933 if (theta_<MINIMUMTHETA) {
01934 theta_=MINIMUMTHETA;
01935 for (iIndex=0;iIndex<numberSwapped;iIndex++) {
01936 int iRow = indexSwapped[iIndex];
01937 #ifdef CLP_DEBUG
01938 if (iRow==pivotRow_)
01939 found=true;
01940 #endif
01941 largestInfeasibility = max (largestInfeasibility,
01942 -(rhs[iRow]-fabs(work[iRow])*theta_));
01943 }
01944 #ifdef CLP_DEBUG
01945 assert(found);
01946 if (largestInfeasibility>primalTolerance_&&(handler_->logLevel()&32))
01947 printf("Primal tolerance increased from %g to %g\n",
01948 primalTolerance_,largestInfeasibility);
01949 #endif
01950 primalTolerance_ = max(primalTolerance_,largestInfeasibility);
01951 }
01952 alpha_ = work[pivotRow_];
01953
01954 sequenceOut_ = pivotVariable_[pivotRow_];
01955 valueOut_ = solution(sequenceOut_);
01956 lowerOut_=lower_[sequenceOut_];
01957 upperOut_=upper_[sequenceOut_];
01958
01959 if (way<0.0)
01960 theta_ = - theta_;
01961 double newValue = valueOut_ - theta_*alpha_;
01962 if (alpha_*way<0.0) {
01963 directionOut_=-1;
01964 if (fabs(theta_)>1.0e-6)
01965 upperOut_ = nonLinearCost_->nearest(sequenceOut_,newValue);
01966 else
01967 upperOut_ = newValue;
01968 } else {
01969 directionOut_=1;
01970 if (fabs(theta_)>1.0e-6)
01971 lowerOut_ = nonLinearCost_->nearest(sequenceOut_,newValue);
01972 else
01973 lowerOut_ = newValue;
01974 }
01975 dualOut_ = reducedCost(sequenceOut_);
01976 } else {
01977
01978 if (throwAway&&(sequenceIn_<numberXColumns||sequenceIn_>=numberColumns_)) {
01979 assert (pivotRow_<0);
01980 accuracyFlag=2;
01981 }
01982 if (maximumMovement<1.0e20&&maximumMovement==trueMaximumMovement) {
01983
01984 theta_ = maximumMovement;
01985 pivotRow_ = -2;
01986 result=0;
01987 sequenceOut_ = sequenceIn_;
01988 valueOut_ = valueIn_;
01989 dualOut_ = dualIn_;
01990 lowerOut_ = lowerIn_;
01991 upperOut_ = upperIn_;
01992 alpha_ = 0.0;
01993 if (accuracyFlag<2)
01994 accuracyFlag=0;
01995 if (way<0.0) {
01996 directionOut_=1;
01997 theta_ = lowerOut_ - valueOut_;
01998 } else {
01999 directionOut_=-1;
02000 theta_ = upperOut_ - valueOut_;
02001 }
02002
02003 } else if (fabs(maximumMovement-mind1d2)<dualTolerance_) {
02004
02005 if (maximumMovement==d2) {
02006
02007 result=0;
02008 } else {
02009
02010 if (!cleanupIteration) {
02011 result=0;
02012 iSjRow=iSjRow2;
02013 if (iSjRow>=0)
02014 crucialSj = pivotVariable_[iSjRow];
02015 else
02016 crucialSj=-1;
02017 assert (pivotRow_<0);
02018
02019 if (crucialSj<0) {
02020 printf("**ouch\n");
02021 theta_ = maximumMovement;
02022 pivotRow_ = -2;
02023 result=0;
02024 sequenceOut_ = sequenceIn_;
02025 valueOut_ = valueIn_;
02026 dualOut_ = dualIn_;
02027 lowerOut_ = lowerIn_;
02028 upperOut_ = upperIn_;
02029 alpha_ = 0.0;
02030 if (accuracyFlag<2)
02031 accuracyFlag=0;
02032 if (way<0.0) {
02033 directionOut_=1;
02034 lowerIn_ = valueOut_-theta_;
02035 theta_ = lowerIn_ - valueOut_;
02036 } else {
02037 directionOut_=-1;
02038 upperIn_ = valueOut_+theta_;
02039 theta_ = upperIn_ - valueOut_;
02040 }
02041 }
02042 } else {
02043 assert (fabs(dualIn_)<1.0e-3);
02044 result=1;
02045 if (minimumAlpha>0.0) {
02046
02047 printf("Should take minimum\n");
02048 pivotRow_ = whichMinimum;
02049 alpha_ = work[pivotRow_];
02050
02051 sequenceOut_ = pivotVariable_[pivotRow_];
02052 valueOut_ = solution(sequenceOut_);
02053 theta_ = minimumAny;
02054 if (way<0.0)
02055 theta_ = - theta_;
02056 lowerOut_=0.0;
02057 upperOut_=0.0;
02058
02059 dualOut_ = reducedCost(sequenceOut_);
02060 }
02061 }
02062 }
02063 if (!result&&crucialSj>=0) {
02064 setColumnStatus(crucialSj,isFree);
02065 pivotRow_ = iSjRow;
02066 alpha_ = work[pivotRow_];
02067
02068 sequenceOut_ = pivotVariable_[pivotRow_];
02069 assert (sequenceOut_==crucialSj);
02070 valueOut_ = solution(sequenceOut_);
02071 theta_ = fabs(valueOut_/alpha_);
02072 if (fabs(maximumMovement-theta_)>1.0e-3*(1.0+maximumMovement))
02073 printf("maximumMovement %g mismatch with theta %g\n",maximumMovement,theta_);;
02074 if (way<0.0)
02075 theta_ = - theta_;
02076 lowerOut_=0.0;
02077 upperOut_=0.0;
02078
02079 dualOut_ = reducedCost(sequenceOut_);
02080 }
02081 } else {
02082
02083 accuracyFlag=2;
02084 }
02085 }
02086 }
02087
02088
02089
02090
02091 memset(spare,0,numberRemaining*sizeof(double));
02092 memset(saveSwapped,0,maximumSwapped*sizeof(int));
02093
02094
02095 nonLinearCost_->goBackAll(rhsArray);
02096
02097 rhsArray->clear();
02098
02099 objectiveValue_ += theta_*coeff1+theta_*theta_*coeff2;
02100 {
02101 int iColumn;
02102 objectiveValue_ =0.0;
02103 CoinPackedMatrix * quadratic =
02104 info->originalObjective()->quadraticObjective();
02105 const int * columnQuadratic = quadratic->getIndices();
02106 const int * columnQuadraticStart = quadratic->getVectorStarts();
02107 const int * columnQuadraticLength = quadratic->getVectorLengths();
02108 const double * quadraticElement = quadratic->getElements();
02109 int numberColumns = info->numberXColumns();
02110 const double * objective = info->linearObjective();
02111 for (iColumn=0;iColumn<numberColumns;iColumn++)
02112 objectiveValue_ += objective[iColumn]*solution_[iColumn];
02113 for (iColumn=0;iColumn<numberColumns;iColumn++) {
02114 double valueI = solution_[iColumn];
02115 int j;
02116 for (j=columnQuadraticStart[iColumn];
02117 j<columnQuadraticStart[iColumn]+columnQuadraticLength[iColumn];j++) {
02118 int jColumn = columnQuadratic[j];
02119 double valueJ = solution_[jColumn];
02120 double elementValue = quadraticElement[j];
02121 objectiveValue_ += 0.5*valueI*valueJ*elementValue;
02122 }
02123 }
02124 }
02125 if (accuracyFlag<2) {
02126 return result+10*accuracyFlag;
02127 } else {
02128 pivotRow_=1;
02129 return 20;
02130 }
02131 }
02132
02133 void
02134 ClpSimplexPrimalQuadratic::statusOfProblemInPrimal(int & lastCleaned,int type,
02135 ClpSimplexProgress * progress,
02136 ClpQuadraticInfo * info)
02137 {
02138 if (info->currentPhase())
02139 info->setCurrentSolution(solution_);
02140
02141
02142 if (type==2) {
02143
02144 memcpy(status_ ,saveStatus_,(numberColumns_+numberRows_)*sizeof(char));
02145 memcpy(rowActivityWork_,savedSolution_+numberColumns_ ,
02146 numberRows_*sizeof(double));
02147 memcpy(columnActivityWork_,savedSolution_ ,
02148 numberColumns_*sizeof(double));
02149 forceFactorization_=1;
02150 pivotRow_=-1;
02151 changeMade_++;
02152 info->restoreStatus();
02153 }
02154 int saveThreshold = factorization_->sparseThreshold();
02155 int tentativeStatus = problemStatus_;
02156 if (problemStatus_>-3||problemStatus_==-4) {
02157
02158
02159
02160
02161
02162 primalColumnPivot_->saveWeights(this,1);
02163
02164 if (type) {
02165
02166 int numberPivots = factorization_->pivots();
02167 if (internalFactorize(1)) {
02168 if (solveType_==2) {
02169
02170 problemStatus_=5;
02171 return;
02172 }
02173 numberIterations_ = progress_->lastIterationNumber(0);
02174
02175 assert (info->crucialSj()<0);
02176 assert (type==1);
02177 memcpy(status_ ,saveStatus_,(numberColumns_+numberRows_)*sizeof(char));
02178 memcpy(rowActivityWork_,savedSolution_+numberColumns_ ,
02179 numberRows_*sizeof(double));
02180 memcpy(columnActivityWork_,savedSolution_ ,
02181 numberColumns_*sizeof(double));
02182 forceFactorization_=1;
02183 type = 2;
02184 assert (internalFactorize(1)==0);
02185 info->restoreStatus();
02186
02187 if (numberPivots==1) {
02188 int crucialSj = info->crucialSj();
02189 if (crucialSj<0) {
02190 setFlagged(sequenceIn_);
02191 } else {
02192 int iSequence;
02193 int numberXColumns = info->numberXColumns();
02194 if (crucialSj<numberRows_) {
02195
02196 iSequence = crucialSj-numberXColumns+numberColumns_;
02197 } else {
02198
02199 iSequence = crucialSj-numberRows_;
02200 }
02201 if (getColumnStatus(iSequence)!=basic) {
02202 setFlagged(iSequence);
02203 info->setSequenceIn(-1);
02204 } else {
02205 printf("**** %d is basic ?\n",iSequence);
02206 }
02207 }
02208 }
02209 changeMade_++;
02210 }
02211 }
02212 if (problemStatus_!=-4)
02213 problemStatus_=-3;
02214 }
02215 if (info->crucialSj()<0) {
02216
02217
02218
02219 createRim(4);
02220 if (info->currentPhase()) {
02221 memcpy(solution_,info->currentSolution(),
02222 (numberRows_+numberColumns_)*sizeof(double));
02223 }
02224 gutsOfSolution(NULL,NULL);
02225 if (info->currentPhase()) {
02226 memcpy(solution_,info->currentSolution(),
02227 (numberRows_+numberColumns_)*sizeof(double));
02228 nonLinearCost_->checkInfeasibilities(primalTolerance_);
02229 }
02230 checkComplementarity(info,rowArray_[2],rowArray_[3]);
02231
02232 if (progress->lastIterationNumber(0)==numberIterations_) {
02233 if (primalColumnPivot_->looksOptimal()) {
02234 numberDualInfeasibilities_ = 0;
02235 sumDualInfeasibilities_ = 0.0;
02236 }
02237 }
02238
02239 int loop;
02240 if (type!=2)
02241 loop = progress->looping();
02242 else
02243 loop=-1;
02244
02245 if (loop>=0) {
02246 problemStatus_ = loop;
02247 return ;
02248 } else if (loop<-1) {
02249
02250 gutsOfSolution(NULL,NULL);
02251 checkComplementarity(info,rowArray_[2],rowArray_[3]);
02252 }
02253
02254
02255
02256 progressFlag_ = 0;
02257
02258 handler_->message(CLP_SIMPLEX_STATUS,messages_)
02259 <<numberIterations_<<objectiveValue();
02260 handler_->printing(sumPrimalInfeasibilities_>0.0)
02261 <<sumPrimalInfeasibilities_<<numberPrimalInfeasibilities_;
02262 handler_->printing(sumDualInfeasibilities_>0.0)
02263 <<sumDualInfeasibilities_<<numberDualInfeasibilities_;
02264 handler_->printing(numberDualInfeasibilitiesWithoutFree_
02265 <numberDualInfeasibilities_)
02266 <<numberDualInfeasibilitiesWithoutFree_;
02267 handler_->message()<<CoinMessageEol;
02268 assert (primalFeasible());
02269
02270 bool alwaysOptimal = (specialOptions_&1)!=0;
02271
02272 if (sumOfRelaxedDualInfeasibilities_ == 0.0&&
02273 sumOfRelaxedPrimalInfeasibilities_ == 0.0&&info->sequenceIn()<0) {
02274
02275 numberDualInfeasibilities_ = 0;
02276 sumDualInfeasibilities_ = 0.0;
02277 numberPrimalInfeasibilities_ = 0;
02278 sumPrimalInfeasibilities_ = 0.0;
02279 }
02280
02281 if (dualFeasible()||problemStatus_==-4) {
02282 if (nonLinearCost_->numberInfeasibilities()&&!alwaysOptimal) {
02283
02284
02285
02286 double saveWeight = infeasibilityCost_;
02287
02288 ClpNonLinearCost * nonLinear = nonLinearCost_;
02289
02290
02291
02292 createRim(4);
02293
02294 int iSequence;
02295 for (iSequence=0;iSequence<numberRows_+numberColumns_;iSequence++) {
02296 Status status = getStatus(iSequence);
02297 if (status==atLowerBound||status==isFixed)
02298 solution_[iSequence]=lower_[iSequence];
02299 else if (status==atUpperBound)
02300 solution_[iSequence]=upper_[iSequence];
02301 }
02302 nonLinearCost_->checkInfeasibilities(primalTolerance_);
02303 gutsOfSolution(NULL,NULL);
02304 nonLinearCost_->checkInfeasibilities(primalTolerance_);
02305 checkComplementarity(info,rowArray_[2],rowArray_[3]);
02306
02307 infeasibilityCost_=1.0e100;
02308
02309 createRim(4);
02310 nonLinearCost_->checkInfeasibilities(primalTolerance_);
02311
02312 if (nonLinearCost_->numberInfeasibilities()==0) {
02313
02314 problemStatus_ = -1;
02315 infeasibilityCost_=saveWeight;
02316 nonLinearCost_->checkInfeasibilities(primalTolerance_);
02317 checkComplementarity(info,rowArray_[2],rowArray_[3]);
02318 } else {
02319 nonLinearCost_=NULL;
02320
02321 int i;
02322 for (i=0;i<numberRows_+numberColumns_;i++)
02323 cost_[i] *= 1.0e-100;
02324 gutsOfSolution(NULL,NULL);
02325 nonLinearCost_=nonLinear;
02326 infeasibilityCost_=saveWeight;
02327 if ((infeasibilityCost_>=1.0e18||
02328 numberDualInfeasibilities_==0)&&perturbation_==101) {
02329 unPerturb();
02330 numberDualInfeasibilities_=1;
02331 }
02332 if (infeasibilityCost_>=1.0e20||
02333 numberDualInfeasibilities_==0) {
02334
02335 delete [] ray_;
02336 ray_ = new double [numberRows_];
02337 memcpy(ray_,dual_,numberRows_*sizeof(double));
02338
02339 infeasibilityCost_=0.0;
02340 createRim(4);
02341
02342 int iSequence;
02343 for (iSequence=0;iSequence<numberRows_+numberColumns_;iSequence++) {
02344 Status status = getStatus(iSequence);
02345 if (status==atLowerBound||status==isFixed)
02346 solution_[iSequence]=lower_[iSequence];
02347 else if (status==atUpperBound)
02348 solution_[iSequence]=upper_[iSequence];
02349 }
02350 nonLinearCost_->checkInfeasibilities(primalTolerance_);
02351 gutsOfSolution(NULL,NULL);
02352 checkComplementarity(info,rowArray_[2],rowArray_[3]);
02353
02354 infeasibilityCost_=1.0e30;
02355
02356 sumPrimalInfeasibilities_=nonLinearCost_->sumInfeasibilities();;
02357 numberPrimalInfeasibilities_=
02358 nonLinearCost_->numberInfeasibilities();
02359 }
02360 if (infeasibilityCost_<1.0e20) {
02361 infeasibilityCost_ *= 5.0;
02362 changeMade_++;
02363 handler_->message(CLP_PRIMAL_WEIGHT,messages_)
02364 <<infeasibilityCost_
02365 <<CoinMessageEol;
02366
02367 createRim(4);
02368 nonLinearCost_->checkInfeasibilities(0.0);
02369 gutsOfSolution(NULL,NULL);
02370 checkComplementarity(info,rowArray_[2],rowArray_[3]);
02371 problemStatus_=-1;
02372 } else {
02373
02374 problemStatus_ = 1;
02375 }
02376 }
02377 } else {
02378
02379 if (perturbation_==101) {
02380 unPerturb();
02381 lastCleaned=-1;
02382 }
02383 if ( lastCleaned!=numberIterations_||unflag()) {
02384 handler_->message(CLP_PRIMAL_OPTIMAL,messages_)
02385 <<primalTolerance_
02386 <<CoinMessageEol;
02387 if (numberTimesOptimal_<4) {
02388 numberTimesOptimal_++;
02389 changeMade_++;
02390 if (numberTimesOptimal_==1) {
02391
02392 factorization_->zeroTolerance(1.0e-15);
02393 }
02394 lastCleaned=numberIterations_;
02395 if (primalTolerance_!=dblParam_[ClpPrimalTolerance])
02396 handler_->message(CLP_PRIMAL_ORIGINAL,messages_)
02397 <<CoinMessageEol;
02398 double oldTolerance = primalTolerance_;
02399 primalTolerance_=dblParam_[ClpPrimalTolerance];
02400
02401 createRim(4);
02402
02403 int iSequence;
02404 for (iSequence=0;iSequence<numberRows_+numberColumns_;iSequence++) {
02405 Status status = getStatus(iSequence);
02406 if (status==atLowerBound||status==isFixed)
02407 solution_[iSequence]=lower_[iSequence];
02408 else if (status==atUpperBound)
02409 solution_[iSequence]=upper_[iSequence];
02410 }
02411 nonLinearCost_->checkInfeasibilities(oldTolerance);
02412 gutsOfSolution(NULL,NULL);
02413 checkComplementarity(info,rowArray_[2],rowArray_[3]);
02414 problemStatus_ = -1;
02415 } else {
02416 problemStatus_=0;
02417 if (lastCleaned<numberIterations_) {
02418 handler_->message(CLP_SIMPLEX_GIVINGUP,messages_)
02419 <<CoinMessageEol;
02420 }
02421 }
02422 } else {
02423 problemStatus_=0;
02424 }
02425 }
02426 } else {
02427
02428 if (problemStatus_==-5) {
02429 if (nonLinearCost_->numberInfeasibilities()) {
02430 if (infeasibilityCost_>1.0e18&&perturbation_==101) {
02431
02432 infeasibilityCost_ = 1.0e13;
02433 unPerturb();
02434 }
02435
02436 if (infeasibilityCost_<1.0e20) {
02437 infeasibilityCost_ *= 5.0;
02438 changeMade_++;
02439 handler_->message(CLP_PRIMAL_WEIGHT,messages_)
02440 <<infeasibilityCost_
02441 <<CoinMessageEol;
02442
02443 createRim(4);
02444 gutsOfSolution(NULL,NULL);
02445 checkComplementarity(info,rowArray_[2],rowArray_[3]);
02446 problemStatus_=-1;
02447 } else {
02448
02449 problemStatus_ = 2;
02450 }
02451 } else {
02452
02453 problemStatus_ = 2;
02454 }
02455 } else {
02456 if(type==3&&problemStatus_!=-5)
02457 unflag();
02458
02459 problemStatus_ = -1;
02460 }
02461 }
02462 } else {
02463
02464 problemStatus_=-1;
02465 }
02466 if (type==0||type==1) {
02467 if (type!=1||!saveStatus_) {
02468
02469 delete [] saveStatus_;
02470 delete [] savedSolution_;
02471 saveStatus_ = new unsigned char [numberRows_+numberColumns_];
02472 savedSolution_ = new double [numberRows_+numberColumns_];
02473 }
02474
02475 memcpy(saveStatus_,status_,(numberColumns_+numberRows_)*sizeof(char));
02476 memcpy(savedSolution_+numberColumns_ ,rowActivityWork_,
02477 numberRows_*sizeof(double));
02478 memcpy(savedSolution_ ,columnActivityWork_,numberColumns_*sizeof(double));
02479 info->saveStatus();
02480 }
02481
02482 if (tentativeStatus>-3)
02483 primalColumnPivot_->saveWeights(this,(type <2) ? 2 : 4);
02484 else
02485 primalColumnPivot_->saveWeights(this,3);
02486 if (problemStatus_<0&&!changeMade_) {
02487 problemStatus_=4;
02488 }
02489 if (saveThreshold) {
02490
02491 factorization_->sparseThreshold(0);
02492 factorization_->goSparse();
02493 }
02494 lastGoodIteration_ = numberIterations_;
02495 }
02496
02497 void
02498 ClpSimplexPrimalQuadratic::createDjs (ClpQuadraticInfo * info,
02499 CoinIndexedVector * array1, CoinIndexedVector * array2)
02500 {
02501 int numberQuadraticRows = info->numberQuadraticRows();
02502 int numberQuadraticColumns = info->numberQuadraticColumns();
02503 int numberXColumns = info->numberXColumns();
02504 int numberXRows = info->numberXRows();
02505
02506
02507
02508
02509 {
02510
02511 double * storedCost = lower_+numberColumns_+numberXRows;
02512 double * storedUpper = upper_ + numberColumns_+numberXRows;
02513 double * storedValue = solution_ + numberColumns_+numberXRows;
02514 int * index = array1->getIndices();
02515 double * modifiedCost = array1->denseVector();
02516
02517 info->createGradient(this);
02518 double * gradient = info->gradient();
02519
02520
02521
02522
02523
02524
02525 int number=0;
02526 int iRow;
02527 for (iRow=0;iRow<numberRows_;iRow++) {
02528 int iPivot=pivotVariable_[iRow];
02529 if (gradient[iPivot]) {
02530 modifiedCost[iRow] = gradient[iPivot];
02531 index[number++]=iRow;
02532 }
02533 }
02534 array1->setNumElements(number);
02535 factorization_->updateColumnTranspose(array2,array1);
02536 memcpy(dual_,modifiedCost,numberRows_*sizeof(double));
02537 array1->clear();
02538 memcpy(dj_,gradient,(numberColumns_+numberRows_)*sizeof(double));
02539 matrix_->transposeTimes(-1.0,dual_,dj_,rowScale_,columnScale_);
02540 memset(dj_+numberXColumns,0,(numberXRows+numberQuadraticColumns)*sizeof(double));
02541
02542 for (iRow=0;iRow<numberRows_;iRow++) {
02543 dj_[numberColumns_+iRow]= cost_[numberColumns_+iRow]+dual_[iRow];
02544 }
02545 double saveSj=0.0;
02546 if (info->crucialSj()>=0)
02547 saveSj=solution_[info->crucialSj()];
02548
02549 for (iRow=0;iRow<numberQuadraticRows;iRow++) {
02550 solution_[iRow+numberXColumns]=dual_[iRow];
02551 }
02552
02553 int start = numberXColumns+numberQuadraticRows;
02554 memset(solution_+start,0,numberQuadraticColumns*sizeof(double));
02555 memset(dj_+numberXColumns,0,(numberQuadraticRows+numberQuadraticColumns)*sizeof(double));
02556 matrix_->times(-1.0,columnActivityWork_,modifiedCost,rowScale_,columnScale_);
02557 memset(modifiedCost,0,numberXRows*sizeof(double));
02558
02559 for (iRow=0;iRow<numberQuadraticColumns;iRow++) {
02560 int jSequence = iRow;
02561 double value=cost_[jSequence];
02562 if (fabs(value)>1.0e5) {
02563 assert (getColumnStatus(jSequence)==basic);
02564 }
02565 double value2=-modifiedCost[iRow+numberXRows];
02566 modifiedCost[iRow+numberXRows]=0.0;
02567 jSequence = iRow+start;
02568 if (getColumnStatus(jSequence)!=basic) {
02569 if (fabs(value2-value)>1.0e-3)
02570 solution_[jSequence]=0.0;
02571 value=value2;
02572 } else {
02573 solution_[jSequence]=value-value2;
02574 }
02575 storedCost[iRow]=value;
02576 storedUpper[iRow]=value;
02577 storedValue[iRow]=value;
02578 }
02579 if (info->crucialSj()>=0)
02580 solution_[info->crucialSj()]=saveSj;
02581 }
02582 if (numberIterations_==-1289) {
02583 int i;
02584 printf ("normal\n");
02585 for (i=0;i<numberRows_+numberColumns_;i++) {
02586 char x='N';
02587 if (getColumnStatus(i)==basic)
02588 x='B';
02589 printf("CH %d %c sol %g dj %g\n",i,x,solution_[i],dj_[i]);
02590 }
02591 }
02592 }
02593
02594 int
02595 ClpSimplexPrimalQuadratic::checkComplementarity (ClpQuadraticInfo * info,
02596 CoinIndexedVector * array1, CoinIndexedVector * array2)
02597 {
02598 createDjs(info,array1,array2);
02599 int numberXColumns = info->numberXColumns();
02600 int numberXRows = info->numberXRows();
02601 int start=numberXColumns+numberXRows;
02602 numberDualInfeasibilities_=0;
02603 sumDualInfeasibilities_=0.0;
02604
02605 const CoinPackedMatrix * quadratic =
02606 info->quadraticObjective();
02607 const int * columnQuadratic = quadratic->getIndices();
02608 const int * columnQuadraticStart = quadratic->getVectorStarts();
02609 const int * columnQuadraticLength = quadratic->getVectorLengths();
02610 const double * quadraticElement = quadratic->getElements();
02611 const double * originalCost = info->linearObjective();
02612 int iColumn;
02613 objectiveValue_=0.0;
02614 double infeasCost=0.0;
02615 double linearCost=0.0;
02616 int number0=0,number1=0,number2=0;
02617 #if 0
02618 int numberNSj=0;
02619 for (iColumn=numberXColumns+info->numberQuadraticRows();iColumn<numberColumns_;iColumn++) {
02620 if (getColumnStatus(iColumn)!=basic)
02621 numberNSj++;
02622 }
02623 printf("NumberN %d\n",numberNSj);
02624 #endif
02625 for (iColumn=0;iColumn<numberXColumns;iColumn++) {
02626 double valueI = solution_[iColumn];
02627 linearCost += valueI*originalCost[iColumn];
02628 double diff =cost_[iColumn]-originalCost[iColumn];
02629
02630 if (diff>0.0) {
02631 double above = valueI-lower_[iColumn];
02632 assert(above>=0.0);
02633 infeasCost += diff*above;
02634 } else if (diff<0.0) {
02635 double below = upper_[iColumn]-valueI;
02636 assert(below>=0.0);
02637 infeasCost -= diff*below;
02638 }
02639 int j;
02640 for (j=columnQuadraticStart[iColumn];
02641 j<columnQuadraticStart[iColumn]+columnQuadraticLength[iColumn];j++) {
02642 int jColumn = columnQuadratic[j];
02643 double valueJ = solution_[jColumn];
02644 double elementValue = 0.5*quadraticElement[j];
02645 objectiveValue_ += valueI*valueJ*elementValue;
02646 }
02647 int jSequence = iColumn+start;
02648 double value=dj_[iColumn];
02649 ClpSimplex::Status status = getColumnStatus(iColumn);
02650 if (status!=basic&&jSequence>=0) {
02651 if (getColumnStatus(jSequence)==basic)
02652 number1++;
02653 else
02654 number0++;
02655 }
02656
02657 switch(status) {
02658
02659 case ClpSimplex::basic:
02660 if (getColumnStatus(jSequence)==basic) {
02661 handler_->message(CLP_QUADRATIC_BOTH,messages_)
02662 <<"Structural"<<iColumn
02663 <<solution_[iColumn]<<jSequence<<solution_[jSequence]
02664 <<CoinMessageEol;
02665 number2++;
02666 assert (info->crucialSj()>=0);
02667 assert (info->crucialSj()==iColumn||info->crucialSj()==jSequence);
02668 } else {
02669 number1++;
02670 }
02671 break;
02672 case ClpSimplex::isFixed:
02673 break;
02674 case ClpSimplex::isFree:
02675 case ClpSimplex::superBasic:
02676 if (fabs(value)>dualTolerance_) {
02677 sumDualInfeasibilities_ += fabs(value)-dualTolerance_;
02678 numberDualInfeasibilities_++;
02679 }
02680 break;
02681 case ClpSimplex::atUpperBound:
02682 if (value>dualTolerance_) {
02683 sumDualInfeasibilities_ += value-dualTolerance_;
02684 numberDualInfeasibilities_++;
02685 }
02686 break;
02687 case ClpSimplex::atLowerBound:
02688 if (value<-dualTolerance_) {
02689 sumDualInfeasibilities_ -= value+dualTolerance_;
02690 numberDualInfeasibilities_++;
02691 }
02692 }
02693 }
02694 int offset = numberXColumns;
02695 int iRow;
02696 for (iRow=0;iRow<numberXRows;iRow++) {
02697 int iColumn = iRow + numberColumns_;
02698 double diff =cost_[iColumn];
02699 double valueI = solution_[iColumn];
02700 if (diff>0.0) {
02701 double above = valueI-lower_[iColumn];
02702 assert(above>=0.0);
02703 infeasCost += diff*above;
02704 } else if (diff<0.0) {
02705 double below = upper_[iColumn]-valueI;
02706 assert(below>=0.0);
02707 infeasCost -= diff*below;
02708 }
02709 int jSequence = iRow+offset;
02710 double value=dj_[iRow+numberColumns_];
02711 ClpSimplex::Status status = getRowStatus(iRow);
02712 if (status!=basic) {
02713 if (getColumnStatus(jSequence)==basic)
02714 number1++;
02715 else
02716 number0++;
02717 }
02718
02719 switch(status) {
02720
02721 case ClpSimplex::basic:
02722 if (getColumnStatus(jSequence)==basic) {
02723 printf("Row %d (%g) and %d (%g) both basic\n",
02724 iRow,solution_[iColumn],jSequence,solution_[jSequence]);
02725 number2++;
02726 assert (info->crucialSj()>=0);
02727 assert (info->crucialSj()==iColumn||info->crucialSj()==jSequence);
02728 } else {
02729 number1++;
02730 }
02731 break;
02732 case ClpSimplex::isFixed:
02733 break;
02734 case ClpSimplex::isFree:
02735 case ClpSimplex::superBasic:
02736 if (fabs(value)>dualTolerance_) {
02737 sumDualInfeasibilities_ += fabs(value)-dualTolerance_;
02738 numberDualInfeasibilities_++;
02739 }
02740 break;
02741 case ClpSimplex::atUpperBound:
02742 if (value>dualTolerance_) {
02743 sumDualInfeasibilities_ += value-dualTolerance_;
02744 numberDualInfeasibilities_++;
02745 }
02746 break;
02747 case ClpSimplex::atLowerBound:
02748 if (value<-dualTolerance_) {
02749 sumDualInfeasibilities_ -= value+dualTolerance_;
02750 numberDualInfeasibilities_++;
02751 }
02752 }
02753 }
02754
02755 objectiveValue_ += linearCost+infeasCost;
02756 assert (infeasCost>=0.0);
02757 sumOfRelaxedDualInfeasibilities_ =sumDualInfeasibilities_;
02758
02759 if (info->sequenceIn()>=0&&!numberDualInfeasibilities_)
02760 numberDualInfeasibilities_=1;
02761 numberDualInfeasibilitiesWithoutFree_= numberDualInfeasibilities_;
02762 info->setInfeasCost(infeasCost);
02763 return numberDualInfeasibilities_;
02764 }
02765
02766
02767
02768
02769 ClpSimplexPrimalQuadratic *
02770 ClpSimplexPrimalQuadratic::makeQuadratic(ClpQuadraticInfo & info)
02771 {
02772
02773
02774 ClpQuadraticObjective * quadraticObj = (dynamic_cast< ClpQuadraticObjective*>(objective_));
02775 assert (quadraticObj);
02776 CoinPackedMatrix * quadratic = quadraticObj->quadraticObjective();
02777 if (!quadratic||!quadratic->getNumElements()) {
02778
02779 return NULL;
02780 }
02781
02782 int numberColumns = this->numberColumns();
02783 double * columnLower = this->columnLower();
02784 double * columnUpper = this->columnUpper();
02785 double * objective = this->objective();
02786 double * solution = this->primalColumnSolution();
02787 double * dj = this->dualColumnSolution();
02788 double * pi = this->dualRowSolution();
02789
02790 int numberRows = this->numberRows();
02791 double * rowLower = this->rowLower();
02792 double * rowUpper = this->rowUpper();
02793
02794
02795 CoinPackedMatrix * matrix = this->matrix();
02796 const int * row = matrix->getIndices();
02797 const int * columnStart = matrix->getVectorStarts();
02798 const double * element = matrix->getElements();
02799 const int * columnLength = matrix->getVectorLengths();
02800
02801 int iColumn;
02802 const int * columnQuadratic = quadratic->getIndices();
02803 const int * columnQuadraticStart = quadratic->getVectorStarts();
02804 const int * columnQuadraticLength = quadratic->getVectorLengths();
02805 const double * quadraticElement = quadratic->getElements();
02806 #if 0
02807
02808
02809
02810
02811
02812 tempMessage messageHandler(this);;
02813 passInMessageHandler(&messageHandler);
02814 factorization()->maximumPivots(1);
02815 primal();
02816 CoinMessageHandler handler2;
02817 passInMessageHandler(&handler2);
02818 factorization()->maximumPivots(100);
02819 setMaximumIterations(1000);
02820 #endif
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832 info=ClpQuadraticInfo(this);
02833 quadratic = info.quadraticObjective();
02834 int numberQuadratic = info.numberQuadraticColumns();
02835 int newNumberRows = numberRows+numberQuadratic;
02836 int newNumberColumns = numberColumns + numberRows + numberQuadratic;
02837 int numberElements = 2*matrix->getNumElements()
02838 +2*quadratic->getNumElements()
02839 + numberQuadratic;
02840 double * elements2 = new double[numberElements];
02841 int * start2 = new int[newNumberColumns+1];
02842 int * row2 = new int[numberElements];
02843 double * objective2 = new double[newNumberColumns];
02844 double * columnLower2 = new double[newNumberColumns];
02845 double * columnUpper2 = new double[newNumberColumns];
02846 double * rowLower2 = new double[newNumberRows];
02847 double * rowUpper2 = new double[newNumberRows];
02848 memcpy(rowLower2,rowLower,numberRows*sizeof(double));
02849 memcpy(rowUpper2,rowUpper,numberRows*sizeof(double));
02850 int iRow;
02851 for (iRow=0;iRow<numberQuadratic;iRow++) {
02852 double cost = objective[iRow];
02853 rowLower2[iRow+numberRows]=cost;
02854 rowUpper2[iRow+numberRows]=cost;
02855 }
02856 memset(objective2,0,newNumberColumns*sizeof(double));
02857
02858 CoinPackedMatrix copyQ;
02859 copyQ.reverseOrderedCopyOf(*quadratic);
02860 const int * columnQ = copyQ.getIndices();
02861 const CoinBigIndex * rowStartQ = copyQ.getVectorStarts();
02862 const int * rowLengthQ = copyQ.getVectorLengths();
02863 const double * elementByRowQ = copyQ.getElements();
02864
02865 double * solution2 = new double[newNumberColumns];
02866 memset(solution2,0,newNumberColumns*sizeof(double));
02867 newNumberColumns=0;
02868 numberElements=0;
02869 start2[0]=0;
02870
02871 memcpy(dj,objective,numberColumns*sizeof(double));
02872 for (iColumn=0;iColumn<numberColumns;iColumn++) {
02873
02874 columnLower2[iColumn]=columnLower[iColumn];
02875 columnUpper2[iColumn]=columnUpper[iColumn];
02876 solution2[iColumn]=solution[iColumn];
02877
02878 objective2[iColumn]=objective[iColumn];
02879 int j;
02880 for (j=columnStart[iColumn];
02881 j<columnStart[iColumn]+columnLength[iColumn];
02882 j++) {
02883 elements2[numberElements]=element[j];
02884 row2[numberElements++]=row[j];
02885 }
02886
02887 for (j=columnQuadraticStart[iColumn];
02888 j<columnQuadraticStart[iColumn]+columnQuadraticLength[iColumn];
02889 j++) {
02890 int jColumn = columnQuadratic[j];
02891 double value = quadraticElement[j];
02892 if (iColumn!=jColumn)
02893 value *= 0.5;
02894 dj[jColumn] += solution[iColumn]*value;
02895 elements2[numberElements]=-value;
02896 row2[numberElements++]=jColumn+numberRows;
02897 }
02898 for (j=rowStartQ[iColumn];
02899 j<rowStartQ[iColumn]+rowLengthQ[iColumn];
02900 j++) {
02901 int jColumn = columnQ[j];
02902 double value = elementByRowQ[j];
02903 if (iColumn!=jColumn) {
02904 value *= 0.5;
02905 dj[jColumn] += solution[iColumn]*value;
02906 elements2[numberElements]=-value;
02907 row2[numberElements++]=jColumn+numberRows;
02908 }
02909 }
02910 start2[iColumn+1]=numberElements;
02911 }
02912 newNumberColumns=numberColumns;
02913
02914 int numberQuadraticRows = info.numberQuadraticRows();
02915
02916 CoinPackedMatrix copy;
02917 copy.reverseOrderedCopyOf(*(this->matrix()));
02918
02919 const int * column = copy.getIndices();
02920 const CoinBigIndex * rowStart = copy.getVectorStarts();
02921 const int * rowLength = copy.getVectorLengths();
02922 const double * elementByRow = copy.getElements();
02923 for (iRow=0;iRow<numberRows;iRow++) {
02924 solution2[newNumberColumns]=pi[iRow];
02925 double value = pi[iRow];
02926 columnLower2[newNumberColumns]=-COIN_DBL_MAX;
02927 columnUpper2[newNumberColumns]=COIN_DBL_MAX;
02928 int j;
02929 for (j=rowStart[iRow];
02930 j<rowStart[iRow]+rowLength[iRow];
02931 j++) {
02932 double elementValue=elementByRow[j];
02933 int jColumn = column[j];
02934 if (jColumn>=0) {
02935 elements2[numberElements]=elementValue;
02936 row2[numberElements++]=jColumn+numberRows;
02937 }
02938 dj[jColumn]-= value*elementValue;
02939 }
02940 #ifndef CORRECT_ROW_COUNTS
02941 newNumberColumns++;
02942 start2[newNumberColumns]=numberElements;
02943 #else
02944 if (numberElements>start2[newNumberColumns]) {
02945 newNumberColumns++;
02946 start2[newNumberColumns]=numberElements;
02947 }
02948 #endif
02949 }
02950
02951 for (iColumn=0;iColumn<numberQuadratic;iColumn++) {
02952 columnLower2[newNumberColumns]=-COIN_DBL_MAX;
02953 columnUpper2[newNumberColumns]=COIN_DBL_MAX;
02954 solution2[newNumberColumns]=dj[iColumn];
02955 elements2[numberElements]=1.0;
02956 row2[numberElements++]=iColumn+numberRows;
02957 newNumberColumns++;
02958 start2[newNumberColumns]=numberElements;
02959 }
02960
02961 ClpSimplex * model2 = new ClpSimplex(*this);
02962 model2->resize(0,0);
02963 model2->loadProblem(newNumberColumns,newNumberRows,
02964 start2,row2, elements2,
02965 columnLower2,columnUpper2,
02966 objective2,
02967 rowLower2,rowUpper2);
02968 delete [] rowLower2;
02969 delete [] rowUpper2;
02970 delete [] columnLower2;
02971 delete [] columnUpper2;
02972
02973
02974 start2[0]=0;
02975 numberElements=0;
02976 for (iColumn=0;iColumn<numberColumns;iColumn++) {
02977
02978 int j;
02979 for (j=columnQuadraticStart[iColumn];
02980 j<columnQuadraticStart[iColumn]+columnQuadraticLength[iColumn];
02981 j++) {
02982 int jColumn = columnQuadratic[j];
02983 double value = quadraticElement[j];
02984 if (iColumn!=jColumn)
02985 value *= 0.5;
02986 elements2[numberElements]=value;
02987 row2[numberElements++]=jColumn;
02988 }
02989 for (j=rowStartQ[iColumn];
02990 j<rowStartQ[iColumn]+rowLengthQ[iColumn];
02991 j++) {
02992 int jColumn = columnQ[j];
02993 double value = elementByRowQ[j];
02994 if (iColumn!=jColumn) {
02995 value *= 0.5;
02996 elements2[numberElements]=value;
02997 row2[numberElements++]=jColumn;
02998 }
02999 }
03000 start2[iColumn+1]=numberElements;
03001 }
03002
03003
03004
03005
03006 ClpQuadraticObjective * obj =
03007 new ClpQuadraticObjective(objective2,numberColumns,
03008 start2,row2,elements2,newNumberColumns);
03009 delete [] objective2;
03010 info.setOriginalObjective(obj);
03011
03012 delete [] start2;
03013 delete [] row2;
03014 delete [] elements2;
03015 model2->allSlackBasis();
03016
03017
03018 model2->setLogLevel(this->logLevel());
03019
03020 memcpy(model2->primalColumnSolution(),solution2,
03021 newNumberColumns*sizeof(double));
03022 columnLower2 = model2->columnLower();
03023 columnUpper2 = model2->columnUpper();
03024 delete [] solution2;
03025 solution2 = model2->primalColumnSolution();
03026
03027 double * rowSolution2 = model2->primalRowSolution();
03028 memset(rowSolution2,0,newNumberRows*sizeof(double));
03029 model2->times(1.0,solution2,rowSolution2);
03030 rowLower2 = model2->rowLower();
03031 rowUpper2 = model2->rowUpper();
03032 #if 0
03033
03034 for (iColumn=0;iColumn<numberColumns;iColumn++) {
03035 Status xStatus = getColumnStatus(iColumn);
03036 bool isSuperBasic;
03037 int iS = iColumn+newNumberRows;
03038 model2->setColumnStatus(iColumn,xStatus);
03039 if (xStatus==basic) {
03040 model2->setColumnStatus(iS,isFree);
03041 solution2[iS]=0.0;
03042 } else {
03043 model2->setColumnStatus(iS,basic);
03044 }
03045
03046 model2->setRowBasic(iColumn+numberRows,superBasic);
03047 }
03048 for (iRow=0;iRow<numberRows;iRow++) {
03049 Status rowStatus = getRowStatus(iRow);
03050 model2->setRowStatus(iRow,rowStatus);
03051 if (rowStatus!=basic) {
03052 model2->setColumnStatus(iRow+numberColumns,basic);
03053 }
03054 assert (rowSolution2[iRow]>=rowLower2[iRow]-primalTolerance_);
03055 assert (rowSolution2[iRow]<=rowUpper2[iRow]+primalTolerance_);
03056 }
03057
03058 for (iRow=0;iRow<numberRows;iRow++) {
03059 model2->setRowStatus(iRow,basic);
03060 model2->setColumnStatus(iRow+numberColumns,superBasic);
03061 solution2[iRow+numberColumns]=0.0;
03062 }
03063 #else
03064 for (iRow=0;iRow<numberRows;iRow++) {
03065 assert (rowSolution2[iRow]>=rowLower2[iRow]-primalTolerance_);
03066 assert (rowSolution2[iRow]<=rowUpper2[iRow]+primalTolerance_);
03067 model2->setRowStatus(iRow,basic);
03068 int jRow = iRow;
03069 model2->setColumnStatus(jRow+numberColumns,superBasic);
03070 solution2[jRow+numberColumns]=0.0;
03071 }
03072 for (iColumn=numberQuadraticRows+numberColumns;iColumn<newNumberColumns;iColumn++) {
03073 model2->setColumnStatus(iColumn,basic);
03074 model2->setRowStatus(iColumn-numberQuadraticRows-numberColumns+numberRows,isFixed);
03075 }
03076 #endif
03077 memset(rowSolution2,0,newNumberRows*sizeof(double));
03078 model2->times(1.0,solution2,rowSolution2);
03079 for (iColumn=0;iColumn<numberQuadratic;iColumn++) {
03080 int iS = iColumn+numberColumns+numberQuadraticRows;
03081 int iRow = iColumn+numberRows;
03082 double value = rowSolution2[iRow];
03083 if (value>rowUpper2[iRow]) {
03084 rowSolution2[iRow] = rowUpper2[iRow];
03085 solution2[iS]-=value-rowUpper2[iRow];
03086 } else {
03087 rowSolution2[iRow] = rowLower2[iRow];
03088 solution2[iS]-=value-rowLower2[iRow];
03089 }
03090 }
03091
03092
03093
03094 double objectiveOffset;
03095 getDblParam(ClpObjOffset,objectiveOffset);
03096 double objValue = -objectiveOffset;
03097 for (iColumn=0;iColumn<numberColumns;iColumn++)
03098 objValue += objective[iColumn]*solution2[iColumn];
03099 for (iColumn=0;iColumn<numberColumns;iColumn++) {
03100 double valueI = solution2[iColumn];
03101 int j;
03102 for (j=columnQuadraticStart[iColumn];
03103 j<columnQuadraticStart[iColumn]+columnQuadraticLength[iColumn];j++) {
03104 int jColumn = columnQuadratic[j];
03105 double valueJ = solution2[jColumn];
03106 double elementValue = quadraticElement[j];
03107 objValue += 0.5*valueI*valueJ*elementValue;
03108 }
03109 }
03110 printf("Objective value %g\n",objValue);
03111
03112
03113 return (ClpSimplexPrimalQuadratic *) model2;
03114 }
03115
03116
03117 int
03118 ClpSimplexPrimalQuadratic::endQuadratic(ClpSimplexPrimalQuadratic * quadraticModel,
03119 ClpQuadraticInfo & info)
03120 {
03121 memcpy(dualRowSolution(),quadraticModel->dualRowSolution(),numberRows_*sizeof(double));
03122 const double * solution2 = quadraticModel->primalColumnSolution();
03123 memcpy(primalColumnSolution(),solution2,numberColumns_*sizeof(double));
03124 memset(quadraticModel->primalRowSolution(),0,
03125 quadraticModel->numberRows()*sizeof(double));
03126 quadraticModel->times(1.0,quadraticModel->primalColumnSolution(),
03127 quadraticModel->primalRowSolution());
03128
03129 int iColumn;
03130 double objectiveOffset;
03131 getDblParam(ClpObjOffset,objectiveOffset);
03132 double objValue = -objectiveOffset;
03133 double * objective = this->objective();
03134 const double * pi = dualRowSolution();
03135 for (iColumn=0;iColumn<numberColumns_;iColumn++)
03136 objValue += objective[iColumn]*solution2[iColumn];
03137 ClpQuadraticObjective * quadraticObj = (dynamic_cast< ClpQuadraticObjective*>(objective_));
03138 assert (quadraticObj);
03139 CoinPackedMatrix * quadratic = quadraticObj->quadraticObjective();
03140 double * dj = dualColumnSolution();
03141
03142 const int * row = matrix_->getIndices();
03143 const int * columnStart = matrix_->getVectorStarts();
03144 const double * element = matrix_->getElements();
03145 const int * columnLength = matrix_->getVectorLengths();
03146 if (quadratic) {
03147 const int * columnQuadratic = quadratic->getIndices();
03148 const int * columnQuadraticStart = quadratic->getVectorStarts();
03149 const int * columnQuadraticLength = quadratic->getVectorLengths();
03150 const double * quadraticElement = quadratic->getElements();
03151 int start = info.numberQuadraticRows()+numberColumns_;
03152 for (iColumn=0;iColumn<numberColumns_;iColumn++) {
03153 int jColumn = iColumn;
03154 double valueI=solution2[iColumn];
03155 double value;
03156 if (jColumn>=0) {
03157 jColumn += start;
03158 value = solution2[jColumn];
03159 } else {
03160 value=objective[iColumn];
03161 int j;
03162 for (j=columnStart[iColumn];j<columnStart[iColumn]+columnLength[iColumn]; j++) {
03163 int iRow = row[j];
03164 value -= element[j]*pi[iRow];
03165 }
03166 }
03167 dj[iColumn]=value;
03168 Status status = quadraticModel->getColumnStatus(iColumn);
03169 setColumnStatus(iColumn,status);
03170 if (status==basic) {
03171 assert(fabs(value)<1.0e-2);
03172 }
03173 int j;
03174 for (j=columnQuadraticStart[iColumn];
03175 j<columnQuadraticStart[iColumn]+columnQuadraticLength[iColumn];j++) {
03176 int jColumn = columnQuadratic[j];
03177 double valueJ = solution2[jColumn];
03178 double elementValue = quadraticElement[j];
03179 objValue += 0.5*valueI*valueJ*elementValue;
03180 }
03181 }
03182 objectiveValue_ = objValue + objectiveOffset;
03183 } else {
03184
03185 for (iColumn=0;iColumn<numberColumns_;iColumn++) {
03186 double value=objective[iColumn];
03187 int j;
03188 for (j=columnStart[iColumn];j<columnStart[iColumn]+columnLength[iColumn]; j++) {
03189 int iRow = row[j];
03190 value -= element[j]*pi[iRow];
03191 }
03192 dj[iColumn]=value;
03193 Status status = quadraticModel->getColumnStatus(iColumn);
03194 setColumnStatus(iColumn,status);
03195 }
03196 }
03197
03198 int iRow;
03199 for (iRow=0;iRow<numberRows_;iRow++) {
03200 Status status = quadraticModel->getRowStatus(iRow);
03201 setRowStatus(iRow,status);
03202 }
03203 printf("Objective value %g\n",objValue);
03204 return 0;
03205 }
03206
03208 ClpQuadraticInfo::ClpQuadraticInfo()
03209 : originalObjective_(NULL),
03210 basicRow_(NULL),
03211 impliedSj_(NULL),
03212 currentSequenceIn_(-1),
03213 crucialSj_(-1),
03214 validSequenceIn_(-1),
03215 validCrucialSj_(-1),
03216 currentPhase_(-1),
03217 currentSolution_(NULL),
03218 validPhase_(-1),
03219 validSolution_(NULL),
03220 djWeight_(NULL),
03221 gradient_(NULL),
03222 numberXRows_(-1),
03223 numberXColumns_(-1),
03224 numberQuadraticColumns_(0),
03225 numberQuadraticRows_(0),
03226 infeasCost_(0.0)
03227 {
03228 }
03229
03230 ClpQuadraticInfo::ClpQuadraticInfo(const ClpSimplex * model)
03231 : originalObjective_(NULL),
03232 basicRow_(NULL),
03233 impliedSj_(NULL),
03234 currentSequenceIn_(-1),
03235 crucialSj_(-1),
03236 validSequenceIn_(-1),
03237 validCrucialSj_(-1),
03238 currentPhase_(-1),
03239 currentSolution_(NULL),
03240 validPhase_(-1),
03241 validSolution_(NULL),
03242 djWeight_(NULL),
03243 gradient_(NULL),
03244 numberXRows_(-1),
03245 numberXColumns_(-1),
03246 numberQuadraticColumns_(0),
03247 numberQuadraticRows_(0),
03248 infeasCost_(0.0)
03249 {
03250 if (model) {
03251 numberXRows_ = model->numberRows();
03252 numberXColumns_ = model->numberColumns();
03253
03254
03255 originalObjective_ = (dynamic_cast< ClpQuadraticObjective*>(model->objectiveAsObject()));
03256 assert (originalObjective_);
03257 impliedSj_ = new int[numberXColumns_];
03258 basicRow_ = new int[numberXColumns_];
03259 int i;
03260 numberQuadraticColumns_=numberXColumns_;
03261 numberQuadraticRows_=numberXRows_;
03262 int numberColumns = numberQuadraticRows_+numberXColumns_+numberQuadraticColumns_;
03263 int numberRows = numberXRows_+numberQuadraticColumns_;
03264 int size = numberRows+numberColumns;
03265 djWeight_ = new double [size];
03266 basicRow_ = new int[size];
03267 for (i=0;i<size;i++)
03268 djWeight_[i]=1.0;
03269 }
03270 }
03271
03272 ClpQuadraticInfo:: ~ClpQuadraticInfo()
03273 {
03274 delete [] impliedSj_;
03275 delete [] basicRow_;
03276 delete [] currentSolution_;
03277 delete [] validSolution_;
03278 delete [] djWeight_;
03279 delete [] gradient_;
03280 }
03281
03282 ClpQuadraticInfo::ClpQuadraticInfo(const ClpQuadraticInfo& rhs)
03283 : originalObjective_(rhs.originalObjective_),
03284 basicRow_(NULL),
03285 impliedSj_(NULL),
03286 currentSequenceIn_(rhs.currentSequenceIn_),
03287 crucialSj_(rhs.crucialSj_),
03288 validSequenceIn_(rhs.validSequenceIn_),
03289 validCrucialSj_(rhs.validCrucialSj_),
03290 currentPhase_(rhs.currentPhase_),
03291 currentSolution_(NULL),
03292 validPhase_(rhs.validPhase_),
03293 validSolution_(NULL),
03294 djWeight_(NULL),
03295 gradient_(NULL),
03296 numberXRows_(rhs.numberXRows_),
03297 numberXColumns_(rhs.numberXColumns_),
03298 numberQuadraticColumns_(rhs.numberQuadraticColumns_),
03299 numberQuadraticRows_(rhs.numberQuadraticRows_),
03300 infeasCost_(rhs.infeasCost_)
03301 {
03302 if (numberXColumns_) {
03303 int numberColumns = numberQuadraticRows_+numberXColumns_+numberQuadraticColumns_;
03304 int numberRows = numberXRows_+numberQuadraticColumns_;
03305 int size = numberRows+numberColumns;
03306 impliedSj_ = new int[numberXColumns_];
03307 memcpy(impliedSj_,rhs.impliedSj_,numberXColumns_*sizeof(int));
03308 basicRow_ = new int [size];
03309 memcpy(basicRow_,rhs.basicRow_,size*sizeof(int));
03310 if (rhs.currentSolution_) {
03311 currentSolution_ = new double [size];
03312 memcpy(currentSolution_,rhs.currentSolution_,size*sizeof(double));
03313 } else {
03314 currentSolution_ = NULL;
03315 }
03316 if (rhs.validSolution_) {
03317 validSolution_ = new double [size];
03318 memcpy(validSolution_,rhs.validSolution_,size*sizeof(double));
03319 } else {
03320 validSolution_ = NULL;
03321 }
03322 if (rhs.djWeight_) {
03323 djWeight_ = new double [size];
03324 memcpy(djWeight_,rhs.djWeight_,size*sizeof(double));
03325 } else {
03326 djWeight_ = NULL;
03327 }
03328 if (rhs.gradient_) {
03329 gradient_ = new double [size];
03330 memcpy(gradient_,rhs.gradient_,size*sizeof(double));
03331 } else {
03332 gradient_ = NULL;
03333 }
03334 }
03335 }
03336
03337 ClpQuadraticInfo &
03338 ClpQuadraticInfo::operator=(const ClpQuadraticInfo&rhs)
03339 {
03340 if (this != &rhs) {
03341 originalObjective_ = rhs.originalObjective_;
03342 delete [] impliedSj_;
03343 delete [] basicRow_;
03344 delete [] currentSolution_;
03345 delete [] validSolution_;
03346 delete [] djWeight_;
03347 delete [] gradient_;
03348 currentSequenceIn_ = rhs.currentSequenceIn_;
03349 crucialSj_ = rhs.crucialSj_;
03350 validSequenceIn_ = rhs.validSequenceIn_;
03351 validCrucialSj_ = rhs.validCrucialSj_;
03352 currentPhase_ = rhs.currentPhase_;
03353 validPhase_ = rhs.validPhase_;
03354 numberXRows_ = rhs.numberXRows_;
03355 numberXColumns_ = rhs.numberXColumns_;
03356 infeasCost_=rhs.infeasCost_;
03357 numberQuadraticColumns_=rhs.numberQuadraticColumns_;
03358 numberQuadraticRows_=rhs.numberQuadraticRows_;
03359 int numberColumns = numberQuadraticRows_+numberXColumns_+numberQuadraticColumns_;
03360 int numberRows = numberXRows_+numberQuadraticColumns_;
03361 int size = numberRows+numberColumns;
03362 impliedSj_ = new int[numberXColumns_];
03363 memcpy(impliedSj_,rhs.impliedSj_,numberXColumns_*sizeof(int));
03364 basicRow_ = new int [size];
03365 memcpy(basicRow_,rhs.basicRow_,size*sizeof(int));
03366 if (rhs.currentSolution_) {
03367 currentSolution_ = new double [size];
03368 memcpy(currentSolution_,rhs.currentSolution_,size*sizeof(double));
03369 } else {
03370 currentSolution_ = NULL;
03371 }
03372 if (rhs.validSolution_) {
03373 validSolution_ = new double [size];
03374 memcpy(validSolution_,rhs.validSolution_,size*sizeof(double));
03375 } else {
03376 validSolution_ = NULL;
03377 }
03378 if (rhs.djWeight_) {
03379 djWeight_ = new double [size];
03380 memcpy(djWeight_,rhs.djWeight_,size*sizeof(double));
03381 } else {
03382 djWeight_ = NULL;
03383 }
03384 if (rhs.gradient_) {
03385 gradient_ = new double [size];
03386 memcpy(gradient_,rhs.gradient_,size*sizeof(double));
03387 } else {
03388 gradient_ = NULL;
03389 }
03390 }
03391 return *this;
03392 }
03393
03394 void
03395 ClpQuadraticInfo::saveStatus()
03396 {
03397 validSequenceIn_ = currentSequenceIn_;
03398 validCrucialSj_ = crucialSj_;
03399 validPhase_ = currentPhase_;
03400 int numberColumns = numberQuadraticRows_+numberXColumns_+numberQuadraticColumns_;
03401 int numberRows = numberXRows_+numberQuadraticColumns_;
03402 int size = numberRows+numberColumns;
03403 if (currentSolution_) {
03404 if (!validSolution_)
03405 validSolution_ = new double [size];
03406 memcpy(validSolution_,currentSolution_,size*sizeof(double));
03407 }
03408 }
03409
03410 void
03411 ClpQuadraticInfo::restoreStatus()
03412 {
03413 currentSequenceIn_ = validSequenceIn_;
03414 crucialSj_ = validCrucialSj_;
03415 currentPhase_ = validPhase_;
03416 delete [] currentSolution_;
03417 currentSolution_ = validSolution_;
03418 validSolution_=NULL;
03419 }
03420 void
03421 ClpQuadraticInfo::setCurrentSolution(const double * solution)
03422 {
03423 if (currentPhase_) {
03424 int numberColumns = numberQuadraticRows_+numberXColumns_+numberQuadraticColumns_;
03425 int numberRows = numberXRows_+numberQuadraticColumns_;
03426 int size = numberRows+numberColumns;
03427 if (!currentSolution_)
03428 currentSolution_ = new double [size];
03429 memcpy(currentSolution_,solution,size*sizeof(double));
03430 } else {
03431 delete [] currentSolution_;
03432 currentSolution_=NULL;
03433 }
03434 }
03435
03436 CoinPackedMatrix *
03437 ClpQuadraticInfo::quadraticObjective() const
03438 {
03439 return originalObjective_->quadraticObjective();
03440 }
03441
03442 double *
03443 ClpQuadraticInfo::linearObjective() const
03444 {
03445 return originalObjective_->linearObjective();
03446 }
03447 void
03448 ClpQuadraticInfo::createGradient(ClpSimplex * model)
03449 {
03450 int numberColumns = numberQuadraticRows_+numberXColumns_+numberQuadraticColumns_;
03451 int numberRows = numberXRows_+numberQuadraticColumns_;
03452 int size = numberRows+numberColumns;
03453 if (!gradient_)
03454 gradient_= new double[size];
03455 memcpy(gradient_,model->costRegion(),size*sizeof(double));
03456 double * solution = model->solutionRegion();
03457 const CoinPackedMatrix * quadratic = quadraticObjective();
03458 const int * columnQuadratic = quadratic->getIndices();
03459 const int * columnQuadraticStart = quadratic->getVectorStarts();
03460 const int * columnQuadraticLength = quadratic->getVectorLengths();
03461 const double * quadraticElement = quadratic->getElements();
03462
03463 int jSequence;
03464 for (jSequence=0;jSequence<numberQuadraticColumns_;jSequence++) {
03465 int iSequence = jSequence;
03466
03467 double coeff1=gradient_[iSequence];
03468 int j;
03469 for (j=columnQuadraticStart[iSequence];
03470 j<columnQuadraticStart[iSequence]+columnQuadraticLength[iSequence];j++) {
03471 int jColumn = columnQuadratic[j];
03472 double valueJ = solution[jColumn];
03473
03474 double elementValue = quadraticElement[j];
03475 double addValue = valueJ*elementValue;
03476 coeff1 += addValue;
03477 }
03478 gradient_[iSequence]=coeff1;
03479 }
03480 }