Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

ClpSimplexPrimalQuadratic Class Reference

#include <ClpSimplexPrimalQuadratic.hpp>

Inheritance diagram for ClpSimplexPrimalQuadratic:

ClpSimplexPrimal ClpSimplex ClpModel List of all members.

Public Member Functions

Description of algorithm
int primalSLP (int numberPasses, double deltaTolerance)
 A sequential LP method.

int primalQuadratic (int phase=2)
int primalQuadratic2 (ClpQuadraticInfo *info, int phase=2)
ClpSimplexPrimalQuadraticmakeQuadratic (ClpQuadraticInfo &info)
int endQuadratic (ClpSimplexPrimalQuadratic *quadraticModel, ClpQuadraticInfo &info)
 This moves solution back.

int checkComplementarity (ClpQuadraticInfo *info, CoinIndexedVector *array1, CoinIndexedVector *array2)
 Checks complementarity and computes infeasibilities.

void createDjs (ClpQuadraticInfo *info, CoinIndexedVector *array1, CoinIndexedVector *array2)
 Fills in reduced costs.

int whileIterating (ClpQuadraticInfo *info)
int primalRow (CoinIndexedVector *rowArray, CoinIndexedVector *rhsArray, CoinIndexedVector *spareArray, CoinIndexedVector *spareArray2, ClpQuadraticInfo *info, int cleanupIteration)
void statusOfProblemInPrimal (int &lastCleaned, int type, ClpSimplexProgress *progress, ClpQuadraticInfo *info)

Detailed Description

This solves Quadratic LPs using the primal simplex method

It inherits from ClpSimplexPrimal. It has no data of its own and is never created - only cast from a ClpSimplexPrimal object at algorithm time. If needed create new class and pass around

Definition at line 26 of file ClpSimplexPrimalQuadratic.hpp.


Member Function Documentation

ClpSimplexPrimalQuadratic * ClpSimplexPrimalQuadratic::makeQuadratic ClpQuadraticInfo info  ) 
 

This creates the large version of QP and fills in quadratic information. Returns NULL if no quadratic information

Definition at line 2770 of file ClpSimplexPrimalQuadratic.cpp.

References ClpSimplex::allSlackBasis(), ClpSimplex::ClpSimplex(), ClpModel::columnLower(), ClpModel::columnUpper(), ClpModel::dualColumnSolution(), ClpModel::dualRowSolution(), ClpSimplex::factorization(), ClpSimplex::loadProblem(), ClpModel::matrix(), ClpModel::messageHandler(), ClpQuadraticInfo::numberQuadraticColumns(), ClpQuadraticInfo::numberQuadraticRows(), ClpModel::numberRows(), ClpModel::objective(), ClpModel::passInMessageHandler(), ClpSimplexPrimal::primal(), ClpModel::primalColumnSolution(), ClpModel::primalRowSolution(), ClpQuadraticInfo::quadraticObjective(), ClpQuadraticObjective::quadraticObjective(), ClpModel::resize(), ClpModel::rowLower(), ClpModel::rowUpper(), ClpSimplex::setColumnStatus(), ClpModel::setLogLevel(), ClpQuadraticInfo::setOriginalObjective(), ClpSimplex::setRowStatus(), and ClpSimplex::times().

Referenced by primalQuadratic().

02771 {
02772 
02773   // Get list of non linear columns
02774   ClpQuadraticObjective * quadraticObj = (dynamic_cast< ClpQuadraticObjective*>(objective_));
02775   assert (quadraticObj);
02776   CoinPackedMatrix * quadratic = quadraticObj->quadraticObjective();
02777   if (!quadratic||!quadratic->getNumElements()) {
02778     // no quadratic part
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   // and elements
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   // deliberate bad solution
02808   // Change to use phase
02809   //double * saveO = new double[numberColumns];
02810   //memcpy(saveO,objective,numberColumns*sizeof(double));
02811   //memset(objective,0,numberColumns*sizeof(double));
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   //memcpy(objective,saveO,numberColumns*sizeof(double));
02822   // Get a feasible solution 
02823   //printf("For testing - deliberate bad solution\n");
02824   //columnUpper[0]=0.0;
02825   //columnLower[0]=0.0;
02826   //quadraticSLP(50,1.0e-4);
02827   //primal(1);
02828   //columnUpper[0]=COIN_DBL_MAX;
02829   
02830   // Create larger problem
02831   // First workout how many rows extra
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   // Get a row copy of quadratic objective in standard format
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   // Move solution across
02865   double * solution2 = new double[newNumberColumns];
02866   memset(solution2,0,newNumberColumns*sizeof(double));
02867   newNumberColumns=0;
02868   numberElements=0;
02869   start2[0]=0;
02870   // x
02871   memcpy(dj,objective,numberColumns*sizeof(double));
02872   for (iColumn=0;iColumn<numberColumns;iColumn++) {
02873     // Original matrix
02874     columnLower2[iColumn]=columnLower[iColumn];
02875     columnUpper2[iColumn]=columnUpper[iColumn];
02876     solution2[iColumn]=solution[iColumn];
02877     // Put in cost so we know it
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     // Quadratic and modify djs
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   // pi
02914   int numberQuadraticRows = info.numberQuadraticRows();
02915   // Get a row copy in standard format
02916   CoinPackedMatrix copy;
02917   copy.reverseOrderedCopyOf(*(this->matrix()));
02918   // get matrix data pointers
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   // djs 
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   // Create model 
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   // Now create expanded quadratic objective for use in primalRow
02973   // Later pack down in some way
02974   start2[0]=0;
02975   numberElements=0;
02976   for (iColumn=0;iColumn<numberColumns;iColumn++) {
02977     // Quadratic
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   // and pad
03003   //for (;iColumn<newNumberColumns;iColumn++)
03004   //start2[iColumn+1]=numberElements;
03005   // Load up objective with expanded linear
03006   ClpQuadraticObjective * obj = 
03007     new ClpQuadraticObjective(objective2,numberColumns,
03008                               start2,row2,elements2,newNumberColumns);
03009   delete [] objective2;
03010   info.setOriginalObjective(obj);
03011   //model2->loadQuadraticObjective(newNumberColumns,start2,row2,elements2);
03012   delete [] start2;
03013   delete [] row2;
03014   delete [] elements2;
03015   model2->allSlackBasis();
03016   //model2->scaling(false);
03017   //printf("scaling off\n");
03018   model2->setLogLevel(this->logLevel());
03019   // Move solution across
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   // Compute row activities and check feasible
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   // redo as Dantzig says 
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     // take slack out on equality rows
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); // make dual basic
03053     }
03054     assert (rowSolution2[iRow]>=rowLower2[iRow]-primalTolerance_);
03055     assert (rowSolution2[iRow]<=rowUpper2[iRow]+primalTolerance_);
03056   }
03057   // why ?? - take duals out and adjust
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   // See if any s sub j have wrong sign and/or use djs from infeasibility objective
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   //for (iColumn=0;iColumn<newNumberColumns;iColumn++) 
03112   //printf("%d %g\n",iColumn,solution2[iColumn]);
03113   return (ClpSimplexPrimalQuadratic *) model2;
03114 }

int ClpSimplexPrimalQuadratic::primalQuadratic int  phase = 2  ) 
 

Dantzig's method (actually a mixture with Jensen and King) phase - 0 normal, 1 getting complementary solution, 2 getting basic solution. Returns 0 if okay, 1 if LP infeasible.

Definition at line 487 of file ClpSimplexPrimalQuadratic.cpp.

References endQuadratic(), ClpModel::getColLower(), ClpModel::getColUpper(), ClpModel::getObjCoefficients(), ClpModel::getRowLower(), ClpModel::getRowUpper(), makeQuadratic(), ClpModel::matrix(), ClpModel::messageHandler(), ClpSimplex::numberPrimalInfeasibilities(), ClpSimplexPrimal::primal(), primalQuadratic2(), CoinMessageHandler::setLogLevel(), CoinMpsIO::setMpsData(), ClpSimplex::setPrimalColumnPivotAlgorithm(), and CoinMpsIO::writeMps().

00488 {
00489   // Get a feasible solution 
00490   if (numberPrimalInfeasibilities())
00491     primal(1);
00492   // still infeasible
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 /*integrality*/,
00508                     model2->getRowLower(), model2->getRowUpper(),
00509                     NULL,NULL);
00510   writer.writeMps("xx.mps");
00511 #endif  
00512   // Now do quadratic
00513   //ClpPrimalQuadraticDantzig dantzigP(model2,&info);
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 }

int ClpSimplexPrimalQuadratic::primalQuadratic2 ClpQuadraticInfo info,
int  phase = 2
 

This is done after first pass phase - 0 normal, 1 getting complementary solution, 2 getting basic solution.

Definition at line 521 of file ClpSimplexPrimalQuadratic.cpp.

References checkComplementarity(), CoinIndexedVector::clear(), ClpQuadraticInfo::currentPhase(), ClpQuadraticInfo::currentSolution(), ClpQuadraticInfo::linearObjective(), ClpQuadraticInfo::numberQuadraticRows(), ClpQuadraticInfo::numberXColumns(), ClpQuadraticInfo::numberXRows(), ClpModel::objectiveAsObject(), ClpQuadraticInfo::originalObjective(), ClpPrimalColumnPivot::pivotColumn(), ClpQuadraticInfo::quadraticObjective(), ClpMatrixBase::refresh(), ClpSimplex::restoreData(), ClpSimplex::saveData(), ClpQuadraticInfo::sequenceIn(), ClpQuadraticInfo::setCrucialSj(), ClpQuadraticInfo::setCurrentPhase(), ClpQuadraticInfo::setSequenceIn(), ClpSimplex::startup(), statusOfProblemInPrimal(), and whileIterating().

Referenced by primalQuadratic().

00523 {
00524 
00525   algorithm_ = +2;
00526 
00527   // save data
00528   ClpDataSave data = saveData();
00529   // Only ClpPackedMatrix at present
00530   assert ((dynamic_cast< ClpPackedMatrix*>(matrix_)));
00531   
00532   // Assume problem is feasible
00533   // Stuff below will be moved into a class
00534   int numberXColumns = info->numberXColumns();
00535   int numberXRows = info->numberXRows();
00536   // initialize - values pass coding and algorithm_ is +1
00537   ClpObjective * saveObj = objectiveAsObject();
00538   setObjectivePointer(info->originalObjective());
00539   factorization_->setBiasLU(0);
00540   if (!startup(1)) {
00541 
00542     //setObjectivePointer(saveObj);
00543     // Setup useful stuff
00544     info->setCurrentPhase(phase);
00545     int lastCleaned=0; // last time objective or bounds cleaned up
00546     info->setSequenceIn(-1);
00547     info->setCrucialSj(-1);
00548     bool deleteCosts=false;
00549     if (scalingFlag_>0) {
00550       // scale
00551       CoinPackedMatrix * quadratic = info->quadraticObjective();
00552       double * objective = info->linearObjective();
00553       // replace column by column
00554       double * newElement = new double[numberXColumns];
00555       // scale column copy
00556       // get matrix data pointers
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       // direction is actually scale out not scale in
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       // replace column by column
00586       double * newElement = new double[numberXColumns];
00587       // get matrix data pointers
00588       const CoinBigIndex * columnStart = quadratic->getVectorStarts();
00589       const int * columnLength = quadratic->getVectorLengths(); 
00590       const double * elementByColumn = quadratic->getElements();
00591       double direction = optimizationDirection_;
00592       // direction is actually scale out not scale in
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     // Say no pivot has occurred (for steepest edge and updates)
00612     pivotRow_=-2;
00613     
00614     // This says whether to restore things etc
00615     int factorType=0;
00616     /*
00617       Status of problem:
00618       0 - optimal
00619       1 - infeasible
00620       2 - unbounded
00621       -1 - iterating
00622       -2 - factorization wanted
00623       -3 - redo checking without factorization
00624       -4 - looks infeasible
00625       -5 - looks unbounded
00626     */
00627     while (problemStatus_<0) {
00628       int iRow,iColumn;
00629       // clear
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       // give matrix (and model costs and bounds a chance to be
00639       // refreshed (normally null)
00640       matrix_->refresh(this);
00641       // If we have done no iterations - special
00642       if (lastGoodIteration_==numberIterations_)
00643         factorType=3;
00644       // may factorize, checks if problem finished
00645       statusOfProblemInPrimal(lastCleaned,factorType,progress_,info);
00646       if (problemStatus_>=0)
00647         break; // declare victory
00648       
00649       checkComplementarity (info,rowArray_[0],rowArray_[1]);
00650 
00651       // Say good factorization
00652       factorType=1;
00653       
00654       // Say no pivot has occurred (for steepest edge and updates)
00655       pivotRow_=-2;
00656       // Check problem phase 
00657       // We assume all X are feasible
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       // exit if victory declared
00698       dualIn_=0.0; // so no updates
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       // Iterate
00708       problemStatus_=-1;
00709       whileIterating(info);
00710     }
00711     if (deleteCosts) {
00712       // delete scaled copy of objective
00713       delete info->originalObjective();
00714     }
00715   }
00716   setObjectivePointer(saveObj);
00717   // clean up
00718   finish();
00719   restoreData(data);
00720   return problemStatus_;
00721 }

int ClpSimplexPrimalQuadratic::primalRow CoinIndexedVector rowArray,
CoinIndexedVector rhsArray,
CoinIndexedVector spareArray,
CoinIndexedVector spareArray2,
ClpQuadraticInfo info,
int  cleanupIteration
 

Row array has pivot column This chooses pivot row. Rhs array is used for distance to next bound (for speed) For speed, we may need to go to a bucket approach when many variables go through bounds On exit rhsArray will have changes in costs of basic variables Initially no go thru Returns 0 - can do normal iteration 1 - losing complementarity cleanupIteration - 0 no, 1 yes, 2 restoring one of x/s in basis

Definition at line 1349 of file ClpSimplexPrimalQuadratic.cpp.

References ClpNonLinearCost::changeInCost(), CoinIndexedVector::clear(), ClpQuadraticInfo::crucialSj(), ClpQuadraticInfo::currentPhase(), CoinIndexedVector::denseVector(), CoinIndexedVector::getIndices(), CoinIndexedVector::getNumElements(), ClpNonLinearCost::goBack(), ClpNonLinearCost::goBackAll(), ClpNonLinearCost::goThru(), ClpQuadraticInfo::linearObjective(), CoinMessageHandler::logLevel(), CoinMessageHandler::message(), ClpNonLinearCost::nearest(), ClpQuadraticInfo::numberXColumns(), ClpQuadraticInfo::originalObjective(), ClpQuadraticObjective::quadraticObjective(), ClpQuadraticInfo::quadraticObjective(), CoinIndexedVector::setNumElements(), and ClpSimplex::solution().

Referenced by whileIterating().

01355 {
01356   int result=1;
01357   
01358   // sequence stays as row number until end
01359   pivotRow_=-1;
01360   int numberSwapped=0;
01361   int numberRemaining=0;
01362   int crucialSj = info->crucialSj();
01363   if (crucialSj<0)
01364     result=0; // linear
01365   int numberThru =0; // number gone thru a barrier
01366   int lastThru =0; // number gone thru a barrier on last time
01367   
01368   double totalThru=0.0; // for when variables flip
01369   double acceptablePivot=1.0e-7;
01370   if (factorization_->pivots())
01371     acceptablePivot=1.0e-5; // if we have iterated be more strict
01372   double bestEverPivot=acceptablePivot;
01373   int lastPivotRow = -1;
01374   double lastPivot=0.0;
01375   double lastTheta=1.0e50;
01376   int lastNumberSwapped=0;
01377 
01378   // use spareArrays to put ones looked at in
01379   // First one is list of candidates
01380   // We could compress if we really know we won't need any more
01381   // Second array has current set of pivot candidates
01382   // with a backup list saved in double * part of indexed vector
01383 
01384   // for zeroing out arrays after
01385   int maximumSwapped=0;
01386   // pivot elements
01387   double * spare;
01388   // indices
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   // we also need somewhere for effective rhs
01399   double * rhs=rhsArray->denseVector();
01400 
01401   /*
01402     First we get a list of possible pivots.  We can also see if the
01403     problem looks unbounded.
01404 
01405     At first we increase theta and see what happens.  We start
01406     theta at a reasonable guess.  If in right area then we do bit by bit.
01407     We save possible pivot candidates
01408 
01409    */
01410 
01411   // do first pass to get possibles 
01412   // We can also see if unbounded
01413 
01414   double * work=rowArray->denseVector();
01415   int number=rowArray->getNumElements();
01416   int * which=rowArray->getIndices();
01417 
01418   // we need to swap sign if coming in from ub
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   // Work out coefficients for quadratic term
01429   // This is expanded one
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   //const double * originalCost = info->originalObjective();
01436   // Use rhsArray
01437   rhsArray->clear();
01438   int * index2 = rhsArray->getIndices();
01439   int numberXColumns = info->numberXColumns();
01440   int number2=0;
01441   //int numberOriginalRows = info->numberXRows();
01442   // sj 
01443   int iSjRow=-1;
01444   // sj for incoming 
01445   int iSjRow2=-1,crucialSj2=-1;
01446   if (sequenceIn_<numberXColumns) {
01447     crucialSj2 = sequenceIn_;
01448     crucialSj2 += numberRows_; // sj2 which should go to 0.0
01449   } else if (sequenceIn_>=numberColumns_) {
01450     int iRow=sequenceIn_-numberColumns_;
01451     crucialSj2 = iRow;
01452     crucialSj2 += numberXColumns; // sj2 which should go to 0.0
01453   }
01454   double tj = 0.0;
01455   // Change in objective will be theta*coeff1 + theta*theta*coeff2
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       //printf("col %d alpha %g solution %g cost %g scale %g\n",iPivot,alpha,solution_[iPivot],
01470       //     cost_[iPivot],columnScale_[iPivot]);
01471     } else {
01472       if (iPivot>=numberColumns_) {
01473         // ? do we go through column of pi
01474         assert (iPivot!=crucialSj);
01475         coeffSlack += alpha*cost_[iPivot];
01476       } else if (iPivot<numberRows_) {
01477         // ? do we go through column of pi
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   // Incoming
01493   if (sequenceIn_<numberXColumns) {
01494     index2[number2++]=sequenceIn_;
01495     rhs[sequenceIn_]=way;
01496     //printf("incoming col %d alpha %g solution %g cost %g scale %g\n",sequenceIn_,way,valueIn_,
01497     //   cost_[sequenceIn_],columnScale_[sequenceIn_]);
01498     coeff1 += way*cost_[sequenceIn_];
01499   } else {
01500     //printf("incoming new col %d alpha %g solution %g\n",sequenceIn_,way,valueIn_);
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     //double valueI = solution_[iColumn];
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   //coeff1 = way*dualIn_;
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       // bad
01541       accuracyFlag=2;
01542     } else if (fabs(way*coeff1-dualIn_)>1.0e-3*(1.0+fabs(dualIn_))) {
01543       // not wonderful
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   // interesting places are where derivative zero or sj goes to zero
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     //if (sequenceIn_<numberXColumns)
01566       //printf("column %d is basically linear\n",sequenceIn_);
01567     //assert(!columnQuadraticLength[sequenceIn_]);
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     // linear variable entering
01577     // maybe we should have done dual iteration to force sj to 0.0
01578     //printf("linear variable\n");
01579   }
01580   handler_->message(CLP_QUADRATIC_PRIMAL_DETAILS,messages_)
01581     <<coeff1<<coeff2<<coeffSlack<<dualIn_<<d1<<d2
01582     <<CoinMessageEol;
01583   // reality check
01584   {
01585     if (crucialSj2>=0) {
01586       // see if works out
01587       if (getColumnStatus(crucialSj2)==basic) {
01588         if (iSjRow2>=0) {
01589           //corresponding alpha nonzero
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   //if (!cleanupIteration)
01607   //dualIn_ = way*coeff1;
01608   double mind1d2=1.0e50;
01609   if (cleanupIteration) {
01610     // we are only interested in d1 if smaller than d2
01611     mind1d2 = min(maximumMovement,d2);
01612     //if (d1>1.0e-8&&d1<0.999*d2)
01613     //mind1d2=d1;
01614   } else {
01615     // There is no d2 - d1 refers to crucialSj
01616     if (d1>1.0e-5) {
01617       mind1d2 = min(maximumMovement,d1);
01618       //assert (d1>=0.0);
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     // get where in bound sequence
01646     if (alpha>0.0) {
01647       // basic variable going towards lower bound
01648       double bound = lower(iPivot);
01649       oldValue -= bound;
01650     } else if (alpha<0.0) {
01651       // basic variable going towards upper bound
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         // basic variable going towards lower bound
01660         oldValue2 -= bound;
01661       } else if (alpha<0.0) {
01662         // basic variable going towards upper bound
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       // add to list
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   // we need to keep where rhs non-zeros are
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     // looks like pivoting
01701     // now try until reasonable theta
01702     tentativeTheta = max(10.0*upperTheta,1.0e-7);
01703     tentativeTheta = min(tentativeTheta,maximumMovement);
01704     
01705     // loops increasing tentative theta until can't go through
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           // how much would it cost to go thru
01727           thruThis += alpha*
01728             nonLinearCost_->changeInCost(pivotVariable_[iRow],alpha);
01729           // goes on swapped list (also means candidates if too many)
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       //double dualCheck = - 2.0*coeff2*tentativeTheta - coeff1 - 0.1*infeasibilityCost_;
01747       double dualCheck = - 2.0*coeff2*tentativeTheta - coeff1;
01748       // but make a bit more pessimistic if pivot
01749       //if (bestPivot>acceptablePivot)
01750       //dualCheck=max(dualCheck-100.0*dualTolerance_,0.99*dualCheck);
01751       //dualCheck=0.0;
01752       if ((totalThru+thruThis>=dualCheck&&bestPivot>acceptablePivot)||fake*bestPivot>1.0e-3) {
01753         // We should be pivoting in this batch
01754         // so compress down to this lot
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         // first get ratio with tolerance
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           // now look at best in this lot
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               // how much would it cost to go thru
01798               totalThru += alpha*
01799                 nonLinearCost_->changeInCost(pivotVariable_[iRow],alpha);
01800               // goes on swapped list (also means candidates if too many)
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             // back to previous one
01818             goBackOne = true;
01819             break;
01820           } else if (pivotRow_==-1&&upperTheta>largeValue_) {
01821             if (lastPivot>acceptablePivot) {
01822               // back to previous one
01823               goBackOne = true;
01824               //break;
01825             } else {
01826               // can only get here if all pivots so far too small
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                 // We can pivot out sj
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                     // make sure will take correct path
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; // no point trying another loop
01854             } else if (totalThru>=dualCheck||fake*bestPivot>1.0e-3||upperTheta==maximumMovement) {
01855               break; // no point trying another loop
01856             } else {
01857               // skip this lot
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         // skip this lot
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     // can get here without pivotRow_ set but with lastPivotRow
01888     if (goBackOne||(pivotRow_<0&&lastPivotRow>=0)) {
01889       // back to previous one
01890       pivotRow_=lastPivotRow;
01891       theta_ = lastTheta;
01892             // undo this lot
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     // translate to sequence
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;      // to upper bound
01915     } else {
01916       directionOut_=1;      // to lower bound
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     // will we need to increase tolerance
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     // translate to sequence
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;      // to upper bound
01964       if (fabs(theta_)>1.0e-6)
01965         upperOut_ = nonLinearCost_->nearest(sequenceOut_,newValue);
01966       else
01967         upperOut_ = newValue;
01968     } else {
01969       directionOut_=1;      // to lower bound
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     // If no pivot but bad move then throw away
01978     if (throwAway&&(sequenceIn_<numberXColumns||sequenceIn_>=numberColumns_)) {
01979       assert (pivotRow_<0);
01980       accuracyFlag=2;
01981     }
01982     if (maximumMovement<1.0e20&&maximumMovement==trueMaximumMovement) {
01983       // flip
01984       theta_ = maximumMovement;
01985       pivotRow_ = -2; // so we can tell its a flip
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;      // to lower bound
01997         theta_ = lowerOut_ - valueOut_;
01998       } else {
01999         directionOut_=-1;      // to upper bound
02000         theta_ = upperOut_ - valueOut_;
02001       }
02002       // we may still have sj to get rid of
02003     } else if (fabs(maximumMovement-mind1d2)<dualTolerance_) {
02004       // crucialSj local copy i.e. dj going to zero
02005       if (maximumMovement==d2) {
02006         // sj going to zero
02007         result=0;
02008       } else {
02009         // incoming dj going to zero
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           // If crucialSj <0 then make superbasic?
02019           if (crucialSj<0) {
02020             printf("**ouch\n");
02021             theta_ = maximumMovement;
02022             pivotRow_ = -2; // so we can tell its a flip
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;      // to lower bound
02034               lowerIn_ = valueOut_-theta_;
02035               theta_ = lowerIn_ - valueOut_;
02036             } else {
02037               directionOut_=-1;      // to upper bound
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             // could do this in other places if pivot looks good
02047             printf("Should take minimum\n");
02048             pivotRow_ = whichMinimum;
02049             alpha_ = work[pivotRow_];
02050             // translate to sequence
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         // translate to sequence
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       // need to do something
02083       accuracyFlag=2;
02084     }
02085   }
02086   }
02087 
02088 
02089   // clear arrays
02090 
02091   memset(spare,0,numberRemaining*sizeof(double));
02092   memset(saveSwapped,0,maximumSwapped*sizeof(int));
02093 
02094   // put back original bounds etc
02095   nonLinearCost_->goBackAll(rhsArray);
02096 
02097   rhsArray->clear();
02098   // Change in objective will be theta*coeff1 + theta*theta*coeff2
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; // make sure correct path
02129     return 20;
02130   }
02131 }

int ClpSimplexPrimalQuadratic::primalSLP int  numberPasses,
double  deltaTolerance
 

A sequential LP method.

Primal algorithms for quadratic At present we have two algorithms:

a) Dantzig's algorithm b) Using a semi-trust region approach as for pooling problem This is in because I have it lying around

Definition at line 58 of file ClpSimplexPrimalQuadratic.cpp.

References ClpModel::columnLower(), ClpModel::columnUpper(), ClpModel::dualColumnSolution(), ClpModel::matrix(), ClpSimplex::numberPrimalInfeasibilities(), ClpModel::numberRows(), ClpModel::objective(), ClpModel::optimizationDirection(), ClpSimplexPrimal::primal(), ClpModel::primalColumnSolution(), ClpQuadraticObjective::quadraticObjective(), ClpSimplex::scaling(), ClpModel::setDblParam(), ClpModel::setLogLevel(), CoinMpsIO::setMpsData(), ClpModel::status(), and CoinMpsIO::writeMps().

00059 {
00060   // Are we minimizing or maximizing
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   // This is as a user would see
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   // Save objective
00077   
00078   double * saveObjective = new double [numberColumns];
00079   memcpy(saveObjective,objective,numberColumns*sizeof(double));
00080 
00081   // Get list of non linear columns
00082   ClpQuadraticObjective * quadraticObj = (dynamic_cast< ClpQuadraticObjective*>(objective_));
00083   CoinPackedMatrix * quadratic = NULL;
00084   if (quadraticObj)
00085     quadratic = quadraticObj->quadraticObjective();
00086   if (!quadratic) {
00087     // no quadratic part
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     // no quadratic part
00115     return primal(0);
00116   }
00117 
00118   // get feasible
00119   if (!this->status()||numberPrimalInfeasibilities())
00120     primal(1);
00121   // still infeasible
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   // 1 bound up, 2 up, -1 bound down, -2 down, 0 no change
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   // goodMove +1 yes, 0 no, -1 last was bad - just halve gaps, -2 do nothing
00156   int goodMove=-2;
00157   char * statusCheck = new char[numberColumns];
00158   for (iPass=0;iPass<numberPasses;iPass++) {
00159     // redo objective
00160     double offset=0.0;
00161     double objValue=-objectiveOffset;
00162     double lambda=-1.0;
00163     if (goodMove>=0) {
00164       // get best interpolation 
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         // update solution
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           // tighten all
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     // goodMove +1 yes, 0 no, -1 last was bad - just halve gaps, -2 do nothing
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           // halve
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       // get reduced costs
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 /*integrality*/,
00410                           getRowLower(), getRowUpper(),
00411                           NULL,NULL);
00412         writer.writeMps("xx.mps");
00413       }
00414       assert (!this->status()); // must be feasible
00415       goodMove=1;
00416     } else {
00417       // bad pass - restore solution
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   // restore solution
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   // redo objective
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   // redo values
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 }

void ClpSimplexPrimalQuadratic::statusOfProblemInPrimal int &  lastCleaned,
int  type,
ClpSimplexProgress progress,
ClpQuadraticInfo info
 

Refactorizes if necessary Checks if finished. Updates status. lastCleaned refers to iteration at which some objective/feasibility cleaning too place.

type - 0 initial so set up save arrays etc

  • 1 normal -if good update save
  • 2 restoring from saved

Definition at line 2134 of file ClpSimplexPrimalQuadratic.cpp.

References checkComplementarity(), ClpNonLinearCost::checkInfeasibilities(), ClpSimplex::createRim(), ClpQuadraticInfo::crucialSj(), ClpQuadraticInfo::currentPhase(), ClpQuadraticInfo::currentSolution(), ClpSimplex::dualFeasible(), ClpSimplex::gutsOfSolution(), ClpSimplexProgress::lastIterationNumber(), ClpPrimalColumnPivot::looksOptimal(), ClpSimplexProgress::looping(), CoinMessageHandler::message(), ClpNonLinearCost::numberInfeasibilities(), ClpQuadraticInfo::numberXColumns(), ClpModel::objectiveValue(), ClpSimplex::primalFeasible(), CoinMessageHandler::printing(), ClpQuadraticInfo::restoreStatus(), ClpQuadraticInfo::saveStatus(), ClpPrimalColumnPivot::saveWeights(), ClpQuadraticInfo::sequenceIn(), ClpQuadraticInfo::setCurrentSolution(), ClpSimplex::setFlagged(), ClpQuadraticInfo::setSequenceIn(), ClpNonLinearCost::sumInfeasibilities(), ClpSimplexPrimal::unflag(), and ClpSimplexPrimal::unPerturb().

Referenced by primalQuadratic2().

02137 {
02138   if (info->currentPhase())
02139     info->setCurrentSolution(solution_);
02140   //info->saveStatus();
02141   
02142   if (type==2) {
02143     // trouble - restore solution
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; // a bit drastic but ..
02150     pivotRow_=-1; // say no weights update
02151     changeMade_++; // say change made
02152     info->restoreStatus();
02153   }
02154   int saveThreshold = factorization_->sparseThreshold();
02155   int tentativeStatus = problemStatus_;
02156   if (problemStatus_>-3||problemStatus_==-4) {
02157     // factorize
02158     // later on we will need to recover from singularities
02159     // also we could skip if first time
02160     // do weights
02161     // This may save pivotRow_ for use 
02162     primalColumnPivot_->saveWeights(this,1);
02163 
02164     if (type) {
02165       // is factorization okay?
02166       int numberPivots = factorization_->pivots();
02167       if (internalFactorize(1)) {
02168         if (solveType_==2) {
02169           // say odd
02170           problemStatus_=5;
02171           return;
02172         }
02173         numberIterations_ = progress_->lastIterationNumber(0);
02174         // no - restore previous basis
02175         assert (info->crucialSj()<0); // need to work out how to unwind
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; // a bit drastic but ..
02183         type = 2;
02184         assert (internalFactorize(1)==0);
02185         info->restoreStatus();
02186         // flag incoming
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               // row
02196               iSequence = crucialSj-numberXColumns+numberColumns_;
02197             } else {
02198               // column
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_++; // say change made
02210       }
02211     }
02212     if (problemStatus_!=-4)
02213       problemStatus_=-3;
02214   }
02215   if (info->crucialSj()<0) {
02216     // at this stage status is -3 or -5 if looks unbounded
02217     // get primal and dual solutions
02218     // put back original costs and then check
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     // Double check reduced costs if no action
02232     if (progress->lastIterationNumber(0)==numberIterations_) {
02233       if (primalColumnPivot_->looksOptimal()) {
02234         numberDualInfeasibilities_ = 0;
02235         sumDualInfeasibilities_ = 0.0;
02236       }
02237     }
02238     // Check if looping
02239     int loop;
02240     if (type!=2) 
02241       loop = progress->looping(); // saves iteration number
02242     else
02243       loop=-1;
02244     //loop=-1;
02245     if (loop>=0) {
02246       problemStatus_ = loop; //exit if in loop
02247       return ;
02248     } else if (loop<-1) {
02249       // something may have changed
02250       gutsOfSolution(NULL,NULL);
02251       checkComplementarity(info,rowArray_[2],rowArray_[3]);
02252     }
02253     // really for free variables in
02254     //if((progressFlag_&2)!=0)
02255     //problemStatus_=-1;;
02256     progressFlag_ = 0; //reset progress flag
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     // we may wish to say it is optimal even if infeasible
02270     bool alwaysOptimal = (specialOptions_&1)!=0;
02271     // give code benefit of doubt
02272     if (sumOfRelaxedDualInfeasibilities_ == 0.0&&
02273         sumOfRelaxedPrimalInfeasibilities_ == 0.0&&info->sequenceIn()<0) {
02274       // say optimal (with these bounds etc)
02275       numberDualInfeasibilities_ = 0;
02276       sumDualInfeasibilities_ = 0.0;
02277       numberPrimalInfeasibilities_ = 0;
02278       sumPrimalInfeasibilities_ = 0.0;
02279     }
02280     // had ||(type==3&&problemStatus_!=-5) -- ??? why ????
02281     if (dualFeasible()||problemStatus_==-4) {
02282       if (nonLinearCost_->numberInfeasibilities()&&!alwaysOptimal) {
02283         //may need infeasiblity cost changed
02284         // we can see if we can construct a ray
02285         // make up a new objective
02286         double saveWeight = infeasibilityCost_;
02287         // save nonlinear cost as we are going to switch off costs
02288         ClpNonLinearCost * nonLinear = nonLinearCost_;
02289         // do twice to make sure Primal solution has settled
02290         // put non-basics to bounds in case tolerance moved
02291         // put back original costs
02292         createRim(4);
02293         // put all non-basic variables to bounds
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         // put back original costs
02309         createRim(4);
02310         nonLinearCost_->checkInfeasibilities(primalTolerance_);
02311         // may have fixed infeasibilities - double check
02312         if (nonLinearCost_->numberInfeasibilities()==0) {
02313           // carry on
02314           problemStatus_ = -1;
02315           infeasibilityCost_=saveWeight;
02316           nonLinearCost_->checkInfeasibilities(primalTolerance_);
02317           checkComplementarity(info,rowArray_[2],rowArray_[3]);
02318         } else {
02319           nonLinearCost_=NULL;
02320           // scale
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(); // stop any further perturbation
02330             numberDualInfeasibilities_=1; // carry on
02331           }
02332           if (infeasibilityCost_>=1.0e20||
02333               numberDualInfeasibilities_==0) {
02334             // we are infeasible - use as ray
02335             delete [] ray_;
02336             ray_ = new double [numberRows_];
02337             memcpy(ray_,dual_,numberRows_*sizeof(double));
02338             // and get feasible duals
02339             infeasibilityCost_=0.0;
02340             createRim(4);
02341             // put all non-basic variables to bounds
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             // so will exit
02354             infeasibilityCost_=1.0e30;
02355             // reset infeasibilities
02356             sumPrimalInfeasibilities_=nonLinearCost_->sumInfeasibilities();;
02357             numberPrimalInfeasibilities_=
02358               nonLinearCost_->numberInfeasibilities();
02359           }
02360           if (infeasibilityCost_<1.0e20) {
02361             infeasibilityCost_ *= 5.0;
02362             changeMade_++; // say change made
02363             handler_->message(CLP_PRIMAL_WEIGHT,messages_)
02364               <<infeasibilityCost_
02365               <<CoinMessageEol;
02366             // put back original costs and then check
02367             createRim(4);
02368             nonLinearCost_->checkInfeasibilities(0.0);
02369             gutsOfSolution(NULL,NULL);
02370             checkComplementarity(info,rowArray_[2],rowArray_[3]);
02371             problemStatus_=-1; //continue
02372           } else {
02373             // say infeasible
02374             problemStatus_ = 1;
02375           }
02376         }
02377       } else {
02378         // may be optimal
02379         if (perturbation_==101) {
02380           unPerturb(); // stop any further perturbation
02381           lastCleaned=-1; // carry on
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_++; // say change made
02390             if (numberTimesOptimal_==1) {
02391               // better to have small tolerance even if slower
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             // put back original costs and then check
02401             createRim(4);
02402             // put all non-basic variables to bounds
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; // optimal
02417             if (lastCleaned<numberIterations_) {
02418               handler_->message(CLP_SIMPLEX_GIVINGUP,messages_)
02419                 <<CoinMessageEol;
02420             }
02421           }
02422         } else {
02423           problemStatus_=0; // optimal
02424         }
02425       }
02426     } else {
02427       // see if looks unbounded
02428       if (problemStatus_==-5) {
02429         if (nonLinearCost_->numberInfeasibilities()) {
02430           if (infeasibilityCost_>1.0e18&&perturbation_==101) {
02431             // back off weight
02432             infeasibilityCost_ = 1.0e13;
02433             unPerturb(); // stop any further perturbation
02434           }
02435           //we need infeasiblity cost changed
02436           if (infeasibilityCost_<1.0e20) {
02437             infeasibilityCost_ *= 5.0;
02438             changeMade_++; // say change made
02439             handler_->message(CLP_PRIMAL_WEIGHT,messages_)
02440               <<infeasibilityCost_
02441               <<CoinMessageEol;
02442             // put back original costs and then check
02443             createRim(4);
02444             gutsOfSolution(NULL,NULL);
02445             checkComplementarity(info,rowArray_[2],rowArray_[3]);
02446             problemStatus_=-1; //continue
02447           } else {
02448             // say unbounded
02449             problemStatus_ = 2;
02450           }
02451         } else {
02452           // say unbounded
02453           problemStatus_ = 2;
02454         } 
02455       } else {
02456         if(type==3&&problemStatus_!=-5)
02457           unflag(); // odd
02458         // carry on
02459         problemStatus_ = -1;
02460       }
02461     }
02462   } else {
02463     // don't update solution
02464     problemStatus_=-1;
02465   }
02466   if (type==0||type==1) {
02467     if (type!=1||!saveStatus_) {
02468       // create save arrays
02469       delete [] saveStatus_;
02470       delete [] savedSolution_;
02471       saveStatus_ = new unsigned char [numberRows_+numberColumns_];
02472       savedSolution_ = new double [numberRows_+numberColumns_];
02473     }
02474     // save arrays
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   // restore weights (if saved) - also recompute infeasibility list
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; // unknown
02488   }
02489   if (saveThreshold) {
02490     // use default at present
02491     factorization_->sparseThreshold(0);
02492     factorization_->goSparse();
02493   }
02494   lastGoodIteration_ = numberIterations_;
02495 }

int ClpSimplexPrimalQuadratic::whileIterating ClpQuadraticInfo info  ) 
 

Main part. phase - 0 normal, 1 getting complementary solution, 2 getting basic solution.

Definition at line 733 of file ClpSimplexPrimalQuadratic.cpp.

References ClpQuadraticInfo::basicRow(), CoinIndexedVector::checkClear(), checkComplementarity(), CoinIndexedVector::clear(), createDjs(), ClpQuadraticInfo::createGradient(), ClpQuadraticInfo::crucialSj(), ClpQuadraticInfo::currentPhase(), CoinIndexedVector::denseVector(), ClpPackedMatrix::getElements(), CoinIndexedVector::getIndices(), ClpPackedMatrix::getIndices(), CoinIndexedVector::getNumElements(), ClpPackedMatrix::getVectorStarts(), ClpQuadraticInfo::gradient(), ClpSimplex::housekeeping(), ClpQuadraticInfo::impliedSj(), ClpQuadraticInfo::infeasCost(), ClpSimplex::isColumn(), CoinMessageHandler::logLevel(), CoinMessageHandler::message(), ClpNonLinearCost::numberInfeasibilities(), ClpQuadraticInfo::numberQuadraticRows(), ClpQuadraticInfo::numberXColumns(), ClpQuadraticInfo::numberXRows(), ClpSimplexPrimal::primalColumn(), ClpSimplexPrimal::primalRay(), primalRow(), ClpQuadraticInfo::sequenceIn(), ClpSimplex::sequenceWithin(), ClpQuadraticInfo::setCrucialSj(), ClpSimplex::setFlagged(), ClpNonLinearCost::setOne(), ClpNonLinearCost::setOneOutgoing(), ClpQuadraticInfo::setSequenceIn(), ClpSimplex::unpack(), ClpSimplexPrimal::updatePrimalsInPrimal(), and ClpPrimalColumnPivot::updateWeights().

Referenced by primalQuadratic2().

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   // Make list of implied sj
00748   // And backward pointers to basic variables
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   // status stays at -1 while iterating, >=0 finished, -2 to invert
00768   // status -3 to go to top without an invert
00769   while (problemStatus_==-1) {
00770     if (info->crucialSj()<0&&factorization_->pivots()>=10) {
00771       returnCode =-2; // refactorize
00772       break;
00773     }
00774 #ifdef CLP_DEBUG
00775     {
00776       int i;
00777       // not [1] as has information
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     // choose column to come in
00788     // can use pivotRow_ to update weights
00789     // pass in list of cost changes so can do row updates (rowArray_[1])
00790     // NOTE rowArray_[0] is used by computeDuals which is a 
00791     // slow way of getting duals but might be used 
00792     // Initially Dantzig and look at s variables
00793     // Only do if one not already chosen
00794     int cleanupIteration;
00795     if (nextSequenceIn<0) {
00796       cleanupIteration=0;
00797       if (phase==2) {
00798         // values pass
00799         // get next
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; // so no updates
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       // we found a pivot column
00861       int chosen = sequenceIn_;
00862       // do second half of iteration
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         // we found a pivot column
00875         // update the incoming column
00876         sequenceIn_=chosen;
00877         chosen=-1;
00878         unpack(rowArray_[1]);
00879         // compute dj in case linear
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           // may need to re-do row of basis
00909           int * impliedSj = info->impliedSj();
00910           if (impliedSj[iSequence]>=0) {
00911             // mark as valid
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         // Take out elements in implied Sj rows
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           // move back to a version of primalColumn?
00959           valueIn_=solution_[sequenceIn_];
00960           // should keep pivot row of crucialSj as well (speed)
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                 // see which way to go
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             //assert(tj);
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           // not clean up
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             // Set dj as value of slack
01013             crucialSj = sequenceIn_+ numberQuadraticRows+numberXColumns; // sj which should go to 0.0
01014           } else {
01015             // Set dj as value of pi
01016             int iRow = sequenceIn_-numberColumns_;
01017             crucialSj = iRow+numberXColumns; // pi which should go to 0.0
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         // save reduced cost
01027         //double saveDj = dualIn_;
01028         // do ratio test and re-compute dj
01029         // Note second parameter long enough for columns
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           // try other way
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           // If sj out AND not gone out since last invert then add back
01048           // if stable replace in basis
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; // force re-factorization
01064               info->setSequenceIn(sequenceIn_);
01065             }
01066           }
01067           // if no pivots, bad update but reasonable alpha - take and invert
01068           if (updateStatus==2&&
01069               lastGoodIteration_==numberIterations_&&fabs(alpha_)>1.0e-5)
01070             updateStatus=4;
01071           if (updateStatus==1||updateStatus==4) {
01072             // slight error
01073             if (factorization_->pivots()>5||updateStatus==4) {
01074               returnCode=-3;
01075             }
01076           } else if (updateStatus==2) {
01077             // major error
01078             // Reset sequenceIn_
01079             // sequenceIn_=saveSequenceIn;
01080             nextSequenceIn=saveSequenceInInfo;
01081             info->setCrucialSj(saveCrucialSjInfo);
01082             if (saveCrucialSjInfo<0&&!phase)
01083               nextSequenceIn=-1;
01084             pivotRow_=-1;
01085             // better to have small tolerance even if slower
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             // later we may need to unwind more e.g. fake bounds
01094             if(lastGoodIteration_ != numberIterations_||factorization_->pivots()) {
01095               rowArray_[1]->clear();
01096               pivotRow_=-1;
01097               returnCode=-4;
01098               // retry on return
01099               if (info->crucialSj()>=0)
01100                 nextSequenceIn = sequenceIn_;
01101               break;
01102             } else {
01103               // need to reject something
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_; // say be more cautious
01110               rowArray_[1]->clear();
01111               pivotRow_=-1;
01112               returnCode = -5;
01113               break;
01114               
01115             }
01116           } else if (updateStatus==3) {
01117             // out of memory
01118             // increase space if not many iterations
01119             if (factorization_->pivots()<
01120                 0.5*factorization_->maximumPivots()&&
01121                 factorization_->pivots()<200)
01122               factorization_->areaFactor(
01123                                          factorization_->areaFactor() * 1.1);
01124             returnCode =-2; // factorize now
01125           }
01126           // here do part of steepest - ready for next iteration
01127           primalColumnPivot_->updateWeights(rowArray_[1]);
01128         } else {
01129           if (pivotRow_==-1) {
01130             // no outgoing row is valid
01131             rowArray_[0]->clear();
01132             if (!factorization_->pivots()) {
01133               returnCode = 2; //say looks unbounded
01134               // do ray
01135               primalRay(rowArray_[1]);
01136             } else {
01137               returnCode = 4; //say looks unbounded but has iterated
01138             }
01139             break;
01140           } else {
01141             // flipping from bound to bound
01142           }
01143         }
01144 
01145 
01146         // update primal solution
01147 
01148         double objectiveChange=0.0;
01149         // Cost on pivot row may change - may need to change dualIn
01150         double oldCost=0.0;
01151         if (pivotRow_>=0)
01152           oldCost = cost(pivotVariable_[pivotRow_]);
01153         // rowArray_[1] is not empty - used to update djs
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           // as if from upper bound
01160           if (sequenceIn_!=sequenceOut_) {
01161             // variable becoming basic
01162             valueIn_ -= fabs(theta_);
01163           } else {
01164             valueIn_=lowerIn_;
01165           }
01166         } else {
01167           // as if from lower bound
01168           if (sequenceIn_!=sequenceOut_) {
01169             // variable becoming basic
01170             valueIn_ += fabs(theta_);
01171           } else {
01172             valueIn_=upperIn_;
01173           }
01174         }
01175         objectiveChange += dualIn_*(valueIn_-oldValue);
01176         // outgoing
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             // really free but going to zero
01187             lowerValue=0.0;
01188             upperValue=0.0;
01189           }
01190           assert(valueOut_>=lowerValue-primalTolerance_&&
01191                  valueOut_<=upperValue+primalTolerance_);
01192           // may not be exactly at bound and bounds may have changed
01193 #if 1
01194           // Make sure outgoing looks feasible
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         // change cost and bounds on incoming if primal
01223         if (sequenceIn_==sequenceOut_&&(lowerOut_!=lowerIn_||upperOut_!=upperIn_)) {
01224           // linear variable superbasic
01225           setStatus(sequenceOut_,superBasic);
01226         }
01227         nonLinearCost_->setOne(sequenceIn_,valueIn_); 
01228         int whatNext=housekeeping(objectiveChange);
01229         // and again as housekeeping may have changed
01230         if (sequenceIn_==sequenceOut_&&(lowerOut_!=lowerIn_||upperOut_!=upperIn_)) {
01231           // linear variable superbasic
01232           setStatus(sequenceOut_,superBasic);
01233         }
01234         // And update backward pointers to basic variables
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           // really free but going to zero
01249           setStatus(sequenceOut_,isFree);
01250           if (sequenceOut_==info->crucialSj())
01251             info->setCrucialSj(-1);
01252         } else if (info->crucialSj()>=0) {
01253           // Just possible crucialSj still in but original out again
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; // refactorize
01267         } else if (whatNext==2) {
01268           // maximum iterations or equivalent
01269           returnCode=3;
01270         } else if(numberIterations_ == lastGoodIteration_
01271                   + 2 * factorization_->maximumPivots()) {
01272           // done a lot of flips - be safe
01273           returnCode =-2; // refactorize
01274         }
01275         // may need to go round again
01276         cleanupIteration = 1;
01277         // may not be correct on second time
01278         if (result&&(returnCode==-1||returnCode==-2||returnCode==-3)) {
01279           int crucialSj=info->crucialSj();
01280           if (sequenceOut_<numberXColumns) {
01281             chosen =sequenceOut_ + numberQuadraticRows + numberXColumns; // sj variable
01282           } else if (sequenceOut_>=numberColumns_) {
01283             // Does this mean we can change pi
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             // pi out
01293             chosen = sequenceOut_-numberXColumns+numberColumns_;
01294           } else {
01295             // sj out
01296             chosen = sequenceOut_-numberQuadraticRows-numberXColumns;
01297           }
01298           // But double check as original incoming might have gone out
01299           if (chosen==crucialSj) {
01300             chosen=-1;
01301             break; // means original has gone out
01302           }
01303           rowArray_[0]->clear();
01304           columnArray_[0]->clear();
01305           if (returnCode==-2) {
01306             // factorization
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         // something flagged - continue;
01318       } else if (returnCode==2) {
01319         problemStatus_=-5; // looks unbounded
01320       } else if (returnCode==4) {
01321         problemStatus_=-2; // looks unbounded but has iterated
01322       } else if (returnCode!=-1) {
01323         assert(returnCode==3);
01324         problemStatus_=3;
01325       }
01326     } else {
01327       // no pivot column
01328 #ifdef CLP_DEBUG
01329       if (handler_->logLevel()&32)
01330         printf("** no column pivot\n");
01331 #endif
01332       if (nonLinearCost_->numberInfeasibilities())
01333         problemStatus_=-4; // might be infeasible 
01334       returnCode=0;
01335       break;
01336     }
01337   }
01338   info->setSequenceIn(nextSequenceIn);
01339   return returnCode;
01340 }


The documentation for this class was generated from the following files:
Generated on Wed Dec 3 14:37:50 2003 for CLP by doxygen 1.3.5