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

ClpSimplex.cpp

00001 // Copyright (C) 2002, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 
00004 
00005 
00006 
00007 #include "CoinPragma.hpp"
00008 
00009 #include <math.h>
00010 
00011 #include "CoinHelperFunctions.hpp"
00012 #include "ClpSimplex.hpp"
00013 #include "ClpFactorization.hpp"
00014 #include "ClpPackedMatrix.hpp"
00015 #include "CoinIndexedVector.hpp"
00016 #include "ClpDualRowDantzig.hpp"
00017 #include "ClpDualRowSteepest.hpp"
00018 #include "ClpPrimalColumnDantzig.hpp"
00019 #include "ClpPrimalColumnSteepest.hpp"
00020 #include "ClpNonLinearCost.hpp"
00021 #include "ClpMessage.hpp"
00022 #include "ClpLinearObjective.hpp"
00023 #include <cfloat>
00024 
00025 #include <string>
00026 #include <stdio.h>
00027 #include <iostream>
00028 //#############################################################################
00029 
00030 ClpSimplex::ClpSimplex () :
00031 
00032   ClpModel(),
00033   columnPrimalInfeasibility_(0.0),
00034   rowPrimalInfeasibility_(0.0),
00035   columnPrimalSequence_(-2),
00036   rowPrimalSequence_(-2), 
00037   columnDualInfeasibility_(0.0),
00038   rowDualInfeasibility_(0.0),
00039   columnDualSequence_(-2),
00040   rowDualSequence_(-2),
00041   primalToleranceToGetOptimal_(-1.0),
00042   remainingDualInfeasibility_(0.0),
00043   largeValue_(1.0e15),
00044   largestPrimalError_(0.0),
00045   largestDualError_(0.0),
00046   largestSolutionError_(0.0),
00047   dualBound_(1.0e10),
00048   alpha_(0.0),
00049   theta_(0.0),
00050   lowerIn_(0.0),
00051   valueIn_(0.0),
00052   upperIn_(0.0),
00053   dualIn_(0.0),
00054   lowerOut_(-1),
00055   valueOut_(-1),
00056   upperOut_(-1),
00057   dualOut_(-1),
00058   dualTolerance_(0.0),
00059   primalTolerance_(0.0),
00060   sumDualInfeasibilities_(0.0),
00061   sumPrimalInfeasibilities_(0.0),
00062   infeasibilityCost_(1.0e10),
00063   sumOfRelaxedDualInfeasibilities_(0.0),
00064   sumOfRelaxedPrimalInfeasibilities_(0.0),
00065   lower_(NULL),
00066   rowLowerWork_(NULL),
00067   columnLowerWork_(NULL),
00068   upper_(NULL),
00069   rowUpperWork_(NULL),
00070   columnUpperWork_(NULL),
00071   cost_(NULL),
00072   rowObjectiveWork_(NULL),
00073   objectiveWork_(NULL),
00074   sequenceIn_(-1),
00075   directionIn_(-1),
00076   sequenceOut_(-1),
00077   directionOut_(-1),
00078   pivotRow_(-1),
00079   lastGoodIteration_(-100),
00080   dj_(NULL),
00081   rowReducedCost_(NULL),
00082   reducedCostWork_(NULL),
00083   solution_(NULL),
00084   rowActivityWork_(NULL),
00085   columnActivityWork_(NULL),
00086   numberDualInfeasibilities_(0),
00087   numberDualInfeasibilitiesWithoutFree_(0),
00088   numberPrimalInfeasibilities_(100),
00089   numberRefinements_(0),
00090   pivotVariable_(NULL),
00091   factorization_(NULL),
00092   rowScale_(NULL),
00093   savedSolution_(NULL),
00094   columnScale_(NULL),
00095   scalingFlag_(3),
00096   numberTimesOptimal_(0),
00097   changeMade_(1),
00098   algorithm_(0),
00099   forceFactorization_(-1),
00100   perturbation_(100),
00101   nonLinearCost_(NULL),
00102   specialOptions_(0),
00103   lastBadIteration_(-999999),
00104   numberFake_(0),
00105   progressFlag_(0),
00106   firstFree_(-1),
00107   incomingInfeasibility_(1.0),
00108   allowedInfeasibility_(10.0),
00109   progress_(NULL)
00110 {
00111   int i;
00112   for (i=0;i<6;i++) {
00113     rowArray_[i]=NULL;
00114     columnArray_[i]=NULL;
00115   }
00116   saveStatus_=NULL;
00117   // get an empty factorization so we can set tolerances etc
00118   factorization_ = new ClpFactorization();
00119   // Say sparse
00120   factorization_->sparseThreshold(1);
00121   // say Steepest pricing
00122   dualRowPivot_ = new ClpDualRowSteepest();
00123   // say Steepest pricing
00124   primalColumnPivot_ = new ClpPrimalColumnSteepest();
00125   solveType_=1; // say simplex based life form
00126   
00127 }
00128 
00129 // Subproblem constructor
00130 ClpSimplex::ClpSimplex ( const ClpModel * rhs,
00131                      int numberRows, const int * whichRow,
00132                      int numberColumns, const int * whichColumn,
00133                      bool dropNames, bool dropIntegers)
00134   : ClpModel(rhs, numberRows, whichRow,
00135              numberColumns,whichColumn,dropNames,dropIntegers),
00136   columnPrimalInfeasibility_(0.0),
00137   rowPrimalInfeasibility_(0.0),
00138   columnPrimalSequence_(-2),
00139   rowPrimalSequence_(-2), 
00140   columnDualInfeasibility_(0.0),
00141   rowDualInfeasibility_(0.0),
00142   columnDualSequence_(-2),
00143   rowDualSequence_(-2),
00144   primalToleranceToGetOptimal_(-1.0),
00145   remainingDualInfeasibility_(0.0),
00146   largeValue_(1.0e15),
00147   largestPrimalError_(0.0),
00148   largestDualError_(0.0),
00149   largestSolutionError_(0.0),
00150   dualBound_(1.0e10),
00151   alpha_(0.0),
00152   theta_(0.0),
00153   lowerIn_(0.0),
00154   valueIn_(0.0),
00155   upperIn_(0.0),
00156   dualIn_(0.0),
00157   lowerOut_(-1),
00158   valueOut_(-1),
00159   upperOut_(-1),
00160   dualOut_(-1),
00161   dualTolerance_(0.0),
00162   primalTolerance_(0.0),
00163   sumDualInfeasibilities_(0.0),
00164   sumPrimalInfeasibilities_(0.0),
00165   infeasibilityCost_(1.0e10),
00166   sumOfRelaxedDualInfeasibilities_(0.0),
00167   sumOfRelaxedPrimalInfeasibilities_(0.0),
00168   lower_(NULL),
00169   rowLowerWork_(NULL),
00170   columnLowerWork_(NULL),
00171   upper_(NULL),
00172   rowUpperWork_(NULL),
00173   columnUpperWork_(NULL),
00174   cost_(NULL),
00175   rowObjectiveWork_(NULL),
00176   objectiveWork_(NULL),
00177   sequenceIn_(-1),
00178   directionIn_(-1),
00179   sequenceOut_(-1),
00180   directionOut_(-1),
00181   pivotRow_(-1),
00182   lastGoodIteration_(-100),
00183   dj_(NULL),
00184   rowReducedCost_(NULL),
00185   reducedCostWork_(NULL),
00186   solution_(NULL),
00187   rowActivityWork_(NULL),
00188   columnActivityWork_(NULL),
00189   numberDualInfeasibilities_(0),
00190   numberDualInfeasibilitiesWithoutFree_(0),
00191   numberPrimalInfeasibilities_(100),
00192   numberRefinements_(0),
00193   pivotVariable_(NULL),
00194   factorization_(NULL),
00195   rowScale_(NULL),
00196   savedSolution_(NULL),
00197   columnScale_(NULL),
00198   scalingFlag_(3),
00199   numberTimesOptimal_(0),
00200   changeMade_(1),
00201   algorithm_(0),
00202   forceFactorization_(-1),
00203   perturbation_(100),
00204   nonLinearCost_(NULL),
00205   specialOptions_(0),
00206   lastBadIteration_(-999999),
00207   numberFake_(0),
00208   progressFlag_(0),
00209   firstFree_(-1),
00210   incomingInfeasibility_(1.0),
00211   allowedInfeasibility_(10.0),
00212   progress_(NULL)
00213 {
00214   int i;
00215   for (i=0;i<6;i++) {
00216     rowArray_[i]=NULL;
00217     columnArray_[i]=NULL;
00218   }
00219   saveStatus_=NULL;
00220   // get an empty factorization so we can set tolerances etc
00221   factorization_ = new ClpFactorization();
00222   // say Steepest pricing
00223   dualRowPivot_ = new ClpDualRowSteepest();
00224   // say Steepest pricing
00225   primalColumnPivot_ = new ClpPrimalColumnSteepest();
00226   solveType_=1; // say simplex based life form
00227   
00228 }
00229 
00230 //-----------------------------------------------------------------------------
00231 
00232 ClpSimplex::~ClpSimplex ()
00233 {
00234   gutsOfDelete(0);
00235   delete nonLinearCost_;
00236 }
00237 //#############################################################################
00238 void ClpSimplex::setLargeValue( double value) 
00239 {
00240   if (value>0.0&&value<COIN_DBL_MAX)
00241     largeValue_=value;
00242 }
00243 int
00244 ClpSimplex::gutsOfSolution ( double * givenDuals,
00245                              const double * givenPrimals,
00246                              bool valuesPass)
00247 {
00248 
00249 
00250   // if values pass, save values of basic variables
00251   double * save = NULL;
00252   double oldValue=0.0;
00253   if (valuesPass) {
00254     assert(algorithm_>0); // only primal at present
00255     assert(nonLinearCost_);
00256     int iRow;
00257     checkPrimalSolution( rowActivityWork_, columnActivityWork_);
00258     // get correct bounds on all variables
00259     nonLinearCost_->checkInfeasibilities(primalTolerance_);
00260     oldValue = nonLinearCost_->largestInfeasibility();
00261     save = new double[numberRows_];
00262     for (iRow=0;iRow<numberRows_;iRow++) {
00263       int iPivot=pivotVariable_[iRow];
00264       save[iRow] = solution_[iPivot];
00265     }
00266   }
00267   // do work
00268   computePrimals(rowActivityWork_, columnActivityWork_);
00269   // If necessary - override results
00270   if (givenPrimals) {
00271     memcpy(columnActivityWork_,givenPrimals,numberColumns_*sizeof(double));
00272     memset(rowActivityWork_,0,numberRows_*sizeof(double));
00273     times(-1.0,columnActivityWork_,rowActivityWork_);
00274   }
00275   double objectiveModification = 0.0;
00276   if (algorithm_>0&&nonLinearCost_!=NULL) {
00277     // primal algorithm
00278     // get correct bounds on all variables
00279     // If  4 bit set - Force outgoing variables to exact bound (primal)
00280     if ((specialOptions_&4)==0)
00281       nonLinearCost_->checkInfeasibilities(primalTolerance_);
00282     else
00283       nonLinearCost_->checkInfeasibilities(0.0);
00284     objectiveModification += nonLinearCost_->changeInCost();
00285     if (nonLinearCost_->numberInfeasibilities())
00286       handler_->message(CLP_SIMPLEX_NONLINEAR,messages_)
00287         <<nonLinearCost_->changeInCost()
00288         <<nonLinearCost_->numberInfeasibilities()
00289         <<CoinMessageEol;
00290   }
00291   if (valuesPass) {
00292 #ifdef CLP_DEBUG
00293     std::cout<<"Largest given infeasibility "<<oldValue
00294              <<" now "<<nonLinearCost_->largestInfeasibility()<<std::endl;
00295 #endif
00296     int numberOut=0;
00297     if (oldValue<incomingInfeasibility_
00298         &&nonLinearCost_->largestInfeasibility()>
00299         max(incomingInfeasibility_,allowedInfeasibility_)||
00300         largestPrimalError_>1.0e-3) {
00301       printf("Original largest infeas %g, now %g, primalError %g\n",
00302              oldValue,nonLinearCost_->largestInfeasibility(),
00303              largestPrimalError_);
00304       // throw out up to 1000 structurals
00305       int iRow;
00306       int * sort = new int[numberRows_];
00307       // first put back solution and store difference
00308       for (iRow=0;iRow<numberRows_;iRow++) {
00309         int iPivot=pivotVariable_[iRow];
00310         double difference = fabs(solution_[iPivot]-save[iRow]);
00311         solution_[iPivot]=save[iRow];
00312         save[iRow]=difference;
00313       }
00314       for (iRow=0;iRow<numberRows_;iRow++) {
00315         int iPivot=pivotVariable_[iRow];
00316 
00317         if (iPivot<numberColumns_) {
00318           // column
00319           double difference= save[iRow];
00320           if (difference>1.0e-4) {
00321             sort[numberOut]=iPivot;
00322             save[numberOut++]=difference;
00323           }
00324         }
00325       }
00326       CoinSort_2(save, save + numberOut, sort,
00327                  CoinFirstGreater_2<double, int>());
00328       numberOut = min(1000,numberOut);
00329       for (iRow=0;iRow<numberOut;iRow++) {
00330         int iColumn=sort[iRow];
00331         setColumnStatus(iColumn,superBasic);
00332 
00333       }
00334       delete [] sort;
00335     }
00336     delete [] save;
00337     if (numberOut)
00338       return numberOut;
00339   }
00340 
00341   computeDuals(givenDuals);
00342 
00343   // now check solutions
00344   checkPrimalSolution( rowActivityWork_, columnActivityWork_);
00345   objectiveValue_ += objectiveModification;
00346   checkDualSolution();
00347   if (handler_->logLevel()>3||(largestPrimalError_>1.0e-2||
00348                                largestDualError_>1.0e-2)) 
00349     handler_->message(CLP_SIMPLEX_ACCURACY,messages_)
00350       <<largestPrimalError_
00351       <<largestDualError_
00352       <<CoinMessageEol;
00353   // Switch off false values pass indicator
00354   if (!valuesPass&&algorithm_>0)
00355     firstFree_ = -1;
00356   return 0;
00357 }
00358 void
00359 ClpSimplex::computePrimals ( const double * rowActivities,
00360                                      const double * columnActivities)
00361 {
00362 
00363   //work space
00364   CoinIndexedVector  * workSpace = rowArray_[0];
00365 
00366   CoinIndexedVector arrayVector;
00367   arrayVector.reserve(numberRows_+1);
00368   CoinIndexedVector previousVector;
00369   previousVector.reserve(numberRows_+1);
00370 
00371   // accumulate non basic stuff 
00372 
00373   int iRow;
00374   // order is this way for scaling
00375   // Use whole matrix every time to make it easier for ClpMatrixBase
00376   // So zero out basic
00377   if (columnActivities!=columnActivityWork_)
00378     ClpDisjointCopyN(columnActivities,numberColumns_,columnActivityWork_);
00379   if (rowActivities!=rowActivityWork_)
00380     ClpDisjointCopyN(rowActivities,numberRows_,rowActivityWork_);
00381   for (iRow=0;iRow<numberRows_;iRow++) {
00382     int iPivot=pivotVariable_[iRow];
00383     solution_[iPivot] = 0.0;
00384   }
00385   double * array = arrayVector.denseVector();
00386   times(-1.0,columnActivityWork_,array);
00387 
00388   int * index = arrayVector.getIndices();
00389   int number=0;
00390   for (iRow=0;iRow<numberRows_;iRow++) {
00391     double value = array[iRow] + rowActivityWork_[iRow];
00392     if (value) {
00393       array[iRow]=value;
00394       index[number++]=iRow;
00395     } else {
00396       array[iRow]=0.0;
00397     }
00398   }
00399   arrayVector.setNumElements(number);
00400 
00401   // Ftran adjusted RHS and iterate to improve accuracy
00402   double lastError=COIN_DBL_MAX;
00403   int iRefine;
00404   double * work = workSpace->denseVector();
00405   CoinIndexedVector * thisVector = &arrayVector;
00406   CoinIndexedVector * lastVector = &previousVector;
00407   factorization_->updateColumn(workSpace,thisVector);
00408   bool goodSolution=true;
00409   for (iRefine=0;iRefine<numberRefinements_+1;iRefine++) {
00410 
00411     int numberIn = thisVector->getNumElements();
00412     int * indexIn = thisVector->getIndices();
00413     double * arrayIn = thisVector->denseVector();
00414     // put solution in correct place
00415     int j;
00416     for (j=0;j<numberIn;j++) {
00417       iRow = indexIn[j];
00418       int iPivot=pivotVariable_[iRow];
00419       solution_[iPivot] = arrayIn[iRow];
00420     }
00421     // check Ax == b  (for all)
00422     times(-1.0,columnActivityWork_,work);
00423     largestPrimalError_=0.0;
00424     double multiplier = 131072.0;
00425     for (iRow=0;iRow<numberRows_;iRow++) {
00426       double value = work[iRow] + rowActivityWork_[iRow];
00427       work[iRow] = value*multiplier;
00428       if (fabs(value)>largestPrimalError_) {
00429         largestPrimalError_=fabs(value);
00430       }
00431     }
00432     if (largestPrimalError_>=lastError) {
00433       // restore
00434       CoinIndexedVector * temp = thisVector;
00435       thisVector = lastVector;
00436       lastVector=temp;
00437       goodSolution=false;
00438       break;
00439     }
00440     if (iRefine<numberRefinements_&&largestPrimalError_>1.0e-10) {
00441       // try and make better
00442       // save this
00443       CoinIndexedVector * temp = thisVector;
00444       thisVector = lastVector;
00445       lastVector=temp;
00446       int * indexOut = thisVector->getIndices();
00447       int number=0;
00448       array = thisVector->denseVector();
00449       thisVector->clear();
00450       for (iRow=0;iRow<numberRows_;iRow++) {
00451         double value = work[iRow];
00452         if (value) {
00453           array[iRow]=value;
00454           indexOut[number++]=iRow;
00455           work[iRow]=0.0;
00456         }
00457       }
00458       thisVector->setNumElements(number);
00459       lastError=largestPrimalError_;
00460       factorization_->updateColumn(workSpace,thisVector);
00461       multiplier = 1.0/multiplier;
00462       double * previous = lastVector->denseVector();
00463       number=0;
00464       for (iRow=0;iRow<numberRows_;iRow++) {
00465         double value = previous[iRow] + multiplier*array[iRow];
00466         if (value) {
00467           array[iRow]=value;
00468           indexOut[number++]=iRow;
00469         } else {
00470           array[iRow]=0.0;
00471         }
00472       }
00473       thisVector->setNumElements(number);
00474     } else {
00475       break;
00476     }
00477   }
00478 
00479   // solution as accurate as we are going to get
00480   ClpFillN(work,numberRows_,0.0);
00481   if (!goodSolution) {
00482     array = thisVector->denseVector();
00483     // put solution in correct place
00484     for (iRow=0;iRow<numberRows_;iRow++) {
00485       int iPivot=pivotVariable_[iRow];
00486       solution_[iPivot] = array[iRow];
00487     }
00488   }
00489 }
00490 // now dual side
00491 void
00492 ClpSimplex::computeDuals(double * givenDjs)
00493 {
00494   //work space
00495   CoinIndexedVector  * workSpace = rowArray_[0];
00496 
00497   CoinIndexedVector arrayVector;
00498   arrayVector.reserve(numberRows_+1);
00499   CoinIndexedVector previousVector;
00500   previousVector.reserve(numberRows_+1);
00501 
00502 
00503   int iRow;
00504 #ifdef CLP_DEBUG
00505   workSpace->checkClear();
00506 #endif
00507   double * array = arrayVector.denseVector();
00508   int * index = arrayVector.getIndices();
00509   int number=0;
00510   if (!givenDjs) {
00511     for (iRow=0;iRow<numberRows_;iRow++) {
00512       int iPivot=pivotVariable_[iRow];
00513       double value = cost_[iPivot];
00514       if (value) {
00515         array[iRow]=value;
00516         index[number++]=iRow;
00517       }
00518     }
00519   } else {
00520     // dual values pass - djs may not be zero
00521     for (iRow=0;iRow<numberRows_;iRow++) {
00522       int iPivot=pivotVariable_[iRow];
00523       // make sure zero if done
00524       if (!pivoted(iPivot))
00525         givenDjs[iPivot]=0.0;
00526       double value =cost_[iPivot]-givenDjs[iPivot];
00527       if (value) {
00528         array[iRow]=value;
00529         index[number++]=iRow;
00530       }
00531     }
00532   }
00533   arrayVector.setNumElements(number);
00534 
00535   // Btran basic costs and get as accurate as possible
00536   double lastError=COIN_DBL_MAX;
00537   int iRefine;
00538   double * work = workSpace->denseVector();
00539   CoinIndexedVector * thisVector = &arrayVector;
00540   CoinIndexedVector * lastVector = &previousVector;
00541   factorization_->updateColumnTranspose(workSpace,thisVector);
00542 
00543   for (iRefine=0;iRefine<numberRefinements_+1;iRefine++) {
00544     // check basic reduced costs zero
00545     largestDualError_=0.0;
00546     // would be faster to do just for basic but this reduces code
00547     ClpDisjointCopyN(objectiveWork_,numberColumns_,reducedCostWork_);
00548     transposeTimes(-1.0,array,reducedCostWork_);
00549     if (!givenDjs) {
00550       for (iRow=0;iRow<numberRows_;iRow++) {
00551         int iPivot=pivotVariable_[iRow];
00552         double value;
00553         if (iPivot>=numberColumns_) {
00554           // slack
00555           value = rowObjectiveWork_[iPivot-numberColumns_]
00556             + array[iPivot-numberColumns_];
00557         } else {
00558           // column
00559           value = reducedCostWork_[iPivot];
00560         }
00561         work[iRow]=value;
00562         if (fabs(value)>largestDualError_) {
00563           largestDualError_=fabs(value);
00564         }
00565       }
00566     } else {
00567       for (iRow=0;iRow<numberRows_;iRow++) {
00568         int iPivot=pivotVariable_[iRow];
00569         if (iPivot>=numberColumns_) {
00570           // slack
00571           work[iRow] = rowObjectiveWork_[iPivot-numberColumns_]
00572             + array[iPivot-numberColumns_]-givenDjs[iPivot];
00573         } else {
00574           // column
00575           work[iRow] = reducedCostWork_[iPivot]- givenDjs[iPivot];
00576         }
00577         if (fabs(work[iRow])>largestDualError_) {
00578           largestDualError_=fabs(work[iRow]);
00579           //assert (largestDualError_<1.0e-7);
00580           //if (largestDualError_>1.0e-7)
00581           //printf("large dual error %g\n",largestDualError_);
00582         }
00583       }
00584     }
00585     if (largestDualError_>=lastError) {
00586       // restore
00587       CoinIndexedVector * temp = thisVector;
00588       thisVector = lastVector;
00589       lastVector=temp;
00590       break;
00591     }
00592     if (iRefine<numberRefinements_&&largestDualError_>1.0e-10
00593         &&!givenDjs) {
00594       // try and make better
00595       // save this
00596       CoinIndexedVector * temp = thisVector;
00597       thisVector = lastVector;
00598       lastVector=temp;
00599       int * indexOut = thisVector->getIndices();
00600       int number=0;
00601       array = thisVector->denseVector();
00602       thisVector->clear();
00603       double multiplier = 131072.0;
00604       for (iRow=0;iRow<numberRows_;iRow++) {
00605         double value = multiplier*work[iRow];
00606         if (value) {
00607           array[iRow]=value;
00608           indexOut[number++]=iRow;
00609           work[iRow]=0.0;
00610         }
00611         work[iRow]=0.0;
00612       }
00613       thisVector->setNumElements(number);
00614       lastError=largestDualError_;
00615       factorization_->updateColumnTranspose(workSpace,thisVector);
00616       multiplier = 1.0/multiplier;
00617       double * previous = lastVector->denseVector();
00618       number=0;
00619       for (iRow=0;iRow<numberRows_;iRow++) {
00620         double value = previous[iRow] + multiplier*array[iRow];
00621         if (value) {
00622           array[iRow]=value;
00623           indexOut[number++]=iRow;
00624         } else {
00625           array[iRow]=0.0;
00626         }
00627       }
00628       thisVector->setNumElements(number);
00629     } else {
00630       break;
00631     }
00632   }
00633   ClpFillN(work,numberRows_,0.0);
00634   // now look at dual solution
00635   array = thisVector->denseVector();
00636   for (iRow=0;iRow<numberRows_;iRow++) {
00637     // slack
00638     double value = array[iRow];
00639     dual_[iRow]=value;
00640     value += rowObjectiveWork_[iRow];
00641     rowReducedCost_[iRow]=value;
00642   }
00643   ClpDisjointCopyN(objectiveWork_,numberColumns_,reducedCostWork_);
00644   transposeTimes(-1.0,dual_,reducedCostWork_);
00645   // If necessary - override results
00646   if (givenDjs) {
00647     // restore accurate duals
00648     memcpy(givenDjs,dj_,(numberRows_+numberColumns_)*sizeof(double));
00649   }
00650 
00651 }
00652 /* Given an existing factorization computes and checks 
00653    primal and dual solutions.  Uses input arrays for variables at
00654    bounds.  Returns feasibility states */
00655 int ClpSimplex::getSolution ( const double * rowActivities,
00656                                const double * columnActivities)
00657 {
00658   if (!factorization_->status()) {
00659     // put in standard form
00660     createRim(7+8+16+32);
00661     // do work
00662     gutsOfSolution ( NULL,NULL);
00663     // release extra memory
00664     deleteRim(0);
00665   }
00666   return factorization_->status();
00667 }
00668 /* Given an existing factorization computes and checks 
00669    primal and dual solutions.  Uses current problem arrays for
00670    bounds.  Returns feasibility states */
00671 int ClpSimplex::getSolution ( )
00672 {
00673   double * rowActivities = new double[numberRows_];
00674   double * columnActivities = new double[numberColumns_];
00675   ClpDisjointCopyN ( rowActivityWork_, numberRows_ , rowActivities);
00676   ClpDisjointCopyN ( columnActivityWork_, numberColumns_ , columnActivities);
00677   int status = getSolution( rowActivities, columnActivities);
00678   delete [] rowActivities;
00679   delete [] columnActivities;
00680   return status;
00681 }
00682 // Factorizes using current basis.  This is for external use
00683 // Return codes are as from ClpFactorization
00684 int ClpSimplex::factorize ()
00685 {
00686   // put in standard form
00687   createRim(7+8+16+32,false);
00688   // do work
00689   int status = internalFactorize(-1);
00690   // release extra memory
00691   deleteRim(0);
00692 
00693   return status;
00694 }
00695 // Clean up status
00696 void 
00697 ClpSimplex::cleanStatus()
00698 {
00699   int iRow,iColumn;
00700   int numberBasic=0;
00701   // make row activities correct
00702   memset(rowActivityWork_,0,numberRows_*sizeof(double));
00703   times(1.0,columnActivityWork_,rowActivityWork_);
00704   if (!status_)
00705     createStatus();
00706   for (iRow=0;iRow<numberRows_;iRow++) {
00707     if (getRowStatus(iRow)==basic) 
00708       numberBasic++;
00709     else {
00710       setRowStatus(iRow,superBasic);
00711       // but put to bound if close
00712       if (fabs(rowActivityWork_[iRow]-rowLowerWork_[iRow])
00713           <=primalTolerance_) {
00714         rowActivityWork_[iRow]=rowLowerWork_[iRow];
00715         setRowStatus(iRow,atLowerBound);
00716       } else if (fabs(rowActivityWork_[iRow]-rowUpperWork_[iRow])
00717                  <=primalTolerance_) {
00718         rowActivityWork_[iRow]=rowUpperWork_[iRow];
00719         setRowStatus(iRow,atUpperBound);
00720       }
00721     }
00722   }
00723   for (iColumn=0;iColumn<numberColumns_;iColumn++) {
00724     if (getColumnStatus(iColumn)==basic) {
00725       if (numberBasic==numberRows_) {
00726         // take out of basis
00727         setColumnStatus(iColumn,superBasic);
00728         // but put to bound if close
00729         if (fabs(columnActivityWork_[iColumn]-columnLowerWork_[iColumn])
00730             <=primalTolerance_) {
00731           columnActivityWork_[iColumn]=columnLowerWork_[iColumn];
00732           setColumnStatus(iColumn,atLowerBound);
00733         } else if (fabs(columnActivityWork_[iColumn]
00734                         -columnUpperWork_[iColumn])
00735                    <=primalTolerance_) {
00736           columnActivityWork_[iColumn]=columnUpperWork_[iColumn];
00737           setColumnStatus(iColumn,atUpperBound);
00738         }
00739       } else 
00740         numberBasic++;
00741     } else {
00742       setColumnStatus(iColumn,superBasic);
00743       // but put to bound if close
00744       if (fabs(columnActivityWork_[iColumn]-columnLowerWork_[iColumn])
00745           <=primalTolerance_) {
00746         columnActivityWork_[iColumn]=columnLowerWork_[iColumn];
00747         setColumnStatus(iColumn,atLowerBound);
00748       } else if (fabs(columnActivityWork_[iColumn]
00749                       -columnUpperWork_[iColumn])
00750                  <=primalTolerance_) {
00751         columnActivityWork_[iColumn]=columnUpperWork_[iColumn];
00752         setColumnStatus(iColumn,atUpperBound);
00753       }
00754     }
00755   }
00756 }
00757 
00758 /* Factorizes using current basis.  
00759       solveType - 1 iterating, 0 initial, -1 external 
00760       - 2 then iterating but can throw out of basis
00761       If 10 added then in primal values pass
00762 */
00763 /* Return codes are as from ClpFactorization unless initial factorization
00764    when total number of singularities is returned */
00765 int ClpSimplex::internalFactorize ( int solveType)
00766 {
00767 
00768   int iRow,iColumn;
00769   int totalSlacks=numberRows_;
00770   if (!status_)
00771     createStatus();
00772 
00773   bool valuesPass=false;
00774   if (solveType>=10) {
00775     valuesPass=true;
00776     solveType -= 10;
00777   }
00778 #ifdef CLP_DEBUG
00779   if (solveType>0) {
00780     int numberFreeIn=0,numberFreeOut=0;
00781     double biggestDj=0.0;
00782     for (iColumn=0;iColumn<numberColumns_;iColumn++) {
00783       switch(getColumnStatus(iColumn)) {
00784 
00785       case basic:
00786         if (columnLower_[iColumn]<-largeValue_
00787             &&columnUpper_[iColumn]>largeValue_) 
00788           numberFreeIn++;
00789         break;
00790       default:
00791         if (columnLower_[iColumn]<-largeValue_
00792             &&columnUpper_[iColumn]>largeValue_) {
00793           numberFreeOut++;
00794           biggestDj = max(fabs(dj_[iColumn]),biggestDj);
00795         }
00796         break;
00797       }
00798     }
00799     if (numberFreeIn+numberFreeOut)
00800       printf("%d in basis, %d out - largest dj %g\n",
00801              numberFreeIn,numberFreeOut,biggestDj);
00802   }
00803 #endif
00804   if (solveType<=0) {
00805     // Make sure everything is clean
00806     for (iRow=0;iRow<numberRows_;iRow++) {
00807       if(getRowStatus(iRow)==isFixed) {
00808         // double check fixed
00809         if (rowUpperWork_[iRow]>rowLowerWork_[iRow])
00810           setRowStatus(iRow,atLowerBound);
00811       } else if (getRowStatus(iRow)==isFree) {
00812         // may not be free after all
00813         if (rowLowerWork_[iRow]>-largeValue_||rowUpperWork_[iRow]<largeValue_)
00814           setRowStatus(iRow,superBasic);
00815       }
00816     }
00817     for (iColumn=0;iColumn<numberColumns_;iColumn++) {
00818       if(getColumnStatus(iColumn)==isFixed) {
00819         // double check fixed
00820         if (columnUpperWork_[iColumn]>columnLowerWork_[iColumn])
00821           setColumnStatus(iColumn,atLowerBound);
00822       } else if (getColumnStatus(iColumn)==isFree) {
00823         // may not be free after all
00824         if (columnLowerWork_[iColumn]>-largeValue_||columnUpperWork_[iColumn]<largeValue_)
00825           setColumnStatus(iColumn,superBasic);
00826       }
00827     }
00828     if (!valuesPass) {
00829       // not values pass so set to bounds
00830       bool allSlack=true;
00831       if (status_) {
00832         for (iRow=0;iRow<numberRows_;iRow++) {
00833           if (getRowStatus(iRow)!=basic) {
00834             allSlack=false;
00835             break;
00836           }
00837         }
00838       }
00839       if (!allSlack) {
00840         // set values from warm start (if sensible)
00841         int numberBasic=0;
00842         for (iRow=0;iRow<numberRows_;iRow++) {
00843           switch(getRowStatus(iRow)) {
00844             
00845           case basic:
00846             numberBasic++;
00847             break;
00848           case atUpperBound:
00849             rowActivityWork_[iRow]=rowUpperWork_[iRow];
00850             if (rowActivityWork_[iRow]>largeValue_) {
00851               if (rowLowerWork_[iRow]>-largeValue_) {
00852                 rowActivityWork_[iRow]=rowLowerWork_[iRow];
00853                 setRowStatus(iRow,atLowerBound);
00854               } else {
00855                 // say free
00856                 setRowStatus(iRow,isFree);
00857                 rowActivityWork_[iRow]=0.0;
00858               }
00859             }
00860             break;
00861           case ClpSimplex::isFixed:
00862           case atLowerBound:
00863             rowActivityWork_[iRow]=rowLowerWork_[iRow];
00864             if (rowActivityWork_[iRow]<-largeValue_) {
00865               if (rowUpperWork_[iRow]<largeValue_) {
00866                 rowActivityWork_[iRow]=rowUpperWork_[iRow];
00867                 setRowStatus(iRow,atUpperBound);
00868               } else {
00869                 // say free
00870                 setRowStatus(iRow,isFree);
00871                 rowActivityWork_[iRow]=0.0;
00872               }
00873             }
00874             break;
00875           case isFree:
00876               break;
00877             // not really free - fall through to superbasic
00878           case superBasic:
00879             if (rowUpperWork_[iRow]>largeValue_) {
00880               if (rowLowerWork_[iRow]>-largeValue_) {
00881                 rowActivityWork_[iRow]=rowLowerWork_[iRow];
00882                 setRowStatus(iRow,atLowerBound);
00883               } else {
00884                 // say free
00885                 setRowStatus(iRow,isFree);
00886                 rowActivityWork_[iRow]=0.0;
00887               }
00888             } else {
00889               if (rowLowerWork_[iRow]>-largeValue_) {
00890                 // set to nearest
00891                 if (fabs(rowActivityWork_[iRow]-rowLowerWork_[iRow])
00892                     <fabs(rowActivityWork_[iRow]-rowLowerWork_[iRow])) {
00893                   rowActivityWork_[iRow]=rowLowerWork_[iRow];
00894                   setRowStatus(iRow,atLowerBound);
00895                 } else {
00896                   rowActivityWork_[iRow]=rowUpperWork_[iRow];
00897                   setRowStatus(iRow,atUpperBound);
00898                 }
00899               } else {
00900                 rowActivityWork_[iRow]=rowUpperWork_[iRow];
00901                 setRowStatus(iRow,atUpperBound);
00902               }
00903             }
00904             break;
00905           }
00906         }
00907         totalSlacks=numberBasic;
00908 
00909         for (iColumn=0;iColumn<numberColumns_;iColumn++) {
00910           switch(getColumnStatus(iColumn)) {
00911             
00912           case basic:
00913             if (numberBasic==numberRows_) {
00914               // take out of basis
00915               if (columnLowerWork_[iColumn]>-largeValue_) {
00916                 if (columnActivityWork_[iColumn]-columnLowerWork_[iColumn]<
00917                     columnUpperWork_[iColumn]-columnActivityWork_[iColumn]) {
00918                   columnActivityWork_[iColumn]=columnLowerWork_[iColumn];
00919                   setColumnStatus(iColumn,atLowerBound);
00920                 } else {
00921                   columnActivityWork_[iColumn]=columnUpperWork_[iColumn];
00922                   setColumnStatus(iColumn,atUpperBound);
00923                 }
00924               } else if (columnUpperWork_[iColumn]<largeValue_) {
00925                 columnActivityWork_[iColumn]=columnUpperWork_[iColumn];
00926                 setColumnStatus(iColumn,atUpperBound);
00927               } else {
00928                 columnActivityWork_[iColumn]=0.0;
00929                 setColumnStatus(iColumn,isFree);
00930               }
00931             } else {
00932               numberBasic++;
00933             }
00934             break;
00935           case atUpperBound:
00936             columnActivityWork_[iColumn]=columnUpperWork_[iColumn];
00937             if (columnActivityWork_[iColumn]>largeValue_) {
00938               if (columnLowerWork_[iColumn]<-largeValue_) {
00939                 columnActivityWork_[iColumn]=0.0;
00940                 setColumnStatus(iColumn,isFree);
00941               } else {
00942                 columnActivityWork_[iColumn]=columnLowerWork_[iColumn];
00943                 setColumnStatus(iColumn,atLowerBound);
00944               }
00945             }
00946             break;
00947           case isFixed:
00948           case atLowerBound:
00949             columnActivityWork_[iColumn]=columnLowerWork_[iColumn];
00950             if (columnActivityWork_[iColumn]<-largeValue_) {
00951               if (columnUpperWork_[iColumn]>largeValue_) {
00952                 columnActivityWork_[iColumn]=0.0;
00953                 setColumnStatus(iColumn,isFree);
00954               } else {
00955                 columnActivityWork_[iColumn]=columnUpperWork_[iColumn];
00956                 setColumnStatus(iColumn,atUpperBound);
00957               }
00958             }
00959             break;
00960           case isFree:
00961               break;
00962             // not really free - fall through to superbasic
00963           case superBasic:
00964             if (columnUpperWork_[iColumn]>largeValue_) {
00965               if (columnLowerWork_[iColumn]>-largeValue_) {
00966                 columnActivityWork_[iColumn]=columnLowerWork_[iColumn];
00967                 setColumnStatus(iColumn,atLowerBound);
00968               } else {
00969                 // say free
00970                 setColumnStatus(iColumn,isFree);
00971                 columnActivityWork_[iColumn]=0.0;
00972               }
00973             } else {
00974               if (columnLowerWork_[iColumn]>-largeValue_) {
00975                 // set to nearest
00976                 if (fabs(columnActivityWork_[iColumn]-columnLowerWork_[iColumn])
00977                     <fabs(columnActivityWork_[iColumn]-columnLowerWork_[iColumn])) {
00978                   columnActivityWork_[iColumn]=columnLowerWork_[iColumn];
00979                   setColumnStatus(iColumn,atLowerBound);
00980                 } else {
00981                   columnActivityWork_[iColumn]=columnUpperWork_[iColumn];
00982                   setColumnStatus(iColumn,atUpperBound);
00983                 }
00984               } else {
00985                 columnActivityWork_[iColumn]=columnUpperWork_[iColumn];
00986                 setColumnStatus(iColumn,atUpperBound);
00987               }
00988             }
00989             break;
00990           }
00991         }
00992       } else {
00993         // all slack basis
00994         int numberBasic=0;
00995         if (!status_) {
00996           createStatus();
00997         }
00998         for (iRow=0;iRow<numberRows_;iRow++) {
00999           double lower=rowLowerWork_[iRow];
01000           double upper=rowUpperWork_[iRow];
01001           if (lower>-largeValue_||upper<largeValue_) {
01002             if (fabs(lower)<=fabs(upper)) {
01003               rowActivityWork_[iRow]=lower;
01004             } else {
01005               rowActivityWork_[iRow]=upper;
01006             }
01007           } else {
01008             rowActivityWork_[iRow]=0.0;
01009           }
01010           setRowStatus(iRow,basic);
01011           numberBasic++;
01012         }
01013         for (iColumn=0;iColumn<numberColumns_;iColumn++) {
01014           double lower=columnLowerWork_[iColumn];
01015           double upper=columnUpperWork_[iColumn];
01016           double big_bound = largeValue_;
01017           if (lower>-big_bound||upper<big_bound) {
01018             if ((getColumnStatus(iColumn)==atLowerBound&&
01019                  columnActivityWork_[iColumn]==lower)||
01020                 (getColumnStatus(iColumn)==atUpperBound&&
01021                  columnActivityWork_[iColumn]==upper)) {
01022               // status looks plausible
01023             } else {
01024               // set to sensible
01025               if (fabs(lower)<=fabs(upper)) {
01026                 setColumnStatus(iColumn,atLowerBound);
01027                 columnActivityWork_[iColumn]=lower;
01028               } else {
01029                 setColumnStatus(iColumn,atUpperBound);
01030                 columnActivityWork_[iColumn]=upper;
01031               }
01032             }
01033           } else {
01034             setColumnStatus(iColumn,isFree);
01035             columnActivityWork_[iColumn]=0.0;
01036           }
01037         }
01038       }
01039     } else {
01040       // values pass has less coding
01041       // make row activities correct and clean basis a bit
01042       cleanStatus();
01043       if (status_) {
01044         int numberBasic=0;
01045         for (iRow=0;iRow<numberRows_;iRow++) {
01046           if (getRowStatus(iRow)==basic) 
01047             numberBasic++;
01048         }
01049         totalSlacks=numberBasic;
01050         for (iColumn=0;iColumn<numberColumns_;iColumn++) {
01051           if (getColumnStatus(iColumn)==basic) 
01052             numberBasic++;
01053         }
01054       } else {
01055         // all slack basis
01056         int numberBasic=0;
01057         if (!status_) {
01058           createStatus();
01059         }
01060         for (iRow=0;iRow<numberRows_;iRow++) {
01061           setRowStatus(iRow,basic);
01062           numberBasic++;
01063         }
01064         for (iColumn=0;iColumn<numberColumns_;iColumn++) {
01065           setColumnStatus(iColumn,superBasic);
01066           // but put to bound if close
01067           if (fabs(columnActivityWork_[iColumn]-columnLowerWork_[iColumn])
01068               <=primalTolerance_) {
01069             columnActivityWork_[iColumn]=columnLowerWork_[iColumn];
01070             setColumnStatus(iColumn,atLowerBound);
01071           } else if (fabs(columnActivityWork_[iColumn]
01072                         -columnUpperWork_[iColumn])
01073                      <=primalTolerance_) {
01074             columnActivityWork_[iColumn]=columnUpperWork_[iColumn];
01075             setColumnStatus(iColumn,atUpperBound);
01076           }
01077         }
01078       }
01079     }
01080     numberRefinements_=1;
01081     // set fixed if they are
01082     for (iRow=0;iRow<numberRows_;iRow++) {
01083       if (getRowStatus(iRow)!=basic ) {
01084         if (rowLowerWork_[iRow]==rowUpperWork_[iRow]) {
01085           rowActivityWork_[iRow]=rowLowerWork_[iRow];
01086           setRowStatus(iRow,isFixed);
01087         }
01088       }
01089     }
01090     for (iColumn=0;iColumn<numberColumns_;iColumn++) {
01091       if (getColumnStatus(iColumn)!=basic ) {
01092         if (columnLowerWork_[iColumn]==columnUpperWork_[iColumn]) {
01093           columnActivityWork_[iColumn]=columnLowerWork_[iColumn];
01094           setColumnStatus(iColumn,isFixed);
01095         }
01096       }
01097     }
01098   }
01099   if (0)  {
01100     static int k=0;
01101     printf("start basis\n");
01102     int i;
01103     for (i=0;i<numberRows_;i++)
01104       printf ("xx %d %d\n",i,pivotVariable_[i]);
01105     for (i=0;i<numberRows_+numberColumns_;i++)
01106       if (getColumnStatus(i)==basic)
01107         printf ("yy %d basic\n",i);
01108     if (k>20)
01109       exit(0);
01110     k++;
01111   }
01112   int status = factorization_->factorize(this, solveType,valuesPass);
01113   if (status) {
01114     handler_->message(CLP_SIMPLEX_BADFACTOR,messages_)
01115       <<status
01116       <<CoinMessageEol;
01117     return -1;
01118   } else if (!solveType) {
01119     // Initial basis - return number of singularities
01120     int numberSlacks=0;
01121     for (iRow=0;iRow<numberRows_;iRow++) {
01122       if (getRowStatus(iRow) == basic)
01123         numberSlacks++;
01124     }
01125     status= max(numberSlacks-totalSlacks,0);
01126   }
01127 
01128   // sparse methods
01129   //if (factorization_->sparseThreshold()) {
01130     // get default value
01131     factorization_->sparseThreshold(0);
01132     factorization_->goSparse();
01133     //}
01134   
01135   return status;
01136 }
01137 /* 
01138    This does basis housekeeping and does values for in/out variables.
01139    Can also decide to re-factorize
01140 */
01141 int 
01142 ClpSimplex::housekeeping(double objectiveChange)
01143 {
01144   numberIterations_++;
01145   changeMade_++; // something has happened
01146   // incoming variable
01147   handler_->message(CLP_SIMPLEX_HOUSE1,messages_)
01148     <<directionOut_
01149     <<directionIn_<<theta_
01150     <<dualOut_<<dualIn_<<alpha_
01151     <<CoinMessageEol;
01152   if (getStatus(sequenceIn_)==isFree) {
01153     handler_->message(CLP_SIMPLEX_FREEIN,messages_)
01154       <<sequenceIn_
01155       <<CoinMessageEol;
01156   }
01157   // change of incoming
01158   char rowcol[]={'R','C'};
01159   if (pivotRow_>=0)
01160     pivotVariable_[pivotRow_]=sequenceIn();
01161   if (upper_[sequenceIn_]>1.0e20&&lower_[sequenceIn_]<-1.0e20)
01162     progressFlag_ |= 2; // making real progress
01163   solution_[sequenceIn_]=valueIn_;
01164   if (upper_[sequenceOut_]-lower_[sequenceOut_]<1.0e-12)
01165     progressFlag_ |= 1; // making real progress
01166   if (sequenceIn_!=sequenceOut_) {
01167     //assert( getStatus(sequenceOut_)== basic);
01168     setStatus(sequenceIn_,basic);
01169     if (upper_[sequenceOut_]-lower_[sequenceOut_]>0) {
01170       // As Nonlinear costs may have moved bounds (to more feasible)
01171       // Redo using value
01172       if (fabs(valueOut_-lower_[sequenceOut_])<fabs(valueOut_-upper_[sequenceOut_])) {
01173         // going to lower
01174         setStatus(sequenceOut_,atLowerBound);
01175       } else {
01176         // going to upper
01177         setStatus(sequenceOut_,atUpperBound);
01178       }
01179     } else {
01180       // fixed
01181       setStatus(sequenceOut_,isFixed);
01182     }
01183     solution_[sequenceOut_]=valueOut_;
01184   } else {
01185     // flip from bound to bound
01186     // As Nonlinear costs may have moved bounds (to more feasible)
01187     // Redo using value
01188     if (fabs(valueIn_-lower_[sequenceIn_])<fabs(valueIn_-upper_[sequenceIn_])) {
01189       // as if from upper bound
01190       setStatus(sequenceIn_, atLowerBound);
01191     } else {
01192       // as if from lower bound
01193       setStatus(sequenceIn_, atUpperBound);
01194     }
01195   }
01196   objectiveValue_ += objectiveChange;
01197   handler_->message(CLP_SIMPLEX_HOUSE2,messages_)
01198     <<numberIterations_<<objectiveValue()
01199     <<rowcol[isColumn(sequenceIn_)]<<sequenceWithin(sequenceIn_)
01200     <<rowcol[isColumn(sequenceOut_)]<<sequenceWithin(sequenceOut_);
01201   handler_->printing(algorithm_<0)<<theta_<<dualOut_;
01202   handler_->printing(algorithm_>0)<<dualIn_<<theta_;
01203   handler_->message()<<CoinMessageEol;
01204   if (hitMaximumIterations())
01205     return 2;
01206 #if 0
01207   // check for small cycles
01208   int cycle=progress_->cycle(sequenceIn_,sequenceOut_,
01209                             directionIn_,directionOut_);
01210   if (cycle>0) {
01211     printf("Cycle of %d\n",cycle);
01212     // reset
01213     progress_->startCheck();
01214     if (factorization_->pivots()>cycle) {
01215       forceFactorization_=cycle-1;
01216     } else {
01217       // need to reject something
01218       int iSequence;
01219       if (algorithm_<0)
01220         iSequence = sequenceIn_;
01221       else
01222         iSequence = sequenceOut_;
01223       char x = isColumn(iSequence) ? 'C' :'R';
01224       handler_->message(CLP_SIMPLEX_FLAG,messages_)
01225         <<x<<sequenceWithin(iSequence)
01226         <<CoinMessageEol;
01227       setFlagged(iSequence);
01228       printf("flagging %d\n",iSequence);
01229     }
01230     return 1;
01231   }
01232 #endif
01233   // only time to re-factorize if one before real time
01234   // this is so user won't be surprised that maximumPivots has exact meaning
01235   if (factorization_->pivots()==factorization_->maximumPivots()) {
01236     return 1;
01237   } else {
01238     if (forceFactorization_>0&&
01239         factorization_->pivots()==forceFactorization_) {
01240       // relax
01241       forceFactorization_ = (3+5*forceFactorization_)/4;
01242       if (forceFactorization_>factorization_->maximumPivots())
01243         forceFactorization_ = -1; //off
01244       return 1;
01245     } else {
01246       // carry on iterating
01247       return 0;
01248     }
01249   }
01250 }
01251 // Copy constructor. 
01252 ClpSimplex::ClpSimplex(const ClpSimplex &rhs) :
01253   ClpModel(rhs),
01254   columnPrimalInfeasibility_(0.0),
01255   rowPrimalInfeasibility_(0.0),
01256   columnPrimalSequence_(-2),
01257   rowPrimalSequence_(-2), 
01258   columnDualInfeasibility_(0.0),
01259   rowDualInfeasibility_(0.0),
01260   columnDualSequence_(-2),
01261   rowDualSequence_(-2),
01262   primalToleranceToGetOptimal_(-1.0),
01263   remainingDualInfeasibility_(0.0),
01264   largeValue_(1.0e15),
01265   largestPrimalError_(0.0),
01266   largestDualError_(0.0),
01267   largestSolutionError_(0.0),
01268   dualBound_(1.0e10),
01269   alpha_(0.0),
01270   theta_(0.0),
01271   lowerIn_(0.0),
01272   valueIn_(0.0),
01273   upperIn_(0.0),
01274   dualIn_(0.0),
01275   lowerOut_(-1),
01276   valueOut_(-1),
01277   upperOut_(-1),
01278   dualOut_(-1),
01279   dualTolerance_(0.0),
01280   primalTolerance_(0.0),
01281   sumDualInfeasibilities_(0.0),
01282   sumPrimalInfeasibilities_(0.0),
01283   infeasibilityCost_(1.0e10),
01284   sumOfRelaxedDualInfeasibilities_(0.0),
01285   sumOfRelaxedPrimalInfeasibilities_(0.0),
01286   lower_(NULL),
01287   rowLowerWork_(NULL),
01288   columnLowerWork_(NULL),
01289   upper_(NULL),
01290   rowUpperWork_(NULL),
01291   columnUpperWork_(NULL),
01292   cost_(NULL),
01293   rowObjectiveWork_(NULL),
01294   objectiveWork_(NULL),
01295   sequenceIn_(-1),
01296   directionIn_(-1),
01297   sequenceOut_(-1),
01298   directionOut_(-1),
01299   pivotRow_(-1),
01300   lastGoodIteration_(-100),
01301   dj_(NULL),
01302   rowReducedCost_(NULL),
01303   reducedCostWork_(NULL),
01304   solution_(NULL),
01305   rowActivityWork_(NULL),
01306   columnActivityWork_(NULL),
01307   numberDualInfeasibilities_(0),
01308   numberDualInfeasibilitiesWithoutFree_(0),
01309   numberPrimalInfeasibilities_(100),
01310   numberRefinements_(0),
01311   pivotVariable_(NULL),
01312   factorization_(NULL),
01313   rowScale_(NULL),
01314   savedSolution_(NULL),
01315   columnScale_(NULL),
01316   scalingFlag_(3),
01317   numberTimesOptimal_(0),
01318   changeMade_(1),
01319   algorithm_(0),
01320   forceFactorization_(-1),
01321   perturbation_(100),
01322   nonLinearCost_(NULL),
01323   specialOptions_(0),
01324   lastBadIteration_(-999999),
01325   numberFake_(0),
01326   progressFlag_(0),
01327   firstFree_(-1),
01328   incomingInfeasibility_(1.0),
01329   allowedInfeasibility_(10.0),
01330   progress_(NULL)
01331 {
01332   int i;
01333   for (i=0;i<6;i++) {
01334     rowArray_[i]=NULL;
01335     columnArray_[i]=NULL;
01336   }
01337   saveStatus_=NULL;
01338   factorization_ = NULL;
01339   dualRowPivot_ = NULL;
01340   primalColumnPivot_ = NULL;
01341   gutsOfDelete(0);
01342   specialOptions_ =0;
01343   delete nonLinearCost_;
01344   nonLinearCost_ = NULL;
01345   gutsOfCopy(rhs);
01346   solveType_=1; // say simplex based life form
01347 }
01348 // Copy constructor from model
01349 ClpSimplex::ClpSimplex(const ClpModel &rhs) :
01350   ClpModel(rhs),
01351   columnPrimalInfeasibility_(0.0),
01352   rowPrimalInfeasibility_(0.0),
01353   columnPrimalSequence_(-2),
01354   rowPrimalSequence_(-2), 
01355   columnDualInfeasibility_(0.0),
01356   rowDualInfeasibility_(0.0),
01357   columnDualSequence_(-2),
01358   rowDualSequence_(-2),
01359   primalToleranceToGetOptimal_(-1.0),
01360   remainingDualInfeasibility_(0.0),
01361   largeValue_(1.0e15),
01362   largestPrimalError_(0.0),
01363   largestDualError_(0.0),
01364   largestSolutionError_(0.0),
01365   dualBound_(1.0e10),
01366   alpha_(0.0),
01367   theta_(0.0),
01368   lowerIn_(0.0),
01369   valueIn_(0.0),
01370   upperIn_(0.0),
01371   dualIn_(0.0),
01372   lowerOut_(-1),
01373   valueOut_(-1),
01374   upperOut_(-1),
01375   dualOut_(-1),
01376   dualTolerance_(0.0),
01377   primalTolerance_(0.0),
01378   sumDualInfeasibilities_(0.0),
01379   sumPrimalInfeasibilities_(0.0),
01380   infeasibilityCost_(1.0e10),
01381   sumOfRelaxedDualInfeasibilities_(0.0),
01382   sumOfRelaxedPrimalInfeasibilities_(0.0),
01383   lower_(NULL),
01384   rowLowerWork_(NULL),
01385   columnLowerWork_(NULL),
01386   upper_(NULL),
01387   rowUpperWork_(NULL),
01388   columnUpperWork_(NULL),
01389   cost_(NULL),
01390   rowObjectiveWork_(NULL),
01391   objectiveWork_(NULL),
01392   sequenceIn_(-1),
01393   directionIn_(-1),
01394   sequenceOut_(-1),
01395   directionOut_(-1),
01396   pivotRow_(-1),
01397   lastGoodIteration_(-100),
01398   dj_(NULL),
01399   rowReducedCost_(NULL),
01400   reducedCostWork_(NULL),
01401   solution_(NULL),
01402   rowActivityWork_(NULL),
01403   columnActivityWork_(NULL),
01404   numberDualInfeasibilities_(0),
01405   numberDualInfeasibilitiesWithoutFree_(0),
01406   numberPrimalInfeasibilities_(100),
01407   numberRefinements_(0),
01408   pivotVariable_(NULL),
01409   factorization_(NULL),
01410   rowScale_(NULL),
01411   savedSolution_(NULL),
01412   columnScale_(NULL),
01413   scalingFlag_(3),
01414   numberTimesOptimal_(0),
01415   changeMade_(1),
01416   algorithm_(0),
01417   forceFactorization_(-1),
01418   perturbation_(100),
01419   nonLinearCost_(NULL),
01420   specialOptions_(0),
01421   lastBadIteration_(-999999),
01422   numberFake_(0),
01423   progressFlag_(0),
01424   firstFree_(-1),
01425   incomingInfeasibility_(1.0),
01426   allowedInfeasibility_(10.0),
01427   progress_(NULL)
01428 {
01429   int i;
01430   for (i=0;i<6;i++) {
01431     rowArray_[i]=NULL;
01432     columnArray_[i]=NULL;
01433   }
01434   saveStatus_=NULL;
01435   // get an empty factorization so we can set tolerances etc
01436   factorization_ = new ClpFactorization();
01437   // say Steepest pricing
01438   dualRowPivot_ = new ClpDualRowSteepest();
01439   // say Steepest pricing
01440   primalColumnPivot_ = new ClpPrimalColumnSteepest();
01441   solveType_=1; // say simplex based life form
01442   
01443 }
01444 // Assignment operator. This copies the data
01445 ClpSimplex & 
01446 ClpSimplex::operator=(const ClpSimplex & rhs)
01447 {
01448   if (this != &rhs) {
01449     gutsOfDelete(0);
01450     specialOptions_=0;
01451     delete nonLinearCost_;
01452     nonLinearCost_ = NULL;
01453     ClpModel::operator=(rhs);
01454     gutsOfCopy(rhs);
01455   }
01456   return *this;
01457 }
01458 void 
01459 ClpSimplex::gutsOfCopy(const ClpSimplex & rhs)
01460 {
01461   lower_ = ClpCopyOfArray(rhs.lower_,numberColumns_+numberRows_);
01462   rowLowerWork_ = lower_+numberColumns_;
01463   columnLowerWork_ = lower_;
01464   upper_ = ClpCopyOfArray(rhs.upper_,numberColumns_+numberRows_);
01465   rowUpperWork_ = upper_+numberColumns_;
01466   columnUpperWork_ = upper_;
01467   //cost_ = ClpCopyOfArray(rhs.cost_,2*(numberColumns_+numberRows_));
01468   cost_ = ClpCopyOfArray(rhs.cost_,(numberColumns_+numberRows_));
01469   objectiveWork_ = cost_;
01470   rowObjectiveWork_ = cost_+numberColumns_;
01471   dj_ = ClpCopyOfArray(rhs.dj_,numberRows_+numberColumns_);
01472   if (dj_) {
01473     reducedCostWork_ = dj_;
01474     rowReducedCost_ = dj_+numberColumns_;
01475   }
01476   solution_ = ClpCopyOfArray(rhs.solution_,numberRows_+numberColumns_);
01477   if (solution_) {
01478     columnActivityWork_ = solution_;
01479     rowActivityWork_ = solution_+numberColumns_;
01480   }
01481   if (rhs.pivotVariable_) {
01482     pivotVariable_ = new int[numberRows_];
01483     ClpDisjointCopyN ( rhs.pivotVariable_, numberRows_ , pivotVariable_);
01484   } else {
01485     pivotVariable_=NULL;
01486   }
01487   if (rhs.factorization_) {
01488     factorization_ = new ClpFactorization(*rhs.factorization_);
01489   } else {
01490     factorization_=NULL;
01491   }
01492   rowScale_ = ClpCopyOfArray(rhs.rowScale_,numberRows_);
01493   savedSolution_ = ClpCopyOfArray(rhs.savedSolution_,numberColumns_+numberRows_);
01494   columnScale_ = ClpCopyOfArray(rhs.columnScale_,numberColumns_);
01495   int i;
01496   for (i=0;i<6;i++) {
01497     rowArray_[i]=NULL;
01498     if (rhs.rowArray_[i]) 
01499       rowArray_[i] = new CoinIndexedVector(*rhs.rowArray_[i]);
01500     columnArray_[i]=NULL;
01501     if (rhs.columnArray_[i]) 
01502       columnArray_[i] = new CoinIndexedVector(*rhs.columnArray_[i]);
01503   }
01504   if (rhs.saveStatus_) {
01505     saveStatus_ = ClpCopyOfArray( rhs.saveStatus_,numberColumns_+numberRows_);
01506   }
01507   columnPrimalInfeasibility_ = rhs.columnPrimalInfeasibility_;
01508   columnPrimalSequence_ = rhs.columnPrimalSequence_;
01509   rowPrimalInfeasibility_ = rhs.rowPrimalInfeasibility_;
01510   rowPrimalSequence_ = rhs.rowPrimalSequence_;
01511   columnDualInfeasibility_ = rhs.columnDualInfeasibility_;
01512   columnDualSequence_ = rhs.columnDualSequence_;
01513   rowDualInfeasibility_ = rhs.rowDualInfeasibility_;
01514   rowDualSequence_ = rhs.rowDualSequence_;
01515   primalToleranceToGetOptimal_ = rhs.primalToleranceToGetOptimal_;
01516   remainingDualInfeasibility_ = rhs.remainingDualInfeasibility_;
01517   largeValue_ = rhs.largeValue_;
01518   largestPrimalError_ = rhs.largestPrimalError_;
01519   largestDualError_ = rhs.largestDualError_;
01520   largestSolutionError_ = rhs.largestSolutionError_;
01521   dualBound_ = rhs.dualBound_;
01522   alpha_ = rhs.alpha_;
01523   theta_ = rhs.theta_;
01524   lowerIn_ = rhs.lowerIn_;
01525   valueIn_ = rhs.valueIn_;
01526   upperIn_ = rhs.upperIn_;
01527   dualIn_ = rhs.dualIn_;
01528   sequenceIn_ = rhs.sequenceIn_;
01529   directionIn_ = rhs.directionIn_;
01530   lowerOut_ = rhs.lowerOut_;
01531   valueOut_ = rhs.valueOut_;
01532   upperOut_ = rhs.upperOut_;
01533   dualOut_ = rhs.dualOut_;
01534   sequenceOut_ = rhs.sequenceOut_;
01535   directionOut_ = rhs.directionOut_;
01536   pivotRow_ = rhs.pivotRow_;
01537   lastGoodIteration_ = rhs.lastGoodIteration_;
01538   numberRefinements_ = rhs.numberRefinements_;
01539   dualTolerance_ = rhs.dualTolerance_;
01540   primalTolerance_ = rhs.primalTolerance_;
01541   sumDualInfeasibilities_ = rhs.sumDualInfeasibilities_;
01542   numberDualInfeasibilities_ = rhs.numberDualInfeasibilities_;
01543   numberDualInfeasibilitiesWithoutFree_ = 
01544     rhs.numberDualInfeasibilitiesWithoutFree_;
01545   sumPrimalInfeasibilities_ = rhs.sumPrimalInfeasibilities_;
01546   numberPrimalInfeasibilities_ = rhs.numberPrimalInfeasibilities_;
01547   dualRowPivot_ = rhs.dualRowPivot_->clone(true);
01548   primalColumnPivot_ = rhs.primalColumnPivot_->clone(true);
01549   scalingFlag_ = rhs.scalingFlag_;
01550   numberTimesOptimal_ = rhs.numberTimesOptimal_;
01551   changeMade_ = rhs.changeMade_;
01552   algorithm_ = rhs.algorithm_;
01553   forceFactorization_ = rhs.forceFactorization_;
01554   perturbation_ = rhs.perturbation_;
01555   infeasibilityCost_ = rhs.infeasibilityCost_;
01556   specialOptions_ = rhs.specialOptions_;
01557   lastBadIteration_ = rhs.lastBadIteration_;
01558   numberFake_ = rhs.numberFake_;
01559   progressFlag_ = rhs.progressFlag_;
01560   firstFree_ = rhs.firstFree_;
01561   incomingInfeasibility_ = rhs.incomingInfeasibility_;
01562   allowedInfeasibility_ = rhs.allowedInfeasibility_;
01563   if (rhs.progress_)
01564     progress_ = new ClpSimplexProgress(*rhs.progress_);
01565   else
01566     progress_=NULL;
01567   sumOfRelaxedDualInfeasibilities_ = rhs.sumOfRelaxedDualInfeasibilities_;
01568   sumOfRelaxedPrimalInfeasibilities_ = rhs.sumOfRelaxedPrimalInfeasibilities_;
01569   if (rhs.nonLinearCost_!=NULL)
01570     nonLinearCost_ = new ClpNonLinearCost(*rhs.nonLinearCost_);
01571   else
01572     nonLinearCost_=NULL;
01573   solveType_=rhs.solveType_;
01574 }
01575 // type == 0 do everything, most + pivot data, 2 factorization data as well
01576 void 
01577 ClpSimplex::gutsOfDelete(int type)
01578 {
01579   delete [] lower_;
01580   lower_=NULL;
01581   rowLowerWork_=NULL;
01582   columnLowerWork_=NULL;
01583   delete [] upper_;
01584   upper_=NULL;
01585   rowUpperWork_=NULL;
01586   columnUpperWork_=NULL;
01587   delete [] cost_;
01588   cost_=NULL;
01589   objectiveWork_=NULL;
01590   rowObjectiveWork_=NULL;
01591   delete [] dj_;
01592   dj_=NULL;
01593   reducedCostWork_=NULL;
01594   rowReducedCost_=NULL;
01595   delete [] solution_;
01596   solution_=NULL;
01597   rowActivityWork_=NULL;
01598   columnActivityWork_=NULL;
01599   delete [] rowScale_;
01600   rowScale_ = NULL;
01601   delete [] savedSolution_;
01602   savedSolution_ = NULL;
01603   delete [] columnScale_;
01604   columnScale_ = NULL;
01605   if ((specialOptions_&2)==0) {
01606     delete nonLinearCost_;
01607     nonLinearCost_ = NULL;
01608   }
01609   int i;
01610   for (i=0;i<6;i++) {
01611     delete rowArray_[i];
01612     rowArray_[i]=NULL;
01613     delete columnArray_[i];
01614     columnArray_[i]=NULL;
01615   }
01616   delete rowCopy_;
01617   rowCopy_=NULL;
01618   delete [] saveStatus_;
01619   saveStatus_=NULL;
01620   if (!type) {
01621     // delete everything
01622     delete factorization_;
01623     factorization_ = NULL;
01624     delete [] pivotVariable_;
01625     pivotVariable_=NULL;
01626     delete dualRowPivot_;
01627     dualRowPivot_ = NULL;
01628     delete primalColumnPivot_;
01629     primalColumnPivot_ = NULL;
01630     delete progress_;
01631     progress_=NULL;
01632   } else {
01633     // delete any size information in methods
01634     if (type>1) {
01635       factorization_->clearArrays();
01636       delete [] pivotVariable_;
01637       pivotVariable_=NULL;
01638     }
01639     dualRowPivot_->clearArrays();
01640     primalColumnPivot_->clearArrays();
01641   }
01642 }
01643 // This sets largest infeasibility and most infeasible
01644 void 
01645 ClpSimplex::checkPrimalSolution(const double * rowActivities,
01646                                         const double * columnActivities)
01647 {
01648   double * solution;
01649   int iRow,iColumn;
01650 
01651   objectiveValue_ = 0.0;
01652   // now look at primal solution
01653   columnPrimalInfeasibility_=0.0;
01654   columnPrimalSequence_=-1;
01655   rowPrimalInfeasibility_=0.0;
01656   rowPrimalSequence_=-1;
01657   largestSolutionError_=0.0;
01658   solution = rowActivityWork_;
01659   sumPrimalInfeasibilities_=0.0;
01660   numberPrimalInfeasibilities_=0;
01661   double primalTolerance = primalTolerance_;
01662   double relaxedTolerance=primalTolerance_;
01663   // we can't really trust infeasibilities if there is primal error
01664   double error = min(1.0e-3,largestPrimalError_);
01665   // allow tolerance at least slightly bigger than standard
01666   relaxedTolerance = relaxedTolerance +  error;
01667   sumOfRelaxedPrimalInfeasibilities_ = 0.0;
01668 
01669   for (iRow=0;iRow<numberRows_;iRow++) {
01670     //assert (fabs(solution[iRow])<1.0e15||getRowStatus(iRow) == basic);
01671     double infeasibility=0.0;
01672     objectiveValue_ += solution[iRow]*rowObjectiveWork_[iRow];
01673     if (solution[iRow]>rowUpperWork_[iRow]) {
01674       infeasibility=solution[iRow]-rowUpperWork_[iRow];
01675     } else if (solution[iRow]<rowLowerWork_[iRow]) {
01676       infeasibility=rowLowerWork_[iRow]-solution[iRow];
01677     }
01678     if (infeasibility>primalTolerance) {
01679       sumPrimalInfeasibilities_ += infeasibility-primalTolerance_;
01680       if (infeasibility>relaxedTolerance) 
01681         sumOfRelaxedPrimalInfeasibilities_ += infeasibility-relaxedTolerance;
01682       numberPrimalInfeasibilities_ ++;
01683     }
01684     if (infeasibility>rowPrimalInfeasibility_) {
01685       rowPrimalInfeasibility_=infeasibility;
01686       rowPrimalSequence_=iRow;
01687     }
01688     infeasibility = fabs(rowActivities[iRow]-solution[iRow]);
01689     if (infeasibility>largestSolutionError_)
01690       largestSolutionError_=infeasibility;
01691   }
01692   solution = columnActivityWork_;
01693   for (iColumn=0;iColumn<numberColumns_;iColumn++) {
01694     //assert (fabs(solution[iColumn])<1.0e15||getColumnStatus(iColumn) == basic);
01695     double infeasibility=0.0;
01696     objectiveValue_ += objectiveWork_[iColumn]*solution[iColumn];
01697     if (solution[iColumn]>columnUpperWork_[iColumn]) {
01698       infeasibility=solution[iColumn]-columnUpperWork_[iColumn];
01699     } else if (solution[iColumn]<columnLowerWork_[iColumn]) {
01700       infeasibility=columnLowerWork_[iColumn]-solution[iColumn];
01701     }
01702     if (infeasibility>columnPrimalInfeasibility_) {
01703       columnPrimalInfeasibility_=infeasibility;
01704       columnPrimalSequence_=iColumn;
01705     }
01706     if (infeasibility>primalTolerance) {
01707       sumPrimalInfeasibilities_ += infeasibility-primalTolerance_;
01708       if (infeasibility>relaxedTolerance) 
01709         sumOfRelaxedPrimalInfeasibilities_ += infeasibility-relaxedTolerance;
01710       numberPrimalInfeasibilities_ ++;
01711     }
01712     infeasibility = fabs(columnActivities[iColumn]-solution[iColumn]);
01713     if (infeasibility>largestSolutionError_)
01714       largestSolutionError_=infeasibility;
01715   }
01716 }
01717 void 
01718 ClpSimplex::checkDualSolution()
01719 {
01720 
01721   int iRow,iColumn;
01722   sumDualInfeasibilities_=0.0;
01723   numberDualInfeasibilities_=0;
01724   numberDualInfeasibilitiesWithoutFree_=0;
01725   columnDualInfeasibility_=0.0;
01726   columnDualSequence_=-1;
01727   rowDualInfeasibility_=0.0;
01728   rowDualSequence_=-1;
01729   int firstFreePrimal = -1;
01730   int firstFreeDual = -1;
01731   int numberSuperBasicWithDj=0;
01732   primalToleranceToGetOptimal_=max(rowPrimalInfeasibility_,
01733                                    columnPrimalInfeasibility_);
01734   remainingDualInfeasibility_=0.0;
01735   double relaxedTolerance=dualTolerance_;
01736   // we can't really trust infeasibilities if there is dual error
01737   double error = min(1.0e-3,largestDualError_);
01738   // allow tolerance at least slightly bigger than standard
01739   relaxedTolerance = relaxedTolerance +  error;
01740   sumOfRelaxedDualInfeasibilities_ = 0.0;
01741 
01742   for (iColumn=0;iColumn<numberColumns_;iColumn++) {
01743     if (getColumnStatus(iColumn) != basic&&!flagged(iColumn)) {
01744       // not basic
01745       double distanceUp = columnUpperWork_[iColumn]-
01746         columnActivityWork_[iColumn];
01747       double distanceDown = columnActivityWork_[iColumn] -
01748         columnLowerWork_[iColumn];
01749       if (distanceUp>primalTolerance_) {
01750         double value = reducedCostWork_[iColumn];
01751         // Check if "free"
01752         if (distanceDown>primalTolerance_) {
01753           if (fabs(value)>1.0e2*relaxedTolerance) {
01754             numberSuperBasicWithDj++;
01755             if (firstFreeDual<0)
01756               firstFreeDual = iColumn;
01757           }
01758           if (firstFreePrimal<0)
01759             firstFreePrimal = iColumn;
01760         }
01761         // should not be negative
01762         if (value<0.0) {
01763           value = - value;
01764           if (value>columnDualInfeasibility_) {
01765             columnDualInfeasibility_=value;
01766             columnDualSequence_=iColumn;
01767           }
01768           if (value>dualTolerance_) {
01769             if (getColumnStatus(iColumn) != isFree) {
01770               numberDualInfeasibilitiesWithoutFree_ ++;
01771               sumDualInfeasibilities_ += value-dualTolerance_;
01772               if (value>relaxedTolerance) 
01773                 sumOfRelaxedDualInfeasibilities_ += value-relaxedTolerance;
01774               numberDualInfeasibilities_ ++;
01775             } else {
01776               // free so relax a lot
01777               value *= 0.01;
01778               if (value>dualTolerance_) {
01779                 sumDualInfeasibilities_ += value-dualTolerance_;
01780                 if (value>relaxedTolerance) 
01781                   sumOfRelaxedDualInfeasibilities_ += value-relaxedTolerance;
01782                 numberDualInfeasibilities_ ++;
01783               }
01784             }
01785             // maybe we can make feasible by increasing tolerance
01786             if (distanceUp<largeValue_) {
01787               if (distanceUp>primalToleranceToGetOptimal_)
01788                 primalToleranceToGetOptimal_=distanceUp;
01789             } else {
01790               //gap too big for any tolerance
01791               remainingDualInfeasibility_=
01792                 max(remainingDualInfeasibility_,value);
01793             }
01794           }
01795         }
01796       }
01797       if (distanceDown>primalTolerance_) {
01798         double value = reducedCostWork_[iColumn];
01799         // should not be positive
01800         if (value>0.0) {
01801           if (value>columnDualInfeasibility_) {
01802             columnDualInfeasibility_=value;
01803             columnDualSequence_=iColumn;
01804           }
01805           if (value>dualTolerance_) {
01806             sumDualInfeasibilities_ += value-dualTolerance_;
01807             if (value>relaxedTolerance) 
01808               sumOfRelaxedDualInfeasibilities_ += value-relaxedTolerance;
01809             numberDualInfeasibilities_ ++;
01810             if (getColumnStatus(iColumn) != isFree) 
01811               numberDualInfeasibilitiesWithoutFree_ ++;
01812             // maybe we can make feasible by increasing tolerance
01813             if (distanceDown<largeValue_&&
01814                 distanceDown>primalToleranceToGetOptimal_)
01815               primalToleranceToGetOptimal_=distanceDown;
01816           }
01817         }
01818       }
01819     }
01820   }
01821   for (iRow=0;iRow<numberRows_;iRow++) {
01822     if (getRowStatus(iRow) != basic&&!flagged(iRow+numberColumns_)) {
01823       // not basic
01824       double distanceUp = rowUpperWork_[iRow]-rowActivityWork_[iRow];
01825       double distanceDown = rowActivityWork_[iRow] -rowLowerWork_[iRow];
01826       if (distanceUp>primalTolerance_) {
01827         double value = rowReducedCost_[iRow];
01828         // Check if "free"
01829         if (distanceDown>primalTolerance_) {
01830           if (fabs(value)>1.0e2*relaxedTolerance) {
01831             numberSuperBasicWithDj++;
01832             if (firstFreeDual<0)
01833               firstFreeDual = iRow+numberColumns_;
01834           }
01835           if (firstFreePrimal<0)
01836             firstFreePrimal = iRow+numberColumns_;
01837         }
01838         // should not be negative
01839         if (value<0.0) {
01840           value = - value;
01841           if (value>rowDualInfeasibility_) {
01842             rowDualInfeasibility_=value;
01843             rowDualSequence_=iRow;
01844           }
01845           if (value>dualTolerance_) {
01846             sumDualInfeasibilities_ += value-dualTolerance_;
01847             if (value>relaxedTolerance) 
01848               sumOfRelaxedDualInfeasibilities_ += value-relaxedTolerance;
01849             numberDualInfeasibilities_ ++;
01850             if (getRowStatus(iRow) != isFree) 
01851               numberDualInfeasibilitiesWithoutFree_ ++;
01852             // maybe we can make feasible by increasing tolerance
01853             if (distanceUp<largeValue_) {
01854               if (distanceUp>primalToleranceToGetOptimal_)
01855                 primalToleranceToGetOptimal_=distanceUp;
01856             } else {
01857               //gap too big for any tolerance
01858               remainingDualInfeasibility_=
01859                 max(remainingDualInfeasibility_,value);
01860             }
01861           }
01862         }
01863       }
01864       if (distanceDown>primalTolerance_) {
01865         double value = rowReducedCost_[iRow];
01866         // should not be positive
01867         if (value>0.0) {
01868           if (value>rowDualInfeasibility_) {
01869             rowDualInfeasibility_=value;
01870             rowDualSequence_=iRow;
01871           }
01872           if (value>dualTolerance_) {
01873             sumDualInfeasibilities_ += value-dualTolerance_;
01874             if (value>relaxedTolerance) 
01875               sumOfRelaxedDualInfeasibilities_ += value-relaxedTolerance;
01876             numberDualInfeasibilities_ ++;
01877             if (getRowStatus(iRow) != isFree) 
01878               numberDualInfeasibilitiesWithoutFree_ ++;
01879             // maybe we can make feasible by increasing tolerance
01880             if (distanceDown<largeValue_&&
01881                 distanceDown>primalToleranceToGetOptimal_)
01882               primalToleranceToGetOptimal_=distanceDown;
01883           }
01884         }
01885       }
01886     }
01887   }
01888   if (algorithm_<0&&firstFreeDual>=0) {
01889     // dual
01890     firstFree_ = firstFreeDual;
01891   } else if (numberSuperBasicWithDj||
01892              (progress_&&progress_->lastIterationNumber(0)<=0)) {
01893     firstFree_=firstFreePrimal;
01894   }
01895 }
01896 /*
01897   Unpacks one column of the matrix into indexed array 
01898 */
01899 void 
01900 ClpSimplex::unpack(CoinIndexedVector * rowArray) const
01901 {
01902   rowArray->clear();
01903   if (sequenceIn_>=numberColumns_) {
01904     //slack
01905     rowArray->insert(sequenceIn_-numberColumns_,-1.0);
01906   } else {
01907     // column
01908     matrix_->unpack(this,rowArray,sequenceIn_);
01909   }
01910 }
01911 void 
01912 ClpSimplex::unpack(CoinIndexedVector * rowArray,int sequence) const
01913 {
01914   rowArray->clear();
01915   if (sequence>=numberColumns_) {
01916     //slack
01917     rowArray->insert(sequence-numberColumns_,-1.0);
01918   } else {
01919     // column
01920     matrix_->unpack(this,rowArray,sequence);
01921   }
01922 }
01923 /*
01924   Unpacks one column of the matrix into indexed array 
01925 */
01926 void 
01927 ClpSimplex::unpackPacked(CoinIndexedVector * rowArray) 
01928 {
01929   rowArray->clear();
01930   if (sequenceIn_>=numberColumns_) {
01931     //slack
01932     int * index = rowArray->getIndices();
01933     double * array = rowArray->denseVector();
01934     array[0]=-1.0;
01935     index[0]=sequenceIn_-numberColumns_;
01936     rowArray->setNumElements(1);
01937     rowArray->setPackedMode(true);
01938   } else {
01939     // column
01940     matrix_->unpackPacked(this,rowArray,sequenceIn_);
01941   }
01942 }
01943 void 
01944 ClpSimplex::unpackPacked(CoinIndexedVector * rowArray,int sequence)
01945 {
01946   rowArray->clear();
01947   if (sequence>=numberColumns_) {
01948     //slack
01949     int * index = rowArray->getIndices();
01950     double * array = rowArray->denseVector();
01951     array[0]=-1.0;
01952     index[0]=sequence-numberColumns_;
01953     rowArray->setNumElements(1);
01954     rowArray->setPackedMode(true);
01955   } else {
01956     // column
01957     matrix_->unpackPacked(this,rowArray,sequence);
01958   }
01959 }
01960 bool
01961 ClpSimplex::createRim(int what,bool makeRowCopy)
01962 {
01963   bool goodMatrix=true;
01964   int saveLevel=handler_->logLevel();
01965   if (problemStatus_==10) {
01966     handler_->setLogLevel(0); // switch off messages
01967   } else if (factorization_) {
01968     // match up factorization messages
01969     if (handler_->logLevel()<3)
01970       factorization_->messageLevel(0);
01971     else
01972       factorization_->messageLevel(3);
01973   }
01974   int i;
01975   if ((what&(16+32))!=0) {
01976     // move information to work arrays
01977     double direction = optimizationDirection_;
01978     // direction is actually scale out not scale in
01979     if (direction)
01980       direction = 1.0/direction;
01981     if (direction!=1.0) {
01982       // reverse all dual signs
01983       for (i=0;i<numberColumns_;i++) 
01984         reducedCost_[i] *= direction;
01985       for (i=0;i<numberRows_;i++) 
01986         dual_[i] *= direction;
01987     }
01988     // row reduced costs
01989     if (!dj_) {
01990       dj_ = new double[numberRows_+numberColumns_];
01991       reducedCostWork_ = dj_;
01992       rowReducedCost_ = dj_+numberColumns_;
01993       memcpy(reducedCostWork_,reducedCost_,numberColumns_*sizeof(double));
01994       memcpy(rowReducedCost_,dual_,numberRows_*sizeof(double));
01995     }
01996     if (!solution_||(what&32)!=0) {
01997       if (!solution_)
01998         solution_ = new double[numberRows_+numberColumns_];
01999       columnActivityWork_ = solution_;
02000       rowActivityWork_ = solution_+numberColumns_;
02001       memcpy(columnActivityWork_,columnActivity_,
02002              numberColumns_*sizeof(double));
02003       memcpy(rowActivityWork_,rowActivity_,
02004              numberRows_*sizeof(double));
02005     }
02006   }
02007   if ((what&16)!=0) {
02008     //check matrix
02009     if (!matrix_)
02010       matrix_=new ClpPackedMatrix();
02011     if (!matrix_->allElementsInRange(this,smallElement_,1.0e20)) {
02012       problemStatus_=4;
02013       goodMatrix= false;
02014     }
02015     if (makeRowCopy) {
02016       delete rowCopy_;
02017       // may return NULL if can't give row copy
02018       rowCopy_ = matrix_->reverseOrderedCopy();
02019 #ifdef TAKEOUT
02020       {
02021 
02022         ClpPackedMatrix* rowCopy =
02023           dynamic_cast< ClpPackedMatrix*>(rowCopy_);
02024         const int * column = rowCopy->getIndices();
02025         const CoinBigIndex * rowStart = rowCopy->getVectorStarts();
02026         const double * element = rowCopy->getElements();
02027         int i;
02028         for (i=133;i<numberRows_;i++) {
02029           if (rowStart[i+1]-rowStart[i]==10||rowStart[i+1]-rowStart[i]==15)
02030             printf("Row %d has %d elements\n",i,rowStart[i+1]-rowStart[i]);
02031         }
02032       }  
02033 #endif
02034     }
02035   }
02036   if ((what&4)!=0) {
02037     delete [] cost_;
02038     // extra copy with original costs
02039     int nTotal = numberRows_+numberColumns_;
02040     //cost_ = new double[2*nTotal];
02041     cost_ = new double[nTotal];
02042     objectiveWork_ = cost_;
02043     rowObjectiveWork_ = cost_+numberColumns_;
02044     memcpy(objectiveWork_,objective(),numberColumns_*sizeof(double));
02045     if (rowObjective_)
02046       memcpy(rowObjectiveWork_,rowObjective_,numberRows_*sizeof(double));
02047     else
02048       memset(rowObjectiveWork_,0,numberRows_*sizeof(double));
02049     // and initialize changes to zero
02050     //memset(cost_+nTotal,0,nTotal*sizeof(double));
02051   }
02052   if ((what&1)!=0) {
02053     delete [] lower_;
02054     delete [] upper_;
02055     lower_ = new double[numberColumns_+numberRows_];
02056     upper_ = new double[numberColumns_+numberRows_];
02057     rowLowerWork_ = lower_+numberColumns_;
02058     columnLowerWork_ = lower_;
02059     rowUpperWork_ = upper_+numberColumns_;
02060     columnUpperWork_ = upper_;
02061     memcpy(rowLowerWork_,rowLower_,numberRows_*sizeof(double));
02062     memcpy(rowUpperWork_,rowUpper_,numberRows_*sizeof(double));
02063     memcpy(columnLowerWork_,columnLower_,numberColumns_*sizeof(double));
02064     memcpy(columnUpperWork_,columnUpper_,numberColumns_*sizeof(double));
02065     // clean up any mismatches on infinity
02066     for (i=0;i<numberColumns_;i++) {
02067       if (columnLowerWork_[i]<-1.0e30)
02068         columnLowerWork_[i] = -COIN_DBL_MAX;
02069       if (columnUpperWork_[i]>1.0e30)
02070         columnUpperWork_[i] = COIN_DBL_MAX;
02071     }
02072     // clean up any mismatches on infinity
02073     for (i=0;i<numberRows_;i++) {
02074       if (rowLowerWork_[i]<-1.0e30)
02075         rowLowerWork_[i] = -COIN_DBL_MAX;
02076       if (rowUpperWork_[i]>1.0e30)
02077         rowUpperWork_[i] = COIN_DBL_MAX;
02078     }
02079   }
02080   // do scaling if needed
02081   if (scalingFlag_>0&&!rowScale_) {
02082     if (matrix_->scale(this))
02083       scalingFlag_=-scalingFlag_; // not scaled after all
02084   }
02085   if ((what&4)!=0) {
02086     double direction = optimizationDirection_;
02087     // direction is actually scale out not scale in
02088     if (direction)
02089       direction = 1.0/direction;
02090     // but also scale by scale factors
02091     // not really sure about row scaling
02092     if (!rowScale_) {
02093       if (direction!=1.0) {
02094         for (i=0;i<numberRows_;i++)
02095           rowObjectiveWork_[i] *= direction;
02096         for (i=0;i<numberColumns_;i++)
02097           objectiveWork_[i] *= direction;
02098       }
02099     } else {
02100       for (i=0;i<numberRows_;i++)
02101         rowObjectiveWork_[i] *= direction/rowScale_[i];
02102       for (i=0;i<numberColumns_;i++)
02103         objectiveWork_[i] *= direction*columnScale_[i];
02104     }
02105   }
02106   if ((what&(1+32))!=0&&rowScale_) {
02107     for (i=0;i<numberColumns_;i++) {
02108       double multiplier = 1.0/columnScale_[i];
02109       if (columnLowerWork_[i]>-1.0e50)
02110         columnLowerWork_[i] *= multiplier;
02111       if (columnUpperWork_[i]<1.0e50)
02112         columnUpperWork_[i] *= multiplier;
02113       
02114     }
02115     for (i=0;i<numberRows_;i++) {
02116       if (rowLowerWork_[i]>-1.0e50)
02117         rowLowerWork_[i] *= rowScale_[i];
02118       if (rowUpperWork_[i]<1.0e50)
02119         rowUpperWork_[i] *= rowScale_[i];
02120     }
02121   }
02122   if ((what&(8+32))!=0&&rowScale_) {
02123     // on entry
02124     for (i=0;i<numberColumns_;i++) {
02125       columnActivityWork_[i] /= columnScale_[i];
02126       reducedCostWork_[i] *= columnScale_[i];
02127     }
02128     for (i=0;i<numberRows_;i++) {
02129       rowActivityWork_[i] *= rowScale_[i];
02130       dual_[i] /= rowScale_[i];
02131       rowReducedCost_[i] = dual_[i];
02132     }
02133   }
02134  
02135   if ((what&16)!=0) {
02136     // check rim of problem okay
02137     if (!sanityCheck())
02138       goodMatrix=false;
02139   } 
02140   // we need to treat matrix as if each element by rowScaleIn and columnScaleout??
02141   // maybe we need to move scales to SimplexModel for factorization?
02142   if ((what&8)!=0&&!pivotVariable_) {
02143     pivotVariable_=new int[numberRows_];
02144   }
02145 
02146   if ((what&16)!=0&&!rowArray_[2]) {
02147     // get some arrays
02148     int iRow,iColumn;
02149     // these are "indexed" arrays so we always know where nonzeros are
02150     /**********************************************************
02151       rowArray_[3] is long enough for rows+columns
02152     *********************************************************/
02153     for (iRow=0;iRow<4;iRow++) {
02154       if (!rowArray_[iRow]) {
02155         rowArray_[iRow]=new CoinIndexedVector();
02156         int length =numberRows_+factorization_->maximumPivots();
02157         if (iRow==3)
02158           length += numberColumns_;
02159         rowArray_[iRow]->reserve(length);
02160       }
02161     }
02162     
02163     for (iColumn=0;iColumn<2;iColumn++) {
02164       if (!columnArray_[iColumn]) {
02165         columnArray_[iColumn]=new CoinIndexedVector();
02166         if (!iColumn)
02167           columnArray_[iColumn]->reserve(numberColumns_);
02168         else
02169           columnArray_[iColumn]->reserve(max(numberRows_,numberColumns_));
02170       }
02171     }    
02172   }
02173   double primalTolerance=dblParam_[ClpPrimalTolerance];
02174   if ((what&1)!=0) {
02175     // fix any variables with tiny gaps
02176     for (i=0;i<numberColumns_;i++) {
02177       if (columnUpperWork_[i]-columnLowerWork_[i]<=primalTolerance) {
02178         if (columnLowerWork_[i]>=0.0) {
02179           columnUpperWork_[i] = columnLowerWork_[i];
02180         } else if (columnUpperWork_[i]<=0.0) {
02181           columnLowerWork_[i] = columnUpperWork_[i];
02182         } else {
02183           columnUpperWork_[i] = 0.0;
02184           columnLowerWork_[i] = 0.0;
02185         }
02186       }
02187     }
02188     for (i=0;i<numberRows_;i++) {
02189       if (rowUpperWork_[i]-rowLowerWork_[i]<=primalTolerance) {
02190         if (rowLowerWork_[i]>=0.0) {
02191           rowUpperWork_[i] = rowLowerWork_[i];
02192         } else if (rowUpperWork_[i]<=0.0) {
02193           rowLowerWork_[i] = rowUpperWork_[i];
02194         } else {
02195           rowUpperWork_[i] = 0.0;
02196           rowLowerWork_[i] = 0.0;
02197         }
02198       }
02199     }
02200   }
02201   if (problemStatus_==10) {
02202     problemStatus_=-1;
02203     handler_->setLogLevel(saveLevel); // switch back messages
02204   }
02205   return goodMatrix;
02206 }
02207 void
02208 ClpSimplex::deleteRim(int getRidOfFactorizationData)
02209 {
02210   int i;
02211   if (problemStatus_!=1&&problemStatus_!=2) {
02212     delete [] ray_;
02213     ray_=NULL;
02214   }
02215   // ray may be null if in branch and bound
02216   if (rowScale_) {
02217     // Collect infeasibilities
02218     int numberPrimalScaled=0;
02219     int numberPrimalUnscaled=0;
02220     int numberDualScaled=0;
02221     int numberDualUnscaled=0;
02222     for (i=0;i<numberColumns_;i++) {
02223       double scaleFactor = columnScale_[i];
02224       double valueScaled = columnActivityWork_[i];
02225       if (valueScaled<columnLowerWork_[i]-primalTolerance_)
02226         numberPrimalScaled++;
02227       else if (valueScaled>columnUpperWork_[i]+primalTolerance_)
02228         numberPrimalScaled++;
02229       columnActivity_[i] = valueScaled*scaleFactor;
02230       double value = columnActivity_[i];
02231       if (value<columnLower_[i]-primalTolerance_)
02232         numberPrimalUnscaled++;
02233       else if (value>columnUpper_[i]+primalTolerance_)
02234         numberPrimalUnscaled++;
02235       double valueScaledDual = reducedCostWork_[i];
02236       if (valueScaled>columnLowerWork_[i]+primalTolerance_&&valueScaledDual>dualTolerance_)
02237         numberDualScaled++;
02238       if (valueScaled<columnUpperWork_[i]-primalTolerance_&&valueScaledDual<-dualTolerance_)
02239         numberDualScaled++;
02240       reducedCost_[i] = valueScaledDual/scaleFactor;
02241       double valueDual = reducedCost_[i];
02242       if (value>columnLower_[i]+primalTolerance_&&valueDual>dualTolerance_)
02243         numberDualUnscaled++;
02244       if (value<columnUpper_[i]-primalTolerance_&&valueDual<-dualTolerance_)
02245         numberDualUnscaled++;
02246     }
02247     for (i=0;i<numberRows_;i++) {
02248       double scaleFactor = rowScale_[i];
02249       double valueScaled = rowActivityWork_[i];
02250       if (valueScaled<rowLowerWork_[i]-primalTolerance_)
02251         numberPrimalScaled++;
02252       else if (valueScaled>rowUpperWork_[i]+primalTolerance_)
02253         numberPrimalScaled++;
02254       rowActivity_[i] = valueScaled/scaleFactor;
02255       double value = rowActivity_[i];
02256       if (value<rowLower_[i]-primalTolerance_)
02257         numberPrimalUnscaled++;
02258       else if (value>rowUpper_[i]+primalTolerance_)
02259         numberPrimalUnscaled++;
02260       double valueScaledDual = dual_[i]+rowObjectiveWork_[i];;
02261       if (valueScaled>rowLowerWork_[i]+primalTolerance_&&valueScaledDual>dualTolerance_)
02262         numberDualScaled++;
02263       if (valueScaled<rowUpperWork_[i]-primalTolerance_&&valueScaledDual<-dualTolerance_)
02264         numberDualScaled++;
02265       dual_[i] = valueScaledDual*scaleFactor;
02266       double valueDual = dual_[i]; 
02267       if (rowObjective_)
02268         valueDual += rowObjective_[i];
02269       if (value>rowLower_[i]+primalTolerance_&&valueDual>dualTolerance_)
02270         numberDualUnscaled++;
02271       if (value<rowUpper_[i]-primalTolerance_&&valueDual<-dualTolerance_)
02272         numberDualUnscaled++;
02273     }
02274     if (!problemStatus_&&!secondaryStatus_) {
02275       // See if we need to set secondary status
02276       if (numberPrimalUnscaled) {
02277         if (numberDualUnscaled) 
02278           secondaryStatus_=4;
02279         else
02280           secondaryStatus_=2;
02281       } else {
02282         if (numberDualUnscaled) 
02283           secondaryStatus_=3;
02284       }
02285     }
02286     if (problemStatus_==2) {
02287       for (i=0;i<numberColumns_;i++) {
02288         ray_[i] *= columnScale_[i];
02289       }
02290     } else if (problemStatus_==1&&ray_) {
02291       for (i=0;i<numberRows_;i++) {
02292         ray_[i] *= rowScale_[i];
02293       }
02294     }
02295   } else {
02296     for (i=0;i<numberColumns_;i++) {
02297       columnActivity_[i] = columnActivityWork_[i];
02298       reducedCost_[i] = reducedCostWork_[i];
02299     }
02300     for (i=0;i<numberRows_;i++) {
02301       rowActivity_[i] = rowActivityWork_[i];
02302     }
02303   }
02304   if (optimizationDirection_!=1.0) {
02305     // and modify all dual signs
02306     for (i=0;i<numberColumns_;i++) 
02307       reducedCost_[i] *= optimizationDirection_;
02308     for (i=0;i<numberRows_;i++) 
02309       dual_[i] *= optimizationDirection_;
02310   }
02311   // scaling may have been turned off
02312   scalingFlag_ = abs(scalingFlag_);
02313   if(getRidOfFactorizationData>=0)
02314     gutsOfDelete(getRidOfFactorizationData+1);
02315 }
02316 void 
02317 ClpSimplex::setDualBound(double value)
02318 {
02319   if (value>0.0)
02320     dualBound_=value;
02321 }
02322 void 
02323 ClpSimplex::setInfeasibilityCost(double value)
02324 {
02325   if (value>0.0)
02326     infeasibilityCost_=value;
02327 }
02328 void ClpSimplex::setNumberRefinements( int value) 
02329 {
02330   if (value>=0&&value<10)
02331     numberRefinements_=value;
02332 }
02333 // Sets row pivot choice algorithm in dual
02334 void 
02335 ClpSimplex::setDualRowPivotAlgorithm(ClpDualRowPivot & choice)
02336 {
02337   delete dualRowPivot_;
02338   dualRowPivot_ = choice.clone(true);
02339 }
02340 // Sets row pivot choice algorithm in dual
02341 void 
02342 ClpSimplex::setPrimalColumnPivotAlgorithm(ClpPrimalColumnPivot & choice)
02343 {
02344   delete primalColumnPivot_;
02345   primalColumnPivot_ = choice.clone(true);
02346 }
02347 // Sets or unsets scaling, 0 -off, 1 on, 2 dynamic(later)
02348 void 
02349 ClpSimplex::scaling(int mode)
02350 {
02351   if (mode>0&&mode<4) {
02352     scalingFlag_=mode;
02353   } else if (!mode) {
02354     scalingFlag_=0;
02355     delete [] rowScale_;
02356     rowScale_ = NULL;
02357     delete [] columnScale_;
02358     columnScale_ = NULL;
02359   }
02360 }
02361 // Passes in factorization
02362 void 
02363 ClpSimplex::setFactorization( ClpFactorization & factorization)
02364 {
02365   delete factorization_;
02366   factorization_= new ClpFactorization(factorization);
02367 }
02368 void 
02369 ClpSimplex::times(double scalar,
02370                   const double * x, double * y) const
02371 {
02372   if (rowScale_)
02373     matrix_->times(scalar,x,y,rowScale_,columnScale_);
02374   else
02375     matrix_->times(scalar,x,y);
02376 }
02377 void 
02378 ClpSimplex::transposeTimes(double scalar,
02379                            const double * x, double * y) const 
02380 {
02381   if (rowScale_)
02382     matrix_->transposeTimes(scalar,x,y,rowScale_,columnScale_);
02383   else
02384     matrix_->transposeTimes(scalar,x,y);
02385 }
02386 /* Perturbation:
02387    -50 to +50 - perturb by this power of ten (-6 sounds good)
02388    100 - auto perturb if takes too long (1.0e-6 largest nonzero)
02389    101 - we are perturbed
02390    102 - don't try perturbing again
02391    default is 100
02392 */
02393 void 
02394 ClpSimplex::setPerturbation(int value)
02395 {
02396   if(value<=100&&value >=-1000) {
02397     perturbation_=value;
02398   } 
02399 }
02400 // Sparsity on or off
02401 bool 
02402 ClpSimplex::sparseFactorization() const
02403 {
02404   return factorization_->sparseThreshold()!=0;
02405 }
02406 void 
02407 ClpSimplex::setSparseFactorization(bool value)
02408 {
02409   if (value) {
02410     if (!factorization_->sparseThreshold())
02411       factorization_->goSparse();
02412   } else {
02413     factorization_->sparseThreshold(0);
02414   }
02415 }
02416 void checkCorrect(ClpSimplex * model,int iRow,
02417                   const double * element,const int * rowStart,const int * rowLength,
02418                   const int * column,
02419                   const double * columnLower_, const double * columnUpper_,
02420                   int infiniteUpperC,
02421                   int infiniteLowerC,
02422                   double &maximumUpC,
02423                   double &maximumDownC)
02424 {
02425   int infiniteUpper = 0;
02426   int infiniteLower = 0;
02427   double maximumUp = 0.0;
02428   double maximumDown = 0.0;
02429   CoinBigIndex rStart = rowStart[iRow];
02430   CoinBigIndex rEnd = rowStart[iRow]+rowLength[iRow];
02431   CoinBigIndex j;
02432   double large=1.0e15;
02433   int iColumn;
02434   // Compute possible lower and upper ranges
02435   
02436   for (j = rStart; j < rEnd; ++j) {
02437     double value=element[j];
02438     iColumn = column[j];
02439     if (value > 0.0) {
02440       if (columnUpper_[iColumn] >= large) {
02441         ++infiniteUpper;
02442       } else {
02443         maximumUp += columnUpper_[iColumn] * value;
02444       }
02445       if (columnLower_[iColumn] <= -large) {
02446         ++infiniteLower;
02447       } else {
02448         maximumDown += columnLower_[iColumn] * value;
02449       }
02450     } else if (value<0.0) {
02451       if (columnUpper_[iColumn] >= large) {
02452         ++infiniteLower;
02453       } else {
02454         maximumDown += columnUpper_[iColumn] * value;
02455       }
02456       if (columnLower_[iColumn] <= -large) {
02457         ++infiniteUpper;
02458       } else {
02459         maximumUp += columnLower_[iColumn] * value;
02460       }
02461     }
02462   }
02463   assert (infiniteLowerC==infiniteLower);
02464   assert (infiniteUpperC==infiniteUpper);
02465   if (fabs(maximumUp-maximumUpC)>1.0e-12*max(fabs(maximumUp),fabs(maximumUpC)))
02466     printf("row %d comp up %g, true up %g\n",iRow,
02467            maximumUpC,maximumUp);
02468   if (fabs(maximumDown-maximumDownC)>1.0e-12*max(fabs(maximumDown),fabs(maximumDownC)))
02469     printf("row %d comp down %g, true down %g\n",iRow,
02470            maximumDownC,maximumDown);
02471   maximumUpC=maximumUp;
02472   maximumDownC=maximumDown;
02473 }
02474 
02475 /* Tightens primal bounds to make dual faster.  Unless
02476    fixed, bounds are slightly looser than they could be.
02477    This is to make dual go faster and is probably not needed
02478    with a presolve.  Returns non-zero if problem infeasible
02479 
02480    Fudge for branch and bound - put bounds on columns of factor *
02481    largest value (at continuous) - should improve stability
02482    in branch and bound on infeasible branches (0.0 is off)
02483 */
02484 int 
02485 ClpSimplex::tightenPrimalBounds(double factor)
02486 {
02487   
02488   // Get a row copy in standard format
02489   CoinPackedMatrix copy;
02490   copy.reverseOrderedCopyOf(*matrix());
02491   // get matrix data pointers
02492   const int * column = copy.getIndices();
02493   const CoinBigIndex * rowStart = copy.getVectorStarts();
02494   const int * rowLength = copy.getVectorLengths(); 
02495   const double * element = copy.getElements();
02496   int numberChanged=1,iPass=0;
02497   double large = largeValue(); // treat bounds > this as infinite
02498 #ifndef NDEBUG
02499   double large2= 1.0e10*large;
02500 #endif
02501   int numberInfeasible=0;
02502   int totalTightened = 0;
02503 
02504   double tolerance = primalTolerance();
02505 
02506 
02507   // Save column bounds
02508   double * saveLower = new double [numberColumns_];
02509   memcpy(saveLower,columnLower_,numberColumns_*sizeof(double));
02510   double * saveUpper = new double [numberColumns_];
02511   memcpy(saveUpper,columnUpper_,numberColumns_*sizeof(double));
02512 
02513   int iRow, iColumn;
02514 
02515   // If wanted - tighten column bounds using solution
02516   if (factor) {
02517     assert (factor>1.0);
02518     double largest=0.0;
02519     for (iColumn=0;iColumn<numberColumns_;iColumn++) {
02520       if (columnUpper_[iColumn]-columnLower_[iColumn]>tolerance) {
02521         largest = max(largest,fabs(columnActivity_[iColumn]));
02522       }
02523     }
02524     largest *= factor;
02525     for (iColumn=0;iColumn<numberColumns_;iColumn++) {
02526       if (columnUpper_[iColumn]-columnLower_[iColumn]>tolerance) {
02527         columnUpper_[iColumn] = min(columnUpper_[iColumn],largest);
02528         columnLower_[iColumn] = max(columnLower_[iColumn],-largest);
02529       }
02530     }
02531   }
02532 #define MAXPASS 10
02533 
02534   // Loop round seeing if we can tighten bounds
02535   // Would be faster to have a stack of possible rows
02536   // and we put altered rows back on stack
02537   int numberCheck=-1;
02538   while(numberChanged>numberCheck) {
02539 
02540     numberChanged = 0; // Bounds tightened this pass
02541     
02542     if (iPass==MAXPASS) break;
02543     iPass++;
02544     
02545     for (iRow = 0; iRow < numberRows_; iRow++) {
02546 
02547       if (rowLower_[iRow]>-large||rowUpper_[iRow]<large) {
02548 
02549         // possible row
02550         int infiniteUpper = 0;
02551         int infiniteLower = 0;
02552         double maximumUp = 0.0;
02553         double maximumDown = 0.0;
02554         double newBound;
02555         CoinBigIndex rStart = rowStart[iRow];
02556         CoinBigIndex rEnd = rowStart[iRow]+rowLength[iRow];
02557         CoinBigIndex j;
02558         // Compute possible lower and upper ranges
02559       
02560         for (j = rStart; j < rEnd; ++j) {
02561           double value=element[j];
02562           iColumn = column[j];
02563           if (value > 0.0) {
02564             if (columnUpper_[iColumn] >= large) {
02565               ++infiniteUpper;
02566             } else {
02567               maximumUp += columnUpper_[iColumn] * value;
02568             }
02569             if (columnLower_[iColumn] <= -large) {
02570               ++infiniteLower;
02571             } else {
02572               maximumDown += columnLower_[iColumn] * value;
02573             }
02574           } else if (value<0.0) {
02575             if (columnUpper_[iColumn] >= large) {
02576               ++infiniteLower;
02577             } else {
02578               maximumDown += columnUpper_[iColumn] * value;
02579             }
02580             if (columnLower_[iColumn] <= -large) {
02581               ++infiniteUpper;
02582             } else {
02583               maximumUp += columnLower_[iColumn] * value;
02584             }
02585           }
02586         }
02587         // Build in a margin of error
02588         maximumUp += 1.0e-8*fabs(maximumUp);
02589         maximumDown -= 1.0e-8*fabs(maximumDown);
02590         double maxUp = maximumUp+infiniteUpper*1.0e31;
02591         double maxDown = maximumDown-infiniteLower*1.0e31;
02592         if (maxUp <= rowUpper_[iRow] + tolerance && 
02593             maxDown >= rowLower_[iRow] - tolerance) {
02594           
02595           // Row is redundant - make totally free
02596           // NO - can't do this for postsolve
02597           // rowLower_[iRow]=-COIN_DBL_MAX;
02598           // rowUpper_[iRow]=COIN_DBL_MAX;
02599           //printf("Redundant row in presolveX %d\n",iRow);
02600 
02601         } else {
02602           if (maxUp < rowLower_[iRow] -100.0*tolerance ||
02603               maxDown > rowUpper_[iRow]+100.0*tolerance) {
02604             // problem is infeasible - exit at once
02605             numberInfeasible++;
02606             break;
02607           }
02608           double lower = rowLower_[iRow];
02609           double upper = rowUpper_[iRow];
02610           for (j = rStart; j < rEnd; ++j) {
02611             double value=element[j];
02612             iColumn = column[j];
02613             double nowLower = columnLower_[iColumn];
02614             double nowUpper = columnUpper_[iColumn];
02615             if (value > 0.0) {
02616               // positive value
02617               if (lower>-large) {
02618                 if (!infiniteUpper) {
02619                   assert(nowUpper < large2);
02620                   newBound = nowUpper + 
02621                     (lower - maximumUp) / value;
02622                   // relax if original was large
02623                   if (fabs(maximumUp)>1.0e8)
02624                     newBound -= 1.0e-12*fabs(maximumUp);
02625                 } else if (infiniteUpper==1&&nowUpper>large) {
02626                   newBound = (lower -maximumUp) / value;
02627                   // relax if original was large
02628                   if (fabs(maximumUp)>1.0e8)
02629                     newBound -= 1.0e-12*fabs(maximumUp);
02630                 } else {
02631                   newBound = -COIN_DBL_MAX;
02632                 }
02633                 if (newBound > nowLower + 1.0e-12&&newBound>-large) {
02634                   // Tighten the lower bound 
02635                   columnLower_[iColumn] = newBound;
02636                   numberChanged++;
02637                   // check infeasible (relaxed)
02638                   if (nowUpper - newBound < 
02639                       -100.0*tolerance) {
02640                     numberInfeasible++;
02641                   }
02642                   // adjust
02643                   double now;
02644                   if (nowLower<-large) {
02645                     now=0.0;
02646                     infiniteLower--;
02647                   } else {
02648                     now = nowLower;
02649                   }
02650                   maximumDown += (newBound-now) * value;
02651                   nowLower = newBound;
02652 #ifdef DEBUG
02653                   checkCorrect(this,iRow,
02654                                element, rowStart, rowLength,
02655                                column,
02656                                columnLower_,  columnUpper_,
02657                                infiniteUpper,
02658                                infiniteLower,
02659                                maximumUp,
02660                                maximumDown);
02661 #endif
02662                 }
02663               } 
02664               if (upper <large) {
02665                 if (!infiniteLower) {
02666                   assert(nowLower >- large2);
02667                   newBound = nowLower + 
02668                     (upper - maximumDown) / value;
02669                   // relax if original was large
02670                   if (fabs(maximumDown)>1.0e8)
02671                     newBound += 1.0e-12*fabs(maximumDown);
02672                 } else if (infiniteLower==1&&nowLower<-large) {
02673                   newBound =   (upper - maximumDown) / value;
02674                   // relax if original was large
02675                   if (fabs(maximumDown)>1.0e8)
02676                     newBound += 1.0e-12*fabs(maximumDown);
02677                 } else {
02678                   newBound = COIN_DBL_MAX;
02679                 }
02680                 if (newBound < nowUpper - 1.0e-12&&newBound<large) {
02681                   // Tighten the upper bound 
02682                   columnUpper_[iColumn] = newBound;
02683                   numberChanged++;
02684                   // check infeasible (relaxed)
02685                   if (newBound - nowLower < 
02686                       -100.0*tolerance) {
02687                     numberInfeasible++;
02688                   }
02689                   // adjust 
02690                   double now;
02691                   if (nowUpper>large) {
02692                     now=0.0;
02693                     infiniteUpper--;
02694                   } else {
02695                     now = nowUpper;
02696                   }
02697                   maximumUp += (newBound-now) * value;
02698                   nowUpper = newBound;
02699 #ifdef DEBUG
02700                   checkCorrect(this,iRow,
02701                                element, rowStart, rowLength,
02702                                column,
02703                                columnLower_,  columnUpper_,
02704                                infiniteUpper,
02705                                infiniteLower,
02706                                maximumUp,
02707                                maximumDown);
02708 #endif
02709                 }
02710               }
02711             } else {
02712               // negative value
02713               if (lower>-large) {
02714                 if (!infiniteUpper) {
02715                   assert(nowLower < large2);
02716                   newBound = nowLower + 
02717                     (lower - maximumUp) / value;
02718                   // relax if original was large
02719                   if (fabs(maximumUp)>1.0e8)
02720                     newBound += 1.0e-12*fabs(maximumUp);
02721                 } else if (infiniteUpper==1&&nowLower<-large) {
02722                   newBound = (lower -maximumUp) / value;
02723                   // relax if original was large
02724                   if (fabs(maximumUp)>1.0e8)
02725                     newBound += 1.0e-12*fabs(maximumUp);
02726                 } else {
02727                   newBound = COIN_DBL_MAX;
02728                 }
02729                 if (newBound < nowUpper - 1.0e-12&&newBound<large) {
02730                   // Tighten the upper bound 
02731                   columnUpper_[iColumn] = newBound;
02732                   numberChanged++;
02733                   // check infeasible (relaxed)
02734                   if (newBound - nowLower < 
02735                       -100.0*tolerance) {
02736                     numberInfeasible++;
02737                   }
02738                   // adjust
02739                   double now;
02740                   if (nowUpper>large) {
02741                     now=0.0;
02742                     infiniteLower--;
02743                   } else {
02744                     now = nowUpper;
02745                   }
02746                   maximumDown += (newBound-now) * value;
02747                   nowUpper = newBound;
02748 #ifdef DEBUG
02749                   checkCorrect(this,iRow,
02750                                element, rowStart, rowLength,
02751                                column,
02752                                columnLower_,  columnUpper_,
02753                                infiniteUpper,
02754                                infiniteLower,
02755                                maximumUp,
02756                                maximumDown);
02757 #endif
02758                 }
02759               }
02760               if (upper <large) {
02761                 if (!infiniteLower) {
02762                   assert(nowUpper < large2);
02763                   newBound = nowUpper + 
02764                     (upper - maximumDown) / value;
02765                   // relax if original was large
02766                   if (fabs(maximumDown)>1.0e8)
02767                     newBound -= 1.0e-12*fabs(maximumDown);
02768                 } else if (infiniteLower==1&&nowUpper>large) {
02769                   newBound =   (upper - maximumDown) / value;
02770                   // relax if original was large
02771                   if (fabs(maximumDown)>1.0e8)
02772                     newBound -= 1.0e-12*fabs(maximumDown);
02773                 } else {
02774                   newBound = -COIN_DBL_MAX;
02775                 }
02776                 if (newBound > nowLower + 1.0e-12&&newBound>-large) {
02777                   // Tighten the lower bound 
02778                   columnLower_[iColumn] = newBound;
02779                   numberChanged++;
02780                   // check infeasible (relaxed)
02781                   if (nowUpper - newBound < 
02782                       -100.0*tolerance) {
02783                     numberInfeasible++;
02784                   }
02785                   // adjust
02786                   double now;
02787                   if (nowLower<-large) {
02788                     now=0.0;
02789                     infiniteUpper--;
02790                   } else {
02791                     now = nowLower;
02792                   }
02793                   maximumUp += (newBound-now) * value;
02794                   nowLower = newBound;
02795 #ifdef DEBUG
02796                   checkCorrect(this,iRow,
02797                                element, rowStart, rowLength,
02798                                column,
02799                                columnLower_,  columnUpper_,
02800                                infiniteUpper,
02801                                infiniteLower,
02802                                maximumUp,
02803                                maximumDown);
02804 #endif
02805                 }
02806               }
02807             }
02808           }
02809         }
02810       }
02811     }
02812     totalTightened += numberChanged;
02813     if (iPass==1)
02814       numberCheck=numberChanged>>4;
02815     if (numberInfeasible) break;
02816   }
02817   if (!numberInfeasible) {
02818     handler_->message(CLP_SIMPLEX_BOUNDTIGHTEN,messages_)
02819       <<totalTightened
02820       <<CoinMessageEol;
02821     // Set bounds slightly loose
02822     double useTolerance = 1.0e-3;
02823     for (iColumn=0;iColumn<numberColumns_;iColumn++) {
02824       if (saveUpper[iColumn]>saveLower[iColumn]+useTolerance) {
02825         if (columnUpper_[iColumn]-columnLower_[iColumn]<useTolerance+1.0e8) {
02826           // relax enough so will have correct dj
02827 #if 1
02828           columnLower_[iColumn]=max(saveLower[iColumn],
02829                                     columnLower_[iColumn]-100.0*useTolerance);
02830           columnUpper_[iColumn]=min(saveUpper[iColumn],
02831                                     columnUpper_[iColumn]+100.0*useTolerance);
02832 #else
02833           if (fabs(columnUpper_[iColumn])<fabs(columnLower_[iColumn])) {
02834             if (columnUpper_[iColumn]- 100.0*useTolerance>saveLower[iColumn]) {
02835               columnLower_[iColumn]=columnUpper_[iColumn]-100.0*useTolerance;
02836             } else {
02837               columnLower_[iColumn]=saveLower[iColumn];
02838               columnUpper_[iColumn]=min(saveUpper[iColumn],
02839                                         saveLower[iColumn]+100.0*useTolerance);
02840             }
02841           } else {
02842             if (columnLower_[iColumn]+100.0*useTolerance<saveUpper[iColumn]) {
02843               columnUpper_[iColumn]=columnLower_[iColumn]+100.0*useTolerance;
02844             } else {
02845               columnUpper_[iColumn]=saveUpper[iColumn];
02846               columnLower_[iColumn]=max(saveLower[iColumn],
02847                                         saveUpper[iColumn]-100.0*useTolerance);
02848             }
02849           }
02850 #endif
02851         } else {
02852           if (columnUpper_[iColumn]<saveUpper[iColumn]) {
02853             // relax a bit
02854             columnUpper_[iColumn] = min(columnUpper_[iColumn]+100.0*useTolerance,
02855                                         saveUpper[iColumn]);
02856           }
02857           if (columnLower_[iColumn]>saveLower[iColumn]) {
02858             // relax a bit
02859             columnLower_[iColumn] = max(columnLower_[iColumn]-100.0*useTolerance,
02860                                         saveLower[iColumn]);
02861           }
02862         }
02863       }
02864     }
02865   } else {
02866     handler_->message(CLP_SIMPLEX_INFEASIBILITIES,messages_)
02867       <<numberInfeasible
02868       <<CoinMessageEol;
02869     // restore column bounds
02870     memcpy(columnLower_,saveLower,numberColumns_*sizeof(double));
02871     memcpy(columnUpper_,saveUpper,numberColumns_*sizeof(double));
02872   }
02873   delete [] saveLower;
02874   delete [] saveUpper;
02875   return (numberInfeasible);
02876 }
02877 // dual 
02878 #include "ClpSimplexDual.hpp"
02879 #include "ClpSimplexPrimal.hpp"
02880 int ClpSimplex::dual (int ifValuesPass )
02881 {
02882   assert (ifValuesPass>=0&&ifValuesPass<2);
02883   int returnCode = ((ClpSimplexDual *) this)->dual(ifValuesPass);
02884   if (problemStatus_==10) {
02885     //printf("Cleaning up with primal\n");
02886     int savePerturbation = perturbation_;
02887     perturbation_=100;
02888     bool denseFactorization = initialDenseFactorization();
02889     // It will be safe to allow dense
02890     setInitialDenseFactorization(true);
02891     returnCode = ((ClpSimplexPrimal *) this)->primal(1);
02892     setInitialDenseFactorization(denseFactorization);
02893     perturbation_=savePerturbation;
02894     if (problemStatus_==10) 
02895       problemStatus_=0;
02896   }
02897   return returnCode;
02898 }
02899 // primal 
02900 int ClpSimplex::primal (int ifValuesPass )
02901 {
02902   assert (ifValuesPass>=0&&ifValuesPass<2);
02903   int returnCode = ((ClpSimplexPrimal *) this)->primal(ifValuesPass);
02904   if (problemStatus_==10) {
02905     //printf("Cleaning up with dual\n");
02906     int savePerturbation = perturbation_;
02907     perturbation_=100;
02908     bool denseFactorization = initialDenseFactorization();
02909     // It will be safe to allow dense
02910     setInitialDenseFactorization(true);
02911     returnCode = ((ClpSimplexDual *) this)->dual(0);
02912     setInitialDenseFactorization(denseFactorization);
02913     perturbation_=savePerturbation;
02914     if (problemStatus_==10) 
02915       problemStatus_=0;
02916   }
02917   return returnCode;
02918 }
02919 #include "ClpSimplexPrimalQuadratic.hpp"
02920 /* Solves quadratic problem using SLP - may be used as crash
02921    for other algorithms when number of iterations small
02922 */
02923 int 
02924 ClpSimplex::quadraticSLP(int numberPasses, double deltaTolerance)
02925 {
02926   return ((ClpSimplexPrimalQuadratic *) this)->primalSLP(numberPasses,deltaTolerance);
02927 }
02928 // Solves quadratic using Dantzig's algorithm - primal
02929 int 
02930 ClpSimplex::quadraticPrimal(int phase)
02931 {
02932   return ((ClpSimplexPrimalQuadratic *) this)->primalQuadratic(phase);
02933 }
02934 /* For strong branching.  On input lower and upper are new bounds
02935    while on output they are objective function values (>1.0e50 infeasible).
02936    Return code is 0 if nothing interesting, -1 if infeasible both
02937    ways and +1 if infeasible one way (check values to see which one(s))
02938 */
02939 int ClpSimplex::strongBranching(int numberVariables,const int * variables,
02940                                 double * newLower, double * newUpper,
02941                                 double ** outputSolution,
02942                                 int * outputStatus, int * outputIterations,
02943                                 bool stopOnFirstInfeasible,
02944                                 bool alwaysFinish)
02945 {
02946   return ((ClpSimplexDual *) this)->strongBranching(numberVariables,variables,
02947                                                     newLower,  newUpper,outputSolution,
02948                                                     outputStatus, outputIterations,
02949                                                     stopOnFirstInfeasible,
02950                                                     alwaysFinish);
02951 }
02952 /* Borrow model.  This is so we dont have to copy large amounts
02953    of data around.  It assumes a derived class wants to overwrite
02954    an empty model with a real one - while it does an algorithm.
02955    This is same as ClpModel one, but sets scaling on etc. */
02956 void 
02957 ClpSimplex::borrowModel(ClpModel & otherModel) 
02958 {
02959   ClpModel::borrowModel(otherModel);
02960   createStatus();
02961   ClpDualRowSteepest steep1;
02962   setDualRowPivotAlgorithm(steep1);
02963   ClpPrimalColumnSteepest steep2;
02964   setPrimalColumnPivotAlgorithm(steep2);
02965 }
02966 typedef struct {
02967   double optimizationDirection;
02968   double dblParam[ClpLastDblParam];
02969   double objectiveValue;
02970   double dualBound;
02971   double dualTolerance;
02972   double primalTolerance;
02973   double sumDualInfeasibilities;
02974   double sumPrimalInfeasibilities;
02975   double infeasibilityCost;
02976   int numberRows;
02977   int numberColumns;
02978   int intParam[ClpLastIntParam];
02979   int numberIterations;
02980   int problemStatus;
02981   int maximumIterations;
02982   int lengthNames;
02983   int numberDualInfeasibilities;
02984   int numberDualInfeasibilitiesWithoutFree;
02985   int numberPrimalInfeasibilities;
02986   int numberRefinements;
02987   int scalingFlag;
02988   int algorithm;
02989   unsigned int specialOptions;
02990   int dualPivotChoice;
02991   int primalPivotChoice;
02992   int matrixStorageChoice;
02993 } Clp_scalars;
02994 
02995 int outDoubleArray(double * array, int length, FILE * fp)
02996 {
02997   int numberWritten;
02998   if (array&&length) {
02999     numberWritten = fwrite(&length,sizeof(int),1,fp);
03000     if (numberWritten!=1)
03001       return 1;
03002     numberWritten = fwrite(array,sizeof(double),length,fp);
03003     if (numberWritten!=length)
03004       return 1;
03005   } else {
03006     length = 0;
03007     numberWritten = fwrite(&length,sizeof(int),1,fp);
03008     if (numberWritten!=1)
03009       return 1;
03010   }
03011   return 0;
03012 }
03013 // Save model to file, returns 0 if success
03014 int
03015 ClpSimplex::saveModel(const char * fileName)
03016 {
03017   FILE * fp = fopen(fileName,"wb");
03018   if (fp) {
03019     Clp_scalars scalars;
03020     int i;
03021     CoinBigIndex numberWritten;
03022     // Fill in scalars
03023     scalars.optimizationDirection = optimizationDirection_;
03024     memcpy(scalars.dblParam, dblParam_,ClpLastDblParam * sizeof(double));
03025     scalars.objectiveValue = objectiveValue_;
03026     scalars.dualBound = dualBound_;
03027     scalars.dualTolerance = dualTolerance_;
03028     scalars.primalTolerance = primalTolerance_;
03029     scalars.sumDualInfeasibilities = sumDualInfeasibilities_;
03030     scalars.sumPrimalInfeasibilities = sumPrimalInfeasibilities_;
03031     scalars.infeasibilityCost = infeasibilityCost_;
03032     scalars.numberRows = numberRows_;
03033     scalars.numberColumns = numberColumns_;
03034     memcpy(scalars.intParam, intParam_,ClpLastIntParam * sizeof(double));
03035     scalars.numberIterations = numberIterations_;
03036     scalars.problemStatus = problemStatus_;
03037     scalars.maximumIterations = maximumIterations();
03038     scalars.lengthNames = lengthNames_;
03039     scalars.numberDualInfeasibilities = numberDualInfeasibilities_;
03040     scalars.numberDualInfeasibilitiesWithoutFree 
03041       = numberDualInfeasibilitiesWithoutFree_;
03042     scalars.numberPrimalInfeasibilities = numberPrimalInfeasibilities_;
03043     scalars.numberRefinements = numberRefinements_;
03044     scalars.scalingFlag = scalingFlag_;
03045     scalars.algorithm = algorithm_;
03046     scalars.specialOptions = specialOptions_;
03047     scalars.dualPivotChoice = dualRowPivot_->type();
03048     scalars.primalPivotChoice = primalColumnPivot_->type();
03049     scalars.matrixStorageChoice = matrix_->type();
03050 
03051     // put out scalars
03052     numberWritten = fwrite(&scalars,sizeof(Clp_scalars),1,fp);
03053     if (numberWritten!=1)
03054       return 1;
03055     // strings
03056     CoinBigIndex length;
03057     for (i=0;i<ClpLastStrParam;i++) {
03058       length = strParam_[i].size();
03059       numberWritten = fwrite(&length,sizeof(int),1,fp);
03060       if (numberWritten!=1)
03061         return 1;
03062       if (length) {
03063         numberWritten = fwrite(strParam_[i].c_str(),length,1,fp);
03064         if (numberWritten!=1)
03065           return 1;
03066       }
03067     }
03068     // arrays - in no particular order
03069     if (outDoubleArray(rowActivity_,numberRows_,fp))
03070         return 1;
03071     if (outDoubleArray(columnActivity_,numberColumns_,fp))
03072         return 1;
03073     if (outDoubleArray(dual_,numberRows_,fp))
03074         return 1;
03075     if (outDoubleArray(reducedCost_,numberColumns_,fp))
03076         return 1;
03077     if (outDoubleArray(rowLower_,numberRows_,fp))
03078         return 1;
03079     if (outDoubleArray(rowUpper_,numberRows_,fp))
03080         return 1;
03081     if (outDoubleArray(objective(),numberColumns_,fp))
03082         return 1;
03083     if (outDoubleArray(rowObjective_,numberRows_,fp))
03084         return 1;
03085     if (outDoubleArray(columnLower_,numberColumns_,fp))
03086         return 1;
03087     if (outDoubleArray(columnUpper_,numberColumns_,fp))
03088         return 1;
03089     if (ray_) {
03090       if (problemStatus_==1)
03091         if (outDoubleArray(ray_,numberRows_,fp))
03092           return 1;
03093       else if (problemStatus_==2)
03094         if (outDoubleArray(ray_,numberColumns_,fp))
03095           return 1;
03096       else
03097         if (outDoubleArray(NULL,0,fp))
03098           return 1;
03099     } else {
03100       if (outDoubleArray(NULL,0,fp))
03101         return 1;
03102     }
03103     if (status_&&(numberRows_+numberColumns_)>0) {
03104       length = numberRows_+numberColumns_;
03105       numberWritten = fwrite(&length,sizeof(int),1,fp);
03106       if (numberWritten!=1)
03107         return 1;
03108       numberWritten = fwrite(status_,sizeof(char),length, fp);
03109       if (numberWritten!=length)
03110         return 1;
03111     } else {
03112       length = 0;
03113       numberWritten = fwrite(&length,sizeof(int),1,fp);
03114       if (numberWritten!=1)
03115         return 1;
03116     }
03117     if (lengthNames_) {
03118       char * array = 
03119         new char[max(numberRows_,numberColumns_)*(lengthNames_+1)];
03120       char * put = array;
03121       assert (numberRows_ == (int) rowNames_.size());
03122       for (i=0;i<numberRows_;i++) {
03123         assert((int)rowNames_[i].size()<=lengthNames_);
03124         strcpy(put,rowNames_[i].c_str());
03125         put += lengthNames_+1;
03126       }
03127       numberWritten = fwrite(array,lengthNames_+1,numberRows_,fp);
03128       if (numberWritten!=numberRows_)
03129         return 1;
03130       put=array;
03131       assert (numberColumns_ == (int) columnNames_.size());
03132       for (i=0;i<numberColumns_;i++) {
03133         assert((int) columnNames_[i].size()<=lengthNames_);
03134         strcpy(put,columnNames_[i].c_str());
03135         put += lengthNames_+1;
03136       }
03137       numberWritten = fwrite(array,lengthNames_+1,numberColumns_,fp);
03138       if (numberWritten!=numberColumns_)
03139         return 1;
03140       delete [] array;
03141     }
03142     // just standard type at present
03143     assert (matrix_->type()==1);
03144     assert (matrix_->getNumCols() == numberColumns_);
03145     assert (matrix_->getNumRows() == numberRows_);
03146     // we are going to save with gaps
03147     length = matrix_->getVectorStarts()[numberColumns_-1]
03148       + matrix_->getVectorLengths()[numberColumns_-1];
03149     numberWritten = fwrite(&length,sizeof(int),1,fp);
03150     if (numberWritten!=1)
03151       return 1;
03152     numberWritten = fwrite(matrix_->getElements(),
03153                            sizeof(double),length,fp);
03154     if (numberWritten!=length)
03155       return 1;
03156     numberWritten = fwrite(matrix_->getIndices(),
03157                            sizeof(int),length,fp);
03158     if (numberWritten!=length)
03159       return 1;
03160     numberWritten = fwrite(matrix_->getVectorStarts(),
03161                            sizeof(int),numberColumns_+1,fp);
03162     if (numberWritten!=numberColumns_+1)
03163       return 1;
03164     numberWritten = fwrite(matrix_->getVectorLengths(),
03165                            sizeof(int),numberColumns_,fp);
03166     if (numberWritten!=numberColumns_)
03167       return 1;
03168     // finished
03169     fclose(fp);
03170     return 0;
03171   } else {
03172     return -1;
03173   }
03174 }
03175 
03176 int inDoubleArray(double * &array, int length, FILE * fp)
03177 {
03178   int numberRead;
03179   int length2;
03180   numberRead = fread(&length2,sizeof(int),1,fp);
03181   if (numberRead!=1)
03182     return 1;
03183   if (length2) {
03184     // lengths must match
03185     if (length!=length2)
03186       return 2;
03187     array = new double[length];
03188     numberRead = fread(array,sizeof(double),length,fp);
03189     if (numberRead!=length)
03190       return 1;
03191   } 
03192   return 0;
03193 }
03194 /* Restore model from file, returns 0 if success,
03195    deletes current model */
03196 int 
03197 ClpSimplex::restoreModel(const char * fileName)
03198 {
03199   FILE * fp = fopen(fileName,"rb");
03200   if (fp) {
03201     // Get rid of current model
03202     ClpModel::gutsOfDelete();
03203     gutsOfDelete(0);
03204     int i;
03205     for (i=0;i<6;i++) {
03206       rowArray_[i]=NULL;
03207       columnArray_[i]=NULL;
03208     }
03209     // get an empty factorization so we can set tolerances etc
03210     factorization_ = new ClpFactorization();
03211     // Say sparse
03212     factorization_->sparseThreshold(1);
03213     Clp_scalars scalars;
03214     CoinBigIndex numberRead;
03215 
03216     // get scalars
03217     numberRead = fread(&scalars,sizeof(Clp_scalars),1,fp);
03218     if (numberRead!=1)
03219       return 1;
03220     // Fill in scalars
03221     optimizationDirection_ = scalars.optimizationDirection;
03222     memcpy(dblParam_, scalars.dblParam, ClpLastDblParam * sizeof(double));
03223     objectiveValue_ = scalars.objectiveValue;
03224     dualBound_ = scalars.dualBound;
03225     dualTolerance_ = scalars.dualTolerance;
03226     primalTolerance_ = scalars.primalTolerance;
03227     sumDualInfeasibilities_ = scalars.sumDualInfeasibilities;
03228     sumPrimalInfeasibilities_ = scalars.sumPrimalInfeasibilities;
03229     infeasibilityCost_ = scalars.infeasibilityCost;
03230     numberRows_ = scalars.numberRows;
03231     numberColumns_ = scalars.numberColumns;
03232     memcpy(intParam_, scalars.intParam,ClpLastIntParam * sizeof(double));
03233     numberIterations_ = scalars.numberIterations;
03234     problemStatus_ = scalars.problemStatus;
03235     setMaximumIterations(scalars.maximumIterations);
03236     lengthNames_ = scalars.lengthNames;
03237     numberDualInfeasibilities_ = scalars.numberDualInfeasibilities;
03238     numberDualInfeasibilitiesWithoutFree_ 
03239       = scalars.numberDualInfeasibilitiesWithoutFree;
03240     numberPrimalInfeasibilities_ = scalars.numberPrimalInfeasibilities;
03241     numberRefinements_ = scalars.numberRefinements;
03242     scalingFlag_ = scalars.scalingFlag;
03243     algorithm_ = scalars.algorithm;
03244     specialOptions_ = scalars.specialOptions;
03245     // strings
03246     CoinBigIndex length;
03247     for (i=0;i<ClpLastStrParam;i++) {
03248       numberRead = fread(&length,sizeof(int),1,fp);
03249       if (numberRead!=1)
03250         return 1;
03251       if (length) {
03252         char * array = new char[length+1];
03253         numberRead = fread(array,length,1,fp);
03254         if (numberRead!=1)
03255           return 1;
03256         array[length]='\0';
03257         strParam_[i]=array;
03258         delete [] array;
03259       }
03260     }
03261     // arrays - in no particular order
03262     if (inDoubleArray(rowActivity_,numberRows_,fp))
03263         return 1;
03264     if (inDoubleArray(columnActivity_,numberColumns_,fp))
03265         return 1;
03266     if (inDoubleArray(dual_,numberRows_,fp))
03267         return 1;
03268     if (inDoubleArray(reducedCost_,numberColumns_,fp))
03269         return 1;
03270     if (inDoubleArray(rowLower_,numberRows_,fp))
03271         return 1;
03272     if (inDoubleArray(rowUpper_,numberRows_,fp))
03273         return 1;
03274     double * objective;
03275     if (inDoubleArray(objective,numberColumns_,fp))
03276         return 1;
03277     delete objective_;
03278     objective_ = new ClpLinearObjective(objective,numberColumns_);
03279     delete [] objective;
03280     if (inDoubleArray(rowObjective_,numberRows_,fp))
03281         return 1;
03282     if (inDoubleArray(columnLower_,numberColumns_,fp))
03283         return 1;
03284     if (inDoubleArray(columnUpper_,numberColumns_,fp))
03285         return 1;
03286     if (problemStatus_==1) {
03287       if (inDoubleArray(ray_,numberRows_,fp))
03288         return 1;
03289     } else if (problemStatus_==2) {
03290       if (inDoubleArray(ray_,numberColumns_,fp))
03291         return 1;
03292     } else {
03293       // ray should be null
03294       numberRead = fread(&length,sizeof(int),1,fp);
03295       if (numberRead!=1)
03296         return 1;
03297       if (length)
03298         return 2;
03299     }
03300     delete [] status_;
03301     status_=NULL;
03302     // status region
03303     numberRead = fread(&length,sizeof(int),1,fp);
03304     if (numberRead!=1)
03305         return 1;
03306     if (length) {
03307       if (length!=numberRows_+numberColumns_)
03308         return 1;
03309       status_ = new char unsigned[length];
03310       numberRead = fread(status_,sizeof(char),length, fp);
03311       if (numberRead!=length)
03312         return 1;
03313     }
03314     if (lengthNames_) {
03315       char * array = 
03316         new char[max(numberRows_,numberColumns_)*(lengthNames_+1)];
03317       char * get = array;
03318       numberRead = fread(array,lengthNames_+1,numberRows_,fp);
03319       if (numberRead!=numberRows_)
03320         return 1;
03321       rowNames_ = std::vector<std::string> ();
03322       rowNames_.resize(numberRows_);
03323       for (i=0;i<numberRows_;i++) {
03324         rowNames_.push_back(get);
03325         get += lengthNames_+1;
03326       }
03327       get = array;
03328       numberRead = fread(array,lengthNames_+1,numberColumns_,fp);
03329       if (numberRead!=numberColumns_)
03330         return 1;
03331       columnNames_ = std::vector<std::string> ();
03332       columnNames_.resize(numberColumns_);
03333       for (i=0;i<numberColumns_;i++) {
03334         columnNames_.push_back(get);
03335         get += lengthNames_+1;
03336       }
03337       delete [] array;
03338     }
03339     // Pivot choices
03340     assert(scalars.dualPivotChoice>0&&(scalars.dualPivotChoice&63)<3);
03341     delete dualRowPivot_;
03342     switch ((scalars.dualPivotChoice&63)) {
03343     default:
03344       printf("Need another dualPivot case %d\n",scalars.dualPivotChoice&63);
03345     case 1:
03346       // Dantzig
03347       dualRowPivot_ = new ClpDualRowDantzig();
03348       break;
03349     case 2:
03350       // Steepest - use mode
03351       dualRowPivot_ = new ClpDualRowSteepest(scalars.dualPivotChoice>>6);
03352       break;
03353     }
03354     assert(scalars.primalPivotChoice>0&&(scalars.primalPivotChoice&63)<3);
03355     delete primalColumnPivot_;
03356     switch ((scalars.primalPivotChoice&63)) {
03357     default:
03358       printf("Need another primalPivot case %d\n",
03359              scalars.primalPivotChoice&63);
03360     case 1:
03361       // Dantzig
03362       primalColumnPivot_ = new ClpPrimalColumnDantzig();
03363       break;
03364     case 2:
03365       // Steepest - use mode
03366       primalColumnPivot_ 
03367         = new ClpPrimalColumnSteepest(scalars.primalPivotChoice>>6);
03368       break;
03369     }
03370     assert(scalars.matrixStorageChoice==1);
03371     delete matrix_;
03372     // get arrays
03373     numberRead = fread(&length,sizeof(int),1,fp);
03374     if (numberRead!=1)
03375       return 1;
03376     double * elements = new double[length];
03377     int * indices = new int[length];
03378     CoinBigIndex * starts = new CoinBigIndex[numberColumns_+1];
03379     int * lengths = new int[numberColumns_];
03380     numberRead = fread(elements, sizeof(double),length,fp);
03381     if (numberRead!=length)
03382       return 1;
03383     numberRead = fread(indices, sizeof(int),length,fp);
03384     if (numberRead!=length)
03385       return 1;
03386     numberRead = fread(starts, sizeof(int),numberColumns_+1,fp);
03387     if (numberRead!=numberColumns_+1)
03388       return 1;
03389     numberRead = fread(lengths, sizeof(int),numberColumns_,fp);
03390     if (numberRead!=numberColumns_)
03391       return 1;
03392     // assign matrix
03393     CoinPackedMatrix * matrix = new CoinPackedMatrix();
03394     matrix->assignMatrix(true, numberRows_, numberColumns_,
03395                          length, elements, indices, starts, lengths);
03396     // and transfer to Clp
03397     matrix_ = new ClpPackedMatrix(matrix);
03398     // finished
03399     fclose(fp);
03400     return 0;
03401   } else {
03402     return -1;
03403   }
03404   return 0;
03405 }
03406 // value of incoming variable (in Dual)
03407 double 
03408 ClpSimplex::valueIncomingDual() const
03409 {
03410   // Need value of incoming for list of infeasibilities as may be infeasible
03411   double valueIncoming = (dualOut_/alpha_)*directionOut_;
03412   if (directionIn_==-1)
03413     valueIncoming = upperIn_-valueIncoming;
03414   else
03415     valueIncoming = lowerIn_-valueIncoming;
03416   return valueIncoming;
03417 }
03418 // Sanity check on input data - returns true if okay
03419 bool 
03420 ClpSimplex::sanityCheck()
03421 {
03422   // bad if empty
03423   if (!numberRows_||!numberColumns_||!matrix_->getNumElements()) {
03424     handler_->message(CLP_EMPTY_PROBLEM,messages_)
03425       <<numberRows_
03426       <<numberColumns_
03427       <<matrix_->getNumElements()
03428       <<CoinMessageEol;
03429     problemStatus_=4;
03430     return false;
03431   }
03432   int numberBad ;
03433   double largestBound, smallestBound, minimumGap;
03434   double smallestObj, largestObj;
03435   int firstBad;
03436   int modifiedBounds=0;
03437   int i;
03438   numberBad=0;
03439   firstBad=-1;
03440   minimumGap=1.0e100;
03441   smallestBound=1.0e100;
03442   largestBound=0.0;
03443   smallestObj=1.0e100;
03444   largestObj=0.0;
03445   // If bounds are too close - fix
03446   double fixTolerance = 10.0*primalTolerance_;
03447   for (i=numberColumns_;i<numberColumns_+numberRows_;i++) {
03448     double value;
03449     value = fabs(cost_[i]);
03450     if (value>1.0e50) {
03451       numberBad++;
03452       if (firstBad<0)
03453         firstBad=i;
03454     } else if (value) {
03455       if (value>largestObj)
03456         largestObj=value;
03457       if (value<smallestObj)
03458         smallestObj=value;
03459     }
03460     value=upper_[i]-lower_[i];
03461     if (value<-primalTolerance_) {
03462       numberBad++;
03463       if (firstBad<0)
03464         firstBad=i;
03465     } else if (value<=fixTolerance) {
03466       if (value) {
03467         // modify
03468         upper_[i] = lower_[i];
03469         modifiedBounds++;
03470       }
03471     } else {
03472       if (value<minimumGap)
03473         minimumGap=value;
03474     }
03475     if (lower_[i]>-1.0e100&&lower_[i]) {
03476       value = fabs(lower_[i]);
03477       if (value>largestBound)
03478         largestBound=value;
03479       if (value<smallestBound)
03480         smallestBound=value;
03481     }
03482     if (upper_[i]<1.0e100&&upper_[i]) {
03483       value = fabs(upper_[i]);
03484       if (value>largestBound)
03485         largestBound=value;
03486       if (value<smallestBound)
03487         smallestBound=value;
03488     }
03489   }
03490   if (largestBound)
03491     handler_->message(CLP_RIMSTATISTICS3,messages_)
03492       <<smallestBound
03493       <<largestBound
03494       <<minimumGap
03495       <<CoinMessageEol;
03496   minimumGap=1.0e100;
03497   smallestBound=1.0e100;
03498   largestBound=0.0;
03499   for (i=0;i<numberColumns_;i++) {
03500     double value;
03501     value = fabs(cost_[i]);
03502     if (value>1.0e50) {
03503       numberBad++;
03504       if (firstBad<0)
03505         firstBad=i;
03506     } else if (value) {
03507       if (value>largestObj)
03508         largestObj=value;
03509       if (value<smallestObj)
03510         smallestObj=value;
03511     }
03512     value=upper_[i]-lower_[i];
03513     if (value<-primalTolerance_) {
03514       numberBad++;
03515       if (firstBad<0)
03516         firstBad=i;
03517     } else if (value<=fixTolerance) {
03518       if (value) {
03519         // modify
03520         upper_[i] = lower_[i];
03521         modifiedBounds++;
03522       }
03523     } else {
03524       if (value<minimumGap)
03525         minimumGap=value;
03526     }
03527     if (lower_[i]>-1.0e100&&lower_[i]) {
03528       value = fabs(lower_[i]);
03529       if (value>largestBound)
03530         largestBound=value;
03531       if (value<smallestBound)
03532         smallestBound=value;
03533     }
03534     if (upper_[i]<1.0e100&&upper_[i]) {
03535       value = fabs(upper_[i]);
03536       if (value>largestBound)
03537         largestBound=value;
03538       if (value<smallestBound)
03539         smallestBound=value;
03540     }
03541   }
03542   char rowcol[]={'R','C'};
03543   if (numberBad) {
03544     handler_->message(CLP_BAD_BOUNDS,messages_)
03545       <<numberBad
03546       <<rowcol[isColumn(firstBad)]<<sequenceWithin(firstBad)
03547       <<CoinMessageEol;
03548     problemStatus_=4;
03549     return false;
03550   }
03551   if (modifiedBounds)
03552     handler_->message(CLP_MODIFIEDBOUNDS,messages_)
03553       <<modifiedBounds
03554       <<CoinMessageEol;
03555   handler_->message(CLP_RIMSTATISTICS1,messages_)
03556     <<smallestObj
03557     <<largestObj
03558     <<CoinMessageEol;  if (largestBound)
03559     handler_->message(CLP_RIMSTATISTICS2,messages_)
03560       <<smallestBound
03561       <<largestBound
03562       <<minimumGap
03563       <<CoinMessageEol;
03564   return true;
03565 }
03566 // Set up status array (for OsiClp)
03567 void 
03568 ClpSimplex::createStatus() 
03569 {
03570   if(!status_)
03571     status_ = new unsigned char [numberColumns_+numberRows_];
03572   memset(status_,0,(numberColumns_+numberRows_)*sizeof(char));
03573   int i;
03574   // set column status to one nearest zero
03575   for (i=0;i<numberColumns_;i++) {
03576 #if 0
03577     if (columnLower_[i]>=0.0) {
03578       setColumnStatus(i,atLowerBound);
03579     } else if (columnUpper_[i]<=0.0) {
03580       setColumnStatus(i,atUpperBound);
03581     } else if (columnLower_[i]<-1.0e20&&columnUpper_[i]>1.0e20) {
03582       // free
03583       setColumnStatus(i,isFree);
03584     } else if (fabs(columnLower_[i])<fabs(columnUpper_[i])) {
03585       setColumnStatus(i,atLowerBound);
03586     } else {
03587       setColumnStatus(i,atUpperBound);
03588     }
03589 #else
03590     setColumnStatus(i,atLowerBound);
03591 #endif
03592   }
03593   for (i=0;i<numberRows_;i++) {
03594     setRowStatus(i,basic);
03595   }
03596 }
03597 /* Loads a problem (the constraints on the
03598    rows are given by lower and upper bounds). If a pointer is 0 then the
03599    following values are the default:
03600    <ul>
03601    <li> <code>colub</code>: all columns have upper bound infinity
03602    <li> <code>collb</code>: all columns have lower bound 0 
03603    <li> <code>rowub</code>: all rows have upper bound infinity
03604    <li> <code>rowlb</code>: all rows have lower bound -infinity
03605    <li> <code>obj</code>: all variables have 0 objective coefficient
03606    </ul>
03607 */
03608 void 
03609 ClpSimplex::loadProblem (  const ClpMatrixBase& matrix,
03610                     const double* collb, const double* colub,   
03611                     const double* obj,
03612                     const double* rowlb, const double* rowub,
03613                     const double * rowObjective)
03614 {
03615   ClpModel::loadProblem(matrix, collb, colub, obj, rowlb, rowub,
03616                         rowObjective);
03617   createStatus();
03618 }
03619 void 
03620 ClpSimplex::loadProblem (  const CoinPackedMatrix& matrix,
03621                     const double* collb, const double* colub,   
03622                     const double* obj,
03623                     const double* rowlb, const double* rowub,
03624                     const double * rowObjective)
03625 {
03626   ClpModel::loadProblem(matrix, collb, colub, obj, rowlb, rowub,
03627                         rowObjective);
03628   createStatus();
03629 }
03630 
03631 /* Just like the other loadProblem() method except that the matrix is
03632    given in a standard column major ordered format (without gaps). */
03633 void 
03634 ClpSimplex::loadProblem (  const int numcols, const int numrows,
03635                     const CoinBigIndex* start, const int* index,
03636                     const double* value,
03637                     const double* collb, const double* colub,   
03638                     const double* obj,
03639                     const double* rowlb, const double* rowub,
03640                     const double * rowObjective)
03641 {
03642   ClpModel::loadProblem(numcols, numrows, start, index, value,
03643                           collb, colub, obj, rowlb, rowub,
03644                           rowObjective);
03645   createStatus();
03646 }
03647 void 
03648 ClpSimplex::loadProblem (  const int numcols, const int numrows,
03649                            const CoinBigIndex* start, const int* index,
03650                            const double* value,const int * length,
03651                            const double* collb, const double* colub,   
03652                            const double* obj,
03653                            const double* rowlb, const double* rowub,
03654                            const double * rowObjective)
03655 {
03656   ClpModel::loadProblem(numcols, numrows, start, index, value, length,
03657                           collb, colub, obj, rowlb, rowub,
03658                           rowObjective);
03659   createStatus();
03660 }
03661 // Read an mps file from the given filename
03662 int 
03663 ClpSimplex::readMps(const char *filename,
03664             bool keepNames,
03665             bool ignoreErrors)
03666 {
03667   int status = ClpModel::readMps(filename,keepNames,ignoreErrors);
03668   createStatus();
03669   return status;
03670 }
03671 // Just check solution (for external use)
03672 void 
03673 ClpSimplex::checkSolution()
03674 {
03675   // put in standard form
03676   createRim(7+8+16);
03677   dualTolerance_=dblParam_[ClpDualTolerance];
03678   primalTolerance_=dblParam_[ClpPrimalTolerance];
03679   checkPrimalSolution( rowActivityWork_, columnActivityWork_);
03680   checkDualSolution();
03681   if (!numberDualInfeasibilities_&&
03682       !numberPrimalInfeasibilities_)
03683     problemStatus_=0;
03684   else
03685     problemStatus_=-1;
03686 #ifdef CLP_DEBUG
03687   int i;
03688   double value=0.0;
03689   for (i=0;i<numberRows_+numberColumns_;i++)
03690     value += dj_[i]*solution_[i];
03691   printf("dual value %g, primal %g\n",value,objectiveValue());
03692 #endif
03693   // release extra memory
03694   deleteRim(0);
03695 }
03696 /* Crash - at present just aimed at dual, returns
03697    -2 if dual preferred and crash basis created
03698    -1 if dual preferred and all slack basis preferred
03699    0 if basis going in was not all slack
03700    1 if primal preferred and all slack basis preferred
03701    2 if primal preferred and crash basis created.
03702    
03703    if gap between bounds <="gap" variables can be flipped
03704    
03705    If "pivot" is
03706    0 No pivoting (so will just be choice of algorithm)
03707    1 Simple pivoting e.g. gub
03708    2 Mini iterations
03709 */
03710 int 
03711 ClpSimplex::crash(double gap,int pivot)
03712 {
03713   assert(!rowObjective_); // not coded
03714   int iColumn;
03715   int numberBad=0;
03716   int numberBasic=0;
03717   double dualTolerance=dblParam_[ClpDualTolerance];
03718   //double primalTolerance=dblParam_[ClpPrimalTolerance];
03719   int returnCode=0;
03720   // If no basis then make all slack one
03721   if (!status_)
03722     createStatus();
03723   
03724   for (iColumn=0;iColumn<numberColumns_;iColumn++) {
03725     if (getColumnStatus(iColumn)==basic)
03726       numberBasic++;
03727   }
03728   if (!numberBasic) {
03729     // all slack
03730     double * dj = new double [numberColumns_];
03731     double * solution = columnActivity_;
03732     const double * linearObjective = objective();
03733     //double objectiveValue=0.0;
03734     int iColumn;
03735     double direction = optimizationDirection_;
03736     // direction is actually scale out not scale in
03737     if (direction)
03738       direction = 1.0/direction;
03739     for (iColumn=0;iColumn<numberColumns_;iColumn++)
03740       dj[iColumn] = direction*linearObjective[iColumn];
03741     for (iColumn=0;iColumn<numberColumns_;iColumn++) {
03742       // assume natural place is closest to zero
03743       double lowerBound = columnLower_[iColumn];
03744       double upperBound = columnUpper_[iColumn];
03745       if (lowerBound>-1.0e20||upperBound<1.0e20) {
03746         bool atLower;
03747         if (fabs(upperBound)<fabs(lowerBound)) {
03748           atLower=false;
03749           setColumnStatus(iColumn,atUpperBound);
03750           solution[iColumn]=upperBound;
03751         } else {
03752           atLower=true;
03753           setColumnStatus(iColumn,atLowerBound);
03754           solution[iColumn]=lowerBound;
03755         }
03756         if (dj[iColumn]<0.0) {
03757           // should be at upper bound
03758           if (atLower) {
03759             // can we flip
03760             if (upperBound-lowerBound<=gap) {
03761               columnActivity_[iColumn]=upperBound;
03762               setColumnStatus(iColumn,atUpperBound);
03763             } else if (dj[iColumn]<-dualTolerance) {
03764               numberBad++;
03765             }
03766           }
03767         } else if (dj[iColumn]>0.0) {
03768           // should be at lower bound
03769           if (!atLower) {
03770             // can we flip
03771             if (upperBound-lowerBound<=gap) {
03772               columnActivity_[iColumn]=lowerBound;
03773               setColumnStatus(iColumn,atLowerBound);
03774             } else if (dj[iColumn]>dualTolerance) {
03775               numberBad++;
03776             }
03777           }
03778         }
03779       } else {
03780         // free
03781         setColumnStatus(iColumn,isFree);
03782         if (fabs(dj[iColumn])>dualTolerance) 
03783           numberBad++;
03784       }
03785     }
03786     if (numberBad||pivot) {
03787       if (!pivot) {
03788         delete [] dj;
03789         returnCode = 1;
03790       } else {
03791         // see if can be made dual feasible with gubs etc
03792         double * pi = new double[numberRows_];
03793         memset (pi,0,numberRows_*sizeof(double));
03794         int * way = new int[numberColumns_];
03795         int numberIn = 0;
03796 
03797         // Get column copy
03798         CoinPackedMatrix * columnCopy = matrix();
03799         // Get a row copy in standard format
03800         CoinPackedMatrix copy;
03801         copy.reverseOrderedCopyOf(*columnCopy);
03802         // get matrix data pointers
03803         const int * column = copy.getIndices();
03804         const CoinBigIndex * rowStart = copy.getVectorStarts();
03805         const int * rowLength = copy.getVectorLengths(); 
03806         const double * elementByRow = copy.getElements();
03807         //const int * row = columnCopy->getIndices();
03808         //const CoinBigIndex * columnStart = columnCopy->getVectorStarts();
03809         //const int * columnLength = columnCopy->getVectorLengths(); 
03810         //const double * element = columnCopy->getElements();
03811 
03812 
03813         // if equality row and bounds mean artificial in basis bad
03814         // then do anyway
03815 
03816         for (iColumn=0;iColumn<numberColumns_;iColumn++) {
03817           // - if we want to reduce dj, + if we want to increase
03818           int thisWay = 100;
03819           double lowerBound = columnLower_[iColumn];
03820           double upperBound = columnUpper_[iColumn];
03821           if (upperBound>lowerBound) {
03822             switch(getColumnStatus(iColumn)) {
03823               
03824             case basic:
03825               thisWay=0;
03826             case ClpSimplex::isFixed:
03827               break;
03828             case isFree:
03829             case superBasic:
03830               if (dj[iColumn]<-dualTolerance) 
03831                 thisWay = 1;
03832               else if (dj[iColumn]>dualTolerance) 
03833                 thisWay = -1;
03834               else
03835                 thisWay =0;
03836               break;
03837             case atUpperBound:
03838               if (dj[iColumn]>dualTolerance) 
03839                 thisWay = -1;
03840               else if (dj[iColumn]<-dualTolerance) 
03841                 thisWay = -3;
03842               else
03843                 thisWay = -2;
03844               break;
03845             case atLowerBound:
03846               if (dj[iColumn]<-dualTolerance) 
03847                 thisWay = 1;
03848               else if (dj[iColumn]>dualTolerance) 
03849                 thisWay = 3;
03850               else
03851                 thisWay = 2;
03852               break;
03853             }
03854           }
03855           way[iColumn] = thisWay;
03856         }
03857         /*if (!numberBad)
03858           printf("Was dual feasible before passes - rows %d\n",
03859           numberRows_);*/
03860         int lastNumberIn = -100000;
03861         int numberPasses=5;
03862         while (numberIn>lastNumberIn+numberRows_/100) {
03863           lastNumberIn = numberIn;
03864           // we need to maximize chance of doing good
03865           int iRow;
03866           for (iRow=0;iRow<numberRows_;iRow++) {
03867             double lowerBound = rowLower_[iRow];
03868             double upperBound = rowUpper_[iRow];
03869             if (getRowStatus(iRow)==basic) {
03870               // see if we can find a column to pivot on
03871               int j;
03872               // down is amount pi can go down
03873               double maximumDown = COIN_DBL_MAX;
03874               double maximumUp = COIN_DBL_MAX;
03875               double minimumDown =0.0;
03876               double minimumUp =0.0;
03877               int iUp=-1;
03878               int iDown=-1;
03879               int iUpB=-1;
03880               int iDownB=-1;
03881               if (lowerBound<-1.0e20)
03882                 maximumUp = -1.0;
03883               if (upperBound>1.0e20)
03884                 maximumDown = -1.0;
03885               for (j=rowStart[iRow];j<rowStart[iRow]+rowLength[iRow];j++) {
03886                 int iColumn = column[j];
03887                 double value = elementByRow[j];
03888                 double djValue = dj[iColumn];
03889                 /* way -
03890                    -3 - okay at upper bound with negative dj
03891                    -2 - marginal at upper bound with zero dj - can only decrease
03892                    -1 - bad at upper bound
03893                    0 - we can never pivot on this row
03894                    1 - bad at lower bound
03895                    2 - marginal at lower bound with zero dj - can only increase
03896                    3 - okay at lower bound with positive dj
03897                    100 - fine we can just ignore
03898                 */
03899                 if (way[iColumn]!=100) {
03900                   switch(way[iColumn]) {
03901                     
03902                   case -3:
03903                     if (value>0.0) {
03904                       if (maximumDown*value>-djValue) {
03905                         maximumDown = -djValue/value;
03906                         iDown = iColumn;
03907                       }
03908                     } else {
03909                       if (-maximumUp*value>-djValue) {
03910                         maximumUp = djValue/value;
03911                         iUp = iColumn;
03912                       }
03913                     }
03914                     break;
03915                   case -2:
03916                     if (value>0.0) {
03917                       maximumDown = 0.0;
03918                     } else {
03919                       maximumUp = 0.0;
03920                     }
03921                     break;
03922                   case -1:
03923                     // see if could be satisfied
03924                     // dj value > 0
03925                     if (value>0.0) {
03926                       maximumDown=0.0;
03927                       if (maximumUp*value<djValue-dualTolerance) {
03928                         maximumUp = 0.0; // would improve but not enough
03929                       } else {
03930                         if (minimumUp*value<djValue) {
03931                           minimumUp = djValue/value;
03932                           iUpB = iColumn;
03933                         }
03934                       }
03935                     } else {
03936                       maximumUp=0.0;
03937                       if (-maximumDown*value<djValue-dualTolerance) {
03938                         maximumDown = 0.0; // would improve but not enough
03939                       } else {
03940                         if (-minimumDown*value<djValue) {
03941                           minimumDown = -djValue/value;
03942                           iDownB = iColumn;
03943                         }
03944                       }
03945                     }
03946                     
03947                     break;
03948                   case 0:
03949                     maximumDown = -1.0;
03950                     maximumUp=-1.0;
03951                     break;
03952                   case 1:
03953                     // see if could be satisfied
03954                     // dj value < 0
03955                     if (value>0.0) {
03956                       maximumUp=0.0;
03957                       if (maximumDown*value<-djValue-dualTolerance) {
03958                         maximumDown = 0.0; // would improve but not enough
03959                       } else {
03960                         if (minimumDown*value<-djValue) {
03961                           minimumDown = -djValue/value;
03962                           iDownB = iColumn;
03963                         }
03964                       }
03965                     } else {
03966                       maximumDown=0.0;
03967                       if (-maximumUp*value<-djValue-dualTolerance) {
03968                         maximumUp = 0.0; // would improve but not enough
03969                       } else {
03970                         if (-minimumUp*value<-djValue) {
03971                           minimumUp = djValue/value;
03972                           iUpB = iColumn;
03973                         }
03974                       }
03975                     }
03976                     
03977                     break;
03978                   case 2:
03979                     if (value>0.0) {
03980                       maximumUp = 0.0;
03981                     } else {
03982                       maximumDown = 0.0;
03983                     }
03984                     
03985                     break;
03986                   case 3:
03987                     if (value>0.0) {
03988                       if (maximumUp*value>djValue) {
03989                         maximumUp = djValue/value;
03990                         iUp = iColumn;
03991                       }
03992                     } else {
03993                       if (-maximumDown*value>djValue) {
03994                         maximumDown = -djValue/value;
03995                         iDown = iColumn;
03996                       }
03997                     }
03998                     
03999                     break;
04000                   default:
04001                     break;
04002                   }
04003                 }
04004               }
04005               if (iUpB>=0)
04006                 iUp=iUpB;
04007               if (maximumUp<=dualTolerance||maximumUp<minimumUp)
04008                 iUp=-1;
04009               if (iDownB>=0)
04010                 iDown=iDownB;
04011               if (maximumDown<=dualTolerance||maximumDown<minimumDown)
04012                 iDown=-1;
04013               if (iUp>=0||iDown>=0) {
04014                 // do something
04015                 if (iUp>=0&&iDown>=0) {
04016                   if (maximumDown>maximumUp)
04017                     iUp=-1;
04018                 }
04019                 double change;
04020                 int kColumn;
04021                 if (iUp>=0) {
04022                   kColumn=iUp;
04023                   change=maximumUp;
04024                   // just do minimum if was dual infeasible
04025                   // ? only if maximum large?
04026                   if (minimumUp>0.0)
04027                     change=minimumUp;
04028                   setRowStatus(iRow,atUpperBound);
04029                 } else {
04030                   kColumn=iDown;
04031                   change=-maximumDown;
04032                   // just do minimum if was dual infeasible
04033                   // ? only if maximum large?
04034                   if (minimumDown>0.0)
04035                     change=-minimumDown;
04036                   setRowStatus(iRow,atLowerBound);
04037                 }
04038                 assert (fabs(change)<1.0e20);
04039                 setColumnStatus(kColumn,basic);
04040                 numberIn++;
04041                 pi[iRow]=change;
04042                 for (j=rowStart[iRow];j<rowStart[iRow]+rowLength[iRow];j++) {
04043                   int iColumn = column[j];
04044                   double value = elementByRow[j];
04045                   double djValue = dj[iColumn]-change*value;
04046                   dj[iColumn]=djValue;
04047                   if (abs(way[iColumn])==1) {
04048                     numberBad--;
04049                     /*if (!numberBad)
04050                       printf("Became dual feasible at row %d out of %d\n",
04051                       iRow, numberRows_);*/
04052                     lastNumberIn=-1000000;
04053                   }
04054                   int thisWay = 100;
04055                   double lowerBound = columnLower_[iColumn];
04056                   double upperBound = columnUpper_[iColumn];
04057                   if (upperBound>lowerBound) {
04058                     switch(getColumnStatus(iColumn)) {
04059                       
04060                     case basic:
04061                       thisWay=0;
04062                     case isFixed:
04063                       break;
04064                     case isFree:
04065                     case superBasic:
04066                       if (djValue<-dualTolerance) 
04067                         thisWay = 1;
04068                       else if (djValue>dualTolerance) 
04069                         thisWay = -1;
04070                       else
04071                         { thisWay =0; abort();}
04072                       break;
04073                     case atUpperBound:
04074                       if (djValue>dualTolerance) 
04075                         { thisWay =-1; abort();}
04076                       else if (djValue<-dualTolerance) 
04077                         thisWay = -3;
04078                       else
04079                         thisWay = -2;
04080                       break;
04081                     case atLowerBound:
04082                       if (djValue<-dualTolerance) 
04083                         { thisWay =1; abort();}
04084                       else if (djValue>dualTolerance) 
04085                         thisWay = 3;
04086                       else
04087                         thisWay = 2;
04088                       break;
04089                     }
04090                   }
04091                   way[iColumn] = thisWay;
04092                 }
04093               }
04094             }
04095           }
04096           if (numberIn==lastNumberIn||numberBad||pivot<2)
04097             break;
04098           if (!(--numberPasses))
04099             break;
04100           //printf("%d put in so far\n",numberIn);
04101         }
04102         // last attempt to flip
04103         for (iColumn=0;iColumn<numberColumns_;iColumn++) {
04104           double lowerBound = columnLower_[iColumn];
04105           double upperBound = columnUpper_[iColumn];
04106           if (upperBound-lowerBound<=gap&&upperBound>lowerBound) {
04107             double djValue=dj[iColumn];
04108             switch(getColumnStatus(iColumn)) {
04109               
04110             case basic:
04111             case ClpSimplex::isFixed:
04112               break;
04113             case isFree:
04114             case superBasic:
04115               break;
04116             case atUpperBound:
04117               if (djValue>dualTolerance) {
04118                 setColumnStatus(iColumn,atUpperBound);
04119                 solution[iColumn]=upperBound;
04120               } 
04121               break;
04122             case atLowerBound:
04123               if (djValue<-dualTolerance) {
04124                 setColumnStatus(iColumn,atUpperBound);
04125                 solution[iColumn]=upperBound;
04126               }
04127               break;
04128             }
04129           }
04130         }
04131         delete [] pi;
04132         delete [] dj;
04133         delete [] way;
04134         handler_->message(CLP_CRASH,messages_)
04135           <<numberIn
04136           <<numberBad
04137           <<CoinMessageEol;
04138         returnCode =  -1;
04139       }
04140     } else {
04141       delete [] dj;
04142       returnCode =  -1;
04143     }
04144     //cleanStatus();
04145   }
04146   return returnCode;
04147 }
04148 /* Pivot in a variable and out a variable.  Returns 0 if okay,
04149    1 if inaccuracy forced re-factorization, -1 if would be singular.
04150    Also updates primal/dual infeasibilities.
04151    Assumes sequenceIn_ and pivotRow_ set and also directionIn and Out.
04152 */
04153 int ClpSimplex::pivot()
04154 {
04155   // scaling not allowed
04156   assert (!scalingFlag_);
04157   // assume In_ and Out_ are correct and directionOut_ set
04158   // (or In_ if flip
04159   lowerIn_ = lower_[sequenceIn_];
04160   valueIn_ = solution_[sequenceIn_];
04161   upperIn_ = upper_[sequenceIn_];
04162   dualIn_ = dj_[sequenceIn_];
04163   if (sequenceOut_>=0&&sequenceIn_!=sequenceIn_) {
04164     assert (pivotRow_>=0&&pivotRow_<numberRows_);
04165     assert (pivotVariable_[pivotRow_]==sequenceOut_);
04166     lowerOut_ = lower_[sequenceOut_];
04167     valueOut_ = solution_[sequenceOut_];
04168     upperOut_ = upper_[sequenceOut_];
04169     // for now assume primal is feasible (or in dual)
04170     dualOut_ = dj_[sequenceOut_];
04171     assert(fabs(dualOut_)<1.0e-6);
04172   } else {
04173     assert (pivotRow_<0);
04174   }
04175   bool roundAgain = true;
04176   int returnCode=0;
04177   while (roundAgain) {
04178     roundAgain=false;
04179     unpack(rowArray_[1]);
04180     factorization_->updateColumnFT(rowArray_[2],rowArray_[1]);
04181     // we are going to subtract movement from current basic
04182     double movement;
04183     // see where incoming will go to
04184     if (sequenceOut_<0||sequenceIn_==sequenceOut_) {
04185       // flip so go to bound
04186       movement  = ((directionIn_>0) ? upperIn_ : lowerIn_) - valueIn_;
04187     } else {
04188       // get where outgoing needs to get to
04189       double outValue = (directionOut_>0) ? upperOut_ : lowerOut_;
04190       // solutionOut_ - movement*alpha_ == outValue
04191       movement = (outValue-valueOut_)/alpha_;
04192       // set directionIn_ correctly
04193       directionIn_ = (movement>0) ? 1 :-1;
04194     }
04195     // update primal solution
04196     {
04197       int i;
04198       int * index = rowArray_[1]->getIndices();
04199       int number = rowArray_[1]->getNumElements();
04200       double * element = rowArray_[1]->denseVector();
04201       for (i=0;i<number;i++) {
04202         int ii = index[i];
04203         // get column
04204         ii = pivotVariable_[ii];
04205         solution_[ii] -= movement*element[i];
04206         element[i]=0.0;
04207       }
04208       // see where something went to
04209       if (sequenceOut_<0) {
04210         if (directionIn_<0) {
04211           assert (fabs(solution_[sequenceIn_]-upperIn_)<1.0e-7);
04212           solution_[sequenceIn_]=upperIn_;
04213         } else {
04214           assert (fabs(solution_[sequenceIn_]-lowerIn_)<1.0e-7);
04215           solution_[sequenceIn_]=lowerIn_;
04216         }
04217       } else {
04218         if (directionOut_<0) {
04219           assert (fabs(solution_[sequenceOut_]-upperOut_)<1.0e-7);
04220           solution_[sequenceOut_]=upperOut_;
04221         } else {
04222           assert (fabs(solution_[sequenceOut_]-lowerOut_)<1.0e-7);
04223           solution_[sequenceOut_]=lowerOut_;
04224         }
04225         solution_[sequenceIn_]=valueIn_+movement;
04226       }
04227     }    
04228     double objectiveChange = dualIn_*movement;
04229     // update duals
04230     if (pivotRow_>=0) {
04231       alpha_ = rowArray_[1]->denseVector()[pivotRow_];
04232       assert (fabs(alpha_)>1.0e-8);
04233       double multiplier = dualIn_/alpha_;
04234       rowArray_[0]->insert(pivotRow_,multiplier);
04235       factorization_->updateColumnTranspose(rowArray_[2],rowArray_[0]);
04236       // put row of tableau in rowArray[0] and columnArray[0]
04237       matrix_->transposeTimes(this,-1.0,
04238                               rowArray_[0],columnArray_[1],columnArray_[0]);
04239       // update column djs
04240       int i;
04241       int * index = columnArray_[0]->getIndices();
04242       int number = columnArray_[0]->getNumElements();
04243       double * element = columnArray_[0]->denseVector();
04244       for (i=0;i<number;i++) {
04245         int ii = index[i];
04246         dj_[ii] += element[ii];
04247         element[ii]=0.0;
04248       }
04249       columnArray_[0]->setNumElements(0);
04250       // and row djs
04251       index = rowArray_[0]->getIndices();
04252       number = rowArray_[0]->getNumElements();
04253       element = rowArray_[0]->denseVector();
04254       for (i=0;i<number;i++) {
04255         int ii = index[i];
04256         dj_[ii+numberColumns_] += element[ii];
04257         dual_[ii] = dj_[ii+numberColumns_];
04258         element[ii]=0.0;
04259       }
04260       rowArray_[0]->setNumElements(0);
04261       // check incoming
04262       assert (fabs(dj_[sequenceIn_])<1.0e-6);
04263     }
04264     
04265     // if stable replace in basis
04266     int updateStatus = factorization_->replaceColumn(rowArray_[2],
04267                                                    pivotRow_,
04268                                                      alpha_);
04269     bool takePivot=true;
04270     // if no pivots, bad update but reasonable alpha - take and invert
04271     if (updateStatus==2&&
04272         lastGoodIteration_==numberIterations_&&fabs(alpha_)>1.0e-5)
04273       updateStatus=4;
04274     if (updateStatus==1||updateStatus==4) {
04275       // slight error
04276       if (factorization_->pivots()>5||updateStatus==4) {
04277         returnCode=-1;
04278       }
04279     } else if (updateStatus==2) {
04280       // major error
04281       rowArray_[1]->clear();
04282       takePivot=false;
04283       if (factorization_->pivots()) {
04284         // refactorize here
04285         statusOfProblem();
04286         roundAgain=true;
04287       } else {
04288         returnCode=1;
04289       }
04290     } else if (updateStatus==3) {
04291       // out of memory
04292       // increase space if not many iterations
04293       if (factorization_->pivots()<
04294           0.5*factorization_->maximumPivots()&&
04295           factorization_->pivots()<200)
04296         factorization_->areaFactor(
04297                                    factorization_->areaFactor() * 1.1);
04298       returnCode =-1; // factorize now
04299     }
04300     if (takePivot) {
04301       int save = algorithm_;
04302       // make simple so always primal
04303       algorithm_=1;
04304       housekeeping(objectiveChange);
04305       algorithm_=save;
04306     }
04307   }
04308   if (returnCode == -1) {
04309     // refactorize here
04310     statusOfProblem();
04311   } else {
04312     // just for now - recompute anyway
04313     gutsOfSolution(NULL,NULL);
04314   }
04315   return returnCode;
04316 }
04317 
04318 /* Pivot in a variable and choose an outgoing one.  Assumes primal
04319    feasible - will not go through a bound.  Returns step length in theta
04320    Returns ray in ray_ (or NULL if no pivot)
04321    Return codes as before but -1 means no acceptable pivot
04322 */
04323 int ClpSimplex::primalPivotResult()
04324 {
04325   assert (sequenceIn_>=0);
04326   valueIn_=solution_[sequenceIn_];
04327   lowerIn_=lower_[sequenceIn_];
04328   upperIn_=upper_[sequenceIn_];
04329   dualIn_=dj_[sequenceIn_];
04330 
04331   int returnCode = ((ClpSimplexPrimal *) this)->pivotResult();
04332   if (returnCode<0&&returnCode>-4) {
04333     return 0;
04334   } else {
04335     printf("Return code of %d from ClpSimplexPrimal::pivotResult\n",
04336            returnCode);
04337     return -1;
04338   }
04339 }
04340   
04341 /* Pivot out a variable and choose an incoing one.  Assumes dual
04342    feasible - will not go through a reduced cost.  
04343    Returns step length in theta
04344    Returns ray in ray_ (or NULL if no pivot)
04345    Return codes as before but -1 means no acceptable pivot
04346 */
04347 int 
04348 ClpSimplex::dualPivotResult()
04349 {
04350   return ((ClpSimplexDual *) this)->pivotResult();
04351 }
04352 // Factorization frequency
04353 int 
04354 ClpSimplex::factorizationFrequency() const
04355 {
04356   if (factorization_)
04357     return factorization_->maximumPivots();
04358   else 
04359     return -1;
04360 }
04361 void 
04362 ClpSimplex::setFactorizationFrequency(int value)
04363 {
04364   if (factorization_)
04365     factorization_->maximumPivots(value);
04366 }
04367 // Common bits of coding for dual and primal
04368 int 
04369 ClpSimplex::startup(int ifValuesPass)
04370 {
04371   // sanity check
04372   // bad if empty (trap here to avoid using bad matrix_)
04373   if (!matrix_||!matrix_->getNumElements()) {
04374     handler_->message(CLP_EMPTY_PROBLEM,messages_)
04375       <<numberRows_
04376       <<numberColumns_
04377       <<0
04378       <<CoinMessageEol;
04379     problemStatus_=4;
04380     return 2;
04381   }
04382   pivotRow_=-1;
04383   sequenceIn_=-1;
04384   sequenceOut_=-1;
04385   secondaryStatus_=0;
04386 
04387   primalTolerance_=dblParam_[ClpPrimalTolerance];
04388   dualTolerance_=dblParam_[ClpDualTolerance];
04389   if (problemStatus_!=10)
04390     numberIterations_=0;
04391 
04392   // put in standard form (and make row copy)
04393   // create modifiable copies of model rim and do optional scaling
04394   bool goodMatrix=createRim(7+8+16,true);
04395 
04396   if (goodMatrix) {
04397     // Model looks okay
04398     // Do initial factorization
04399     // and set certain stuff
04400     // We can either set increasing rows so ...IsBasic gives pivot row
04401     // or we can just increment iBasic one by one
04402     // for now let ...iBasic give pivot row
04403     factorization_->increasingRows(2);
04404     // row activities have negative sign
04405     factorization_->slackValue(-1.0);
04406     factorization_->zeroTolerance(1.0e-13);
04407     // Switch off dense (unless special option set)
04408     int saveThreshold = factorization_->denseThreshold();
04409     factorization_->setDenseThreshold(0);
04410     // If values pass then perturb (otherwise may be optimal so leave a bit)
04411     if (ifValuesPass) {
04412       // do perturbation if asked for
04413       
04414       if (perturbation_<100) {
04415         if (algorithm_>0) {
04416           ((ClpSimplexPrimal *) this)->perturb(0);
04417         } else if (algorithm_<0) {
04418         ((ClpSimplexDual *) this)->perturb();
04419         }
04420       }
04421     }
04422     // for primal we will change bounds using infeasibilityCost_
04423     if (nonLinearCost_==NULL&&algorithm_>0) {
04424       // get a valid nonlinear cost function
04425       delete nonLinearCost_;
04426       nonLinearCost_= new ClpNonLinearCost(this);
04427     }
04428     
04429     // loop round to clean up solution if values pass
04430     int numberThrownOut = -1;
04431     int totalNumberThrownOut=0;
04432     while(numberThrownOut) {
04433       int status = internalFactorize(0+10*ifValuesPass);
04434       if (status<0)
04435         return 1; // some error
04436       else
04437         numberThrownOut = status;
04438       
04439       // for this we need clean basis so it is after factorize
04440       if (!numberThrownOut)
04441         numberThrownOut = gutsOfSolution(  NULL,NULL,
04442                                          ifValuesPass!=0);
04443       totalNumberThrownOut+= numberThrownOut;
04444       
04445     }
04446     
04447     if (totalNumberThrownOut)
04448       handler_->message(CLP_SINGULARITIES,messages_)
04449         <<totalNumberThrownOut
04450         <<CoinMessageEol;
04451     // Switch back dense
04452     factorization_->setDenseThreshold(saveThreshold);
04453     
04454     problemStatus_ = -1;
04455     
04456     // number of times we have declared optimality
04457     numberTimesOptimal_=0;
04458 
04459     return 0;
04460   } else {
04461     // bad matrix
04462     return 2;
04463   }
04464     
04465 }
04466 
04467 
04468 void 
04469 ClpSimplex::finish()
04470 {
04471   // Get rid of some arrays and empty factorization
04472   deleteRim();
04473   // Skip message if changing algorithms
04474   if (problemStatus_!=10) {
04475     assert(problemStatus_>=0&&problemStatus_<5);
04476     handler_->message(CLP_SIMPLEX_FINISHED+problemStatus_,messages_)
04477       <<objectiveValue()
04478       <<CoinMessageEol;
04479   }
04480   factorization_->relaxAccuracyCheck(1.0);
04481   // get rid of any network stuff - could do more
04482   factorization_->cleanUp();
04483 }
04484 // Save data
04485 ClpDataSave 
04486 ClpSimplex::saveData() 
04487 {
04488   ClpDataSave saved;
04489   saved.dualBound_ = dualBound_;
04490   saved.infeasibilityCost_ = infeasibilityCost_;
04491   saved.sparseThreshold_ = factorization_->sparseThreshold();
04492   saved.perturbation_ = perturbation_;
04493   // Progress indicator
04494   delete progress_;
04495   progress_ = new ClpSimplexProgress (this);
04496   return saved;
04497 }
04498 // Restore data
04499 void 
04500 ClpSimplex::restoreData(ClpDataSave saved)
04501 {
04502   factorization_->sparseThreshold(saved.sparseThreshold_);
04503   perturbation_ = saved.perturbation_;
04504   infeasibilityCost_ = saved.infeasibilityCost_;
04505   dualBound_ = saved.dualBound_;
04506   delete progress_;
04507   progress_=NULL;
04508 }
04509 /* Factorizes and returns true if optimal.  Used by user */
04510 bool
04511 ClpSimplex::statusOfProblem()
04512 {
04513   // is factorization okay?
04514   assert (internalFactorize(1)==0);
04515   // put back original costs and then check
04516   // also move to work arrays
04517   createRim(4+32);
04518   //memcpy(rowActivityWork_,rowActivity_,numberRows_*sizeof(double));
04519   //memcpy(columnActivityWork_,columnActivity_,numberColumns_*sizeof(double));
04520   gutsOfSolution(NULL,NULL);
04521   //memcpy(rowActivity_,rowActivityWork_,numberRows_*sizeof(double));
04522   //memcpy(columnActivity_,columnActivityWork_,numberColumns_*sizeof(double));
04523   //memcpy(reducedCost_,dj_,numberColumns_*sizeof(double));
04524   deleteRim(-1);
04525   return (primalFeasible()&&dualFeasible());
04526 }
04527 /* Return model - updates any scalars */
04528 void 
04529 ClpSimplex::returnModel(ClpSimplex & otherModel)
04530 {
04531   ClpModel::returnModel(otherModel);
04532   otherModel.columnPrimalInfeasibility_ = columnPrimalInfeasibility_;
04533   otherModel.columnPrimalSequence_ = columnPrimalSequence_;
04534   otherModel.rowPrimalInfeasibility_ = rowPrimalInfeasibility_;
04535   otherModel.rowPrimalSequence_ = rowPrimalSequence_;
04536   otherModel.columnDualInfeasibility_ = columnDualInfeasibility_;
04537   otherModel.columnDualSequence_ = columnDualSequence_;
04538   otherModel.rowDualInfeasibility_ = rowDualInfeasibility_;
04539   otherModel.rowDualSequence_ = rowDualSequence_;
04540   otherModel.primalToleranceToGetOptimal_ = primalToleranceToGetOptimal_;
04541   otherModel.remainingDualInfeasibility_ = remainingDualInfeasibility_;
04542   otherModel.largestPrimalError_ = largestPrimalError_;
04543   otherModel.largestDualError_ = largestDualError_;
04544   otherModel.largestSolutionError_ = largestSolutionError_;
04545   otherModel.alpha_ = alpha_;
04546   otherModel.theta_ = theta_;
04547   otherModel.lowerIn_ = lowerIn_;
04548   otherModel.valueIn_ = valueIn_;
04549   otherModel.upperIn_ = upperIn_;
04550   otherModel.dualIn_ = dualIn_;
04551   otherModel.sequenceIn_ = sequenceIn_;
04552   otherModel.directionIn_ = directionIn_;
04553   otherModel.lowerOut_ = lowerOut_;
04554   otherModel.valueOut_ = valueOut_;
04555   otherModel.upperOut_ = upperOut_;
04556   otherModel.dualOut_ = dualOut_;
04557   otherModel.sequenceOut_ = sequenceOut_;
04558   otherModel.directionOut_ = directionOut_;
04559   otherModel.pivotRow_ = pivotRow_;
04560   otherModel.sumDualInfeasibilities_ = sumDualInfeasibilities_;
04561   otherModel.numberDualInfeasibilities_ = numberDualInfeasibilities_;
04562   otherModel.numberDualInfeasibilitiesWithoutFree_ = 
04563     numberDualInfeasibilitiesWithoutFree_;
04564   otherModel.sumPrimalInfeasibilities_ = sumPrimalInfeasibilities_;
04565   otherModel.numberPrimalInfeasibilities_ = numberPrimalInfeasibilities_;
04566   otherModel.numberTimesOptimal_ = numberTimesOptimal_;
04567   otherModel.sumOfRelaxedDualInfeasibilities_ = sumOfRelaxedDualInfeasibilities_;
04568   otherModel.sumOfRelaxedPrimalInfeasibilities_ = sumOfRelaxedPrimalInfeasibilities_;
04569 }
04570 /* Constructs a non linear cost from list of non-linearities (columns only)
04571    First lower of each column is taken as real lower
04572    Last lower is taken as real upper and cost ignored
04573    
04574    Returns nonzero if bad data e.g. lowers not monotonic
04575 */
04576 int 
04577 ClpSimplex::createPiecewiseLinearCosts(const int * starts,
04578                                        const double * lower, const double * gradient)
04579 {
04580   delete nonLinearCost_;
04581   // Set up feasible bounds and check monotonicity
04582   int iColumn;
04583   int returnCode=0;
04584 
04585   for (iColumn=0;iColumn<numberColumns_;iColumn++) {
04586     int iIndex = starts[iColumn];
04587     int end = starts[iColumn+1]-1;
04588     columnLower_[iColumn] = lower[iIndex];
04589     columnUpper_[iColumn] = lower[end];
04590     double value = columnLower_[iColumn];
04591     iIndex++;
04592     for (;iIndex<end;iIndex++) {
04593       if (lower[iIndex]<value)
04594         returnCode++; // not monotonic
04595       value=lower[iIndex];
04596     }
04597   }
04598   nonLinearCost_ = new ClpNonLinearCost(this,starts,lower,gradient);
04599   specialOptions_ |= 2; // say keep
04600   return returnCode;
04601 }
04602 /* For advanced use.  When doing iterative solves things can get
04603    nasty so on values pass if incoming solution has largest
04604    infeasibility < incomingInfeasibility throw out variables
04605    from basis until largest infeasibility < allowedInfeasibility
04606    or incoming largest infeasibility.
04607    If allowedInfeasibility>= incomingInfeasibility this is
04608    always possible altough you may end up with an all slack basis.
04609    
04610    Defaults are 1.0,10.0
04611 */
04612 void 
04613 ClpSimplex::setValuesPassAction(float incomingInfeasibility,
04614                                 float allowedInfeasibility)
04615 {
04616   incomingInfeasibility_=incomingInfeasibility;
04617   allowedInfeasibility_=allowedInfeasibility;
04618   assert(incomingInfeasibility_>=0.0);
04619   assert(allowedInfeasibility_>=incomingInfeasibility_);
04620 }
04621 //#############################################################################
04622 
04623 ClpSimplexProgress::ClpSimplexProgress () 
04624 {
04625   int i;
04626   for (i=0;i<CLP_PROGRESS;i++) {
04627     objective_[i] = COIN_DBL_MAX;
04628     infeasibility_[i] = -1.0; // set to an impossible value
04629     numberInfeasibilities_[i]=-1; 
04630     iterationNumber_[i]=-1;
04631   }
04632   for (i=0;i<CLP_CYCLE;i++) {
04633     obj_[i]=COIN_DBL_MAX;
04634     in_[i]=-1;
04635     out_[i]=-1;
04636     way_[i]=0;
04637   }
04638   numberTimes_ = 0;
04639   numberBadTimes_ = 0;
04640   model_ = NULL;
04641   oddState_=0;
04642 }
04643 
04644 
04645 //-----------------------------------------------------------------------------
04646 
04647 ClpSimplexProgress::~ClpSimplexProgress ()
04648 {
04649 }
04650 // Copy constructor. 
04651 ClpSimplexProgress::ClpSimplexProgress(const ClpSimplexProgress &rhs) 
04652 {
04653   int i;
04654   for (i=0;i<CLP_PROGRESS;i++) {
04655     objective_[i] = rhs.objective_[i];
04656     infeasibility_[i] = rhs.infeasibility_[i];
04657     numberInfeasibilities_[i]=rhs.numberInfeasibilities_[i]; 
04658     iterationNumber_[i]=rhs.iterationNumber_[i];
04659   }
04660   for (i=0;i<CLP_CYCLE;i++) {
04661     obj_[i]=rhs.obj_[i];
04662     in_[i]=rhs.in_[i];
04663     out_[i]=rhs.out_[i];
04664     way_[i]=rhs.way_[i];
04665   }
04666   numberTimes_ = rhs.numberTimes_;
04667   numberBadTimes_ = rhs.numberBadTimes_;
04668   model_ = rhs.model_;
04669   oddState_=rhs.oddState_;
04670 }
04671 // Copy constructor.from model
04672 ClpSimplexProgress::ClpSimplexProgress(ClpSimplex * model) 
04673 {
04674   model_ = model;
04675   int i;
04676   for (i=0;i<CLP_PROGRESS;i++) {
04677     if (model_->algorithm()>=0)
04678       objective_[i] = COIN_DBL_MAX;
04679     else
04680       objective_[i] = -COIN_DBL_MAX;
04681     infeasibility_[i] = -1.0; // set to an impossible value
04682     numberInfeasibilities_[i]=-1; 
04683     iterationNumber_[i]=-1;
04684   }
04685   for (i=0;i<CLP_CYCLE;i++) {
04686     obj_[i]=COIN_DBL_MAX;
04687     in_[i]=-1;
04688     out_[i]=-1;
04689     way_[i]=0;
04690   }
04691   numberTimes_ = 0;
04692   numberBadTimes_ = 0;
04693   oddState_=0;
04694 }
04695 // Assignment operator. This copies the data
04696 ClpSimplexProgress & 
04697 ClpSimplexProgress::operator=(const ClpSimplexProgress & rhs)
04698 {
04699   if (this != &rhs) {
04700     int i;
04701     for (i=0;i<CLP_PROGRESS;i++) {
04702       objective_[i] = rhs.objective_[i];
04703       infeasibility_[i] = rhs.infeasibility_[i];
04704       numberInfeasibilities_[i]=rhs.numberInfeasibilities_[i]; 
04705       iterationNumber_[i]=rhs.iterationNumber_[i];
04706     }
04707     for (i=0;i<CLP_CYCLE;i++) {
04708       obj_[i]=rhs.obj_[i];
04709       in_[i]=rhs.in_[i];
04710       out_[i]=rhs.out_[i];
04711       way_[i]=rhs.way_[i];
04712     }
04713     numberTimes_ = rhs.numberTimes_;
04714     numberBadTimes_ = rhs.numberBadTimes_;
04715     model_ = rhs.model_;
04716     oddState_=rhs.oddState_;
04717   }
04718   return *this;
04719 }
04720 // Seems to be something odd about exact comparison of doubles on linux
04721 static bool equalDouble(double value1, double value2)
04722 {
04723   unsigned int *i1 = (unsigned int *) &value1;
04724   unsigned int *i2 = (unsigned int *) &value2;
04725   if (sizeof(unsigned int)*2==sizeof(double)) 
04726     return (i1[0]==i2[0]&&i1[1]==i2[1]);
04727   else
04728     return (i1[0]==i2[0]);
04729 }
04730 int
04731 ClpSimplexProgress::looping()
04732 {
04733   if (!model_)
04734     return -1;
04735   double objective = model_->rawObjectiveValue();
04736   double infeasibility;
04737   int numberInfeasibilities;
04738   int iterationNumber = model_->numberIterations();
04739   if (model_->algorithm()<0) {
04740     // dual
04741     infeasibility = model_->sumPrimalInfeasibilities();
04742     numberInfeasibilities = model_->numberPrimalInfeasibilities();
04743   } else {
04744     //primal
04745     infeasibility = model_->sumDualInfeasibilities();
04746     numberInfeasibilities = model_->numberDualInfeasibilities();
04747   }
04748   int i;
04749   int numberMatched=0;
04750   int matched=0;
04751   int nsame=0;
04752   for (i=0;i<CLP_PROGRESS;i++) {
04753     bool matchedOnObjective = equalDouble(objective,objective_[i]);
04754     bool matchedOnInfeasibility = equalDouble(infeasibility,infeasibility_[i]);
04755     bool matchedOnInfeasibilities = 
04756       (numberInfeasibilities==numberInfeasibilities_[i]);
04757     
04758     if (matchedOnObjective&&matchedOnInfeasibility&&matchedOnInfeasibilities) {
04759       matched |= (1<<i);
04760       // Check not same iteration
04761       if (iterationNumber!=iterationNumber_[i]) {
04762         numberMatched++;
04763         // here mainly to get over compiler bug?
04764         if (model_->messageHandler()->logLevel()>10)
04765           printf("%d %d %d %d %d loop check\n",i,numberMatched,
04766                  matchedOnObjective, matchedOnInfeasibility, 
04767                  matchedOnInfeasibilities);
04768       } else {
04769         // stuck but code should notice
04770         nsame++;
04771       }
04772     }
04773     if (i) {
04774       objective_[i-1] = objective_[i];
04775       infeasibility_[i-1] = infeasibility_[i];
04776       numberInfeasibilities_[i-1]=numberInfeasibilities_[i]; 
04777       iterationNumber_[i-1]=iterationNumber_[i];
04778     }
04779   }
04780   objective_[CLP_PROGRESS-1] = objective;
04781   infeasibility_[CLP_PROGRESS-1] = infeasibility;
04782   numberInfeasibilities_[CLP_PROGRESS-1]=numberInfeasibilities;
04783   iterationNumber_[CLP_PROGRESS-1]=iterationNumber;
04784   if (nsame==CLP_PROGRESS)
04785     numberMatched=CLP_PROGRESS; // really stuck
04786   if (model_->progressFlag())
04787     numberMatched=0;
04788   numberTimes_++;
04789   if (numberTimes_<10)
04790     numberMatched=0;
04791   // skip if just last time as may be checking something
04792   if (matched==(1<<(CLP_PROGRESS-1)))
04793     numberMatched=0;
04794   if (numberMatched) {
04795     model_->messageHandler()->message(CLP_POSSIBLELOOP,model_->messages())
04796       <<numberMatched
04797       <<matched
04798       <<numberTimes_
04799       <<CoinMessageEol;
04800     numberBadTimes_++;
04801     if (numberBadTimes_<10) {
04802       // make factorize every iteration
04803       model_->forceFactorization(1);
04804       if (model_->algorithm()<0) {
04805         // dual - change tolerance
04806         model_->setCurrentDualTolerance(model_->currentDualTolerance()*1.05);
04807         // if infeasible increase dual bound
04808         if (model_->dualBound()<1.0e17) {
04809           model_->setDualBound(model_->dualBound()*1.1);
04810         }
04811       } else {
04812         // primal - change tolerance    
04813         if (numberBadTimes_>3)
04814           model_->setCurrentPrimalTolerance(model_->currentPrimalTolerance()*1.05);
04815         // if infeasible increase infeasibility cost
04816         if (model_->nonLinearCost()->numberInfeasibilities()&&
04817             model_->infeasibilityCost()<1.0e17) {
04818           model_->setInfeasibilityCost(model_->infeasibilityCost()*1.1);
04819         }
04820       }
04821       return -2;
04822     } else {
04823       // look at solution and maybe declare victory
04824       if (infeasibility<1.0e-4) {
04825         return 0;
04826       } else {
04827         model_->messageHandler()->message(CLP_LOOP,model_->messages())
04828           <<CoinMessageEol;
04829 #ifndef NDEBUG
04830         abort();
04831 #endif
04832         return 3;
04833       }
04834     }
04835   }
04836   return -1;
04837 }
04838 // Returns previous objective (if -1) - current if (0)
04839 double 
04840 ClpSimplexProgress::lastObjective(int back) const
04841 {
04842   return objective_[CLP_PROGRESS-1-back];
04843 }
04844 // Modify objective e.g. if dual infeasible in dual
04845 void 
04846 ClpSimplexProgress::modifyObjective(double value)
04847 {
04848   objective_[CLP_PROGRESS-1]=value;
04849 }
04850 // Returns previous iteration number (if -1) - current if (0)
04851 int 
04852 ClpSimplexProgress::lastIterationNumber(int back) const
04853 {
04854   return iterationNumber_[CLP_PROGRESS-1-back];
04855 }
04856 // Start check at beginning of whileIterating
04857 void 
04858 ClpSimplexProgress::startCheck()
04859 {
04860   int i;
04861   for (i=0;i<CLP_CYCLE;i++) {
04862     obj_[i]=COIN_DBL_MAX;
04863     in_[i]=-1;
04864     out_[i]=-1;
04865     way_[i]=0;
04866   }
04867 }
04868 // Returns cycle length in whileIterating
04869 int 
04870 ClpSimplexProgress::cycle(int in, int out,int wayIn,int wayOut)
04871 {
04872   int i;
04873   int matched=0;
04874   // first see if in matches any out
04875   for (i=1;i<CLP_CYCLE;i++) {
04876     if (in==out_[i]) {
04877       // even if flip then suspicious
04878       matched=-1;
04879       break;
04880     }
04881   }
04882   if (!matched||in_[0]<0) {
04883     // can't be cycle
04884     for (i=0;i<CLP_CYCLE-1;i++) {
04885       obj_[i]=obj_[i+1];
04886       in_[i]=in_[i+1];
04887       out_[i]=out_[i+1];
04888       way_[i]=way_[i+1];
04889     }
04890   } else {
04891     // possible cycle
04892     matched=0;
04893     for (i=0;i<CLP_CYCLE-1;i++) {
04894       int k;
04895       char wayThis = way_[i];
04896       int inThis = in_[i];
04897       int outThis = out_[i];
04898       //double objThis = obj_[i];
04899       for(k=i+1;k<CLP_CYCLE;k++) {
04900         if (inThis==in_[k]&&outThis==out_[k]&&wayThis==way_[k]) {
04901           if (k+(k-i)<CLP_CYCLE) {
04902             // See if repeats
04903             int j=k+(k-i);
04904             if (inThis==in_[j]&&outThis==out_[j]&&wayThis==way_[j]) {
04905               matched=k-i;
04906               break;
04907             }
04908           } else {
04909             matched=k-i;
04910             break;
04911           }
04912         }
04913       }
04914       obj_[i]=obj_[i+1];
04915       in_[i]=in_[i+1];
04916       out_[i]=out_[i+1];
04917       way_[i]=way_[i+1];
04918     }
04919   }
04920   char way = 1-wayIn+4*(1-wayOut);
04921   obj_[i]=model_->objectiveValue();
04922   in_[CLP_CYCLE-1]=in;
04923   out_[CLP_CYCLE-1]=out;
04924   way_[CLP_CYCLE-1]=way;
04925   return matched;
04926 }
04927 // Allow initial dense factorization
04928 void 
04929 ClpSimplex::setInitialDenseFactorization(bool onOff)
04930 {
04931   if (onOff)
04932     specialOptions_ |= 8;
04933   else
04934     specialOptions_ &= ~8;
04935 }
04936 bool 
04937 ClpSimplex::initialDenseFactorization() const
04938 {
04939   return (specialOptions_&8)!=0;
04940 }
04941 /* This constructor modifies original ClpSimplex and stores
04942    original stuff in created ClpSimplex.  It is only to be used in
04943    conjunction with originalModel */
04944 ClpSimplex::ClpSimplex (ClpSimplex * wholeModel,
04945                         int numberColumns, const int * whichColumns)
04946 {
04947 
04948   // Set up dummy row selection list
04949   numberRows_ = wholeModel->numberRows_;
04950   int * whichRow = new int [numberRows_];
04951   int iRow;
04952   for (iRow=0;iRow<numberRows_;iRow++)
04953     whichRow[iRow]=iRow;
04954   // ClpModel stuff (apart from numberColumns_)
04955   matrix_ = wholeModel->matrix_;
04956   rowCopy_ = wholeModel->rowCopy_;
04957   if (wholeModel->rowCopy_) {
04958     // note reversal of order
04959     wholeModel->rowCopy_ = wholeModel->rowCopy_->subsetClone(numberRows_,whichRow,
04960                                                              numberColumns,whichColumns);
04961   } else {
04962     wholeModel->rowCopy_=NULL;
04963   }
04964   assert (wholeModel->matrix_);
04965   wholeModel->matrix_ = wholeModel->matrix_->subsetClone(numberRows_,whichRow,
04966                                         numberColumns,whichColumns);
04967   delete [] whichRow;
04968   numberColumns_ = wholeModel->numberColumns_;
04969   // Now ClpSimplex stuff and status_
04970   ClpPrimalColumnSteepest * steep =
04971     dynamic_cast< ClpPrimalColumnSteepest*>(wholeModel->primalColumnPivot_);
04972 #ifdef NDEBUG
04973   if (!steep)
04974     abort();
04975 #else
04976   assert (steep);
04977 #endif
04978   delete  wholeModel->primalColumnPivot_;
04979   wholeModel->primalColumnPivot_ = new ClpPrimalColumnSteepest(0);
04980   nonLinearCost_ = wholeModel->nonLinearCost_;
04981 
04982   // Now main arrays
04983   int iColumn;
04984   int numberTotal = numberRows_+numberColumns;
04985   printf("%d %d %d\n",numberTotal,numberRows_,numberColumns);
04986   // mapping 
04987   int * mapping = new int[numberRows_+numberColumns_];
04988   for (iColumn=0;iColumn<numberColumns_;iColumn++) 
04989     mapping[iColumn]=-1;
04990   for (iRow=0;iRow<numberRows_;iRow++) 
04991     mapping[iRow+numberColumns_] = iRow+numberColumns;
04992   // Redo costs and bounds of whole model
04993   wholeModel->createRim(5,false);
04994   lower_ = wholeModel->lower_;
04995   wholeModel->lower_ = new double [numberTotal];
04996   memcpy(wholeModel->lower_+numberColumns,lower_+numberColumns_,numberRows_*sizeof(double));
04997   for (iColumn=0;iColumn<numberColumns;iColumn++) {
04998     int jColumn = whichColumns[iColumn];
04999     wholeModel->lower_[iColumn]=lower_[jColumn];
05000     // and pointer back 
05001     mapping[jColumn]=iColumn;
05002   }
05003 #ifdef CLP_DEBUG
05004   for (iColumn=0;iColumn<numberRows_+numberColumns_;iColumn++) 
05005     printf("mapx %d %d\n",iColumn,mapping[iColumn]);
05006 #endif
05007   // Re-define pivotVariable_
05008   for (iRow=0;iRow<numberRows_;iRow++) {
05009     int iPivot = wholeModel->pivotVariable_[iRow];
05010     wholeModel->pivotVariable_[iRow]=mapping[iPivot];
05011 #ifdef CLP_DEBUG
05012     printf("p row %d, pivot %d -> %d\n",iRow,iPivot,mapping[iPivot]);
05013 #endif
05014     assert (wholeModel->pivotVariable_[iRow]>=0);
05015   }
05016   // Reverse mapping (so extended version of whichColumns)
05017   for (iColumn=0;iColumn<numberColumns;iColumn++) 
05018     mapping[iColumn]=whichColumns[iColumn];
05019   for (;iColumn<numberRows_+numberColumns;iColumn++) 
05020     mapping[iColumn] = iColumn + (numberColumns_-numberColumns);
05021 #ifdef CLP_DEBUG
05022   for (iColumn=0;iColumn<numberRows_+numberColumns;iColumn++) 
05023     printf("map %d %d\n",iColumn,mapping[iColumn]);
05024 #endif
05025   // Save mapping somewhere - doesn't matter
05026   rowUpper_ = (double *) mapping;
05027   upper_ = wholeModel->upper_;
05028   wholeModel->upper_ = new double [numberTotal];
05029   for (iColumn=0;iColumn<numberTotal;iColumn++) {
05030     int jColumn = mapping[iColumn];
05031     wholeModel->upper_[iColumn]=upper_[jColumn];
05032   }
05033   cost_ = wholeModel->cost_;
05034   wholeModel->cost_ = new double [numberTotal];
05035   for (iColumn=0;iColumn<numberTotal;iColumn++) {
05036     int jColumn = mapping[iColumn];
05037     wholeModel->cost_[iColumn]=cost_[jColumn];
05038   }
05039   dj_ = wholeModel->dj_;
05040   wholeModel->dj_ = new double [numberTotal];
05041   for (iColumn=0;iColumn<numberTotal;iColumn++) {
05042     int jColumn = mapping[iColumn];
05043     wholeModel->dj_[iColumn]=dj_[jColumn];
05044   }
05045   solution_ = wholeModel->solution_;
05046   wholeModel->solution_ = new double [numberTotal];
05047   for (iColumn=0;iColumn<numberTotal;iColumn++) {
05048     int jColumn = mapping[iColumn];
05049     wholeModel->solution_[iColumn]=solution_[jColumn];
05050   }
05051   // now see what variables left out do to row solution
05052   double * rowSolution = wholeModel->solution_+numberColumns;
05053   double * fullSolution = solution_;
05054   double * sumFixed = new double[numberRows_];
05055   memset (sumFixed,0,numberRows_*sizeof(double));
05056   // zero out ones in small problem
05057   for (iColumn=0;iColumn<numberColumns;iColumn++) {
05058     int jColumn = mapping[iColumn];
05059     fullSolution[jColumn]=0.0;
05060   }
05061   // Get objective offset
05062   double originalOffset;
05063   wholeModel->getDblParam(ClpObjOffset,originalOffset);
05064   double offset=0.0;
05065   const double * cost = cost_;
05066   for (iColumn=0;iColumn<numberColumns_;iColumn++) 
05067     offset += fullSolution[iColumn]*cost[iColumn];
05068   wholeModel->setDblParam(ClpObjOffset,originalOffset-offset);
05069   setDblParam(ClpObjOffset,originalOffset);
05070   matrix_->times(1.0,fullSolution,sumFixed,wholeModel->rowScale_,wholeModel->columnScale_);
05071       
05072   double * lower = lower_+numberColumns;
05073   double * upper = upper_+numberColumns;
05074   double fixed=0.0;
05075   for (iRow=0;iRow<numberRows_;iRow++) {
05076     fixed += fabs(sumFixed[iRow]);
05077     if (lower[iRow]>-1.0e50) 
05078       lower[iRow] -= sumFixed[iRow];
05079     if (upper[iRow]<1.0e50)
05080       upper[iRow] -= sumFixed[iRow];
05081     rowSolution[iRow] -= sumFixed[iRow];
05082   }
05083   printf("offset %g sumfixed %g\n",offset,fixed);
05084   delete [] sumFixed;
05085   columnScale_ = wholeModel->columnScale_;
05086   if (columnScale_) {
05087     wholeModel->columnScale_ = new double [numberTotal];
05088     for (iColumn=0;iColumn<numberColumns;iColumn++) {
05089       int jColumn = mapping[iColumn];
05090       wholeModel->columnScale_[iColumn]=columnScale_[jColumn];
05091     }
05092   }
05093   status_ = wholeModel->status_;
05094   wholeModel->status_ = new unsigned char [numberTotal];
05095   for (iColumn=0;iColumn<numberTotal;iColumn++) {
05096     int jColumn = mapping[iColumn];
05097     wholeModel->status_[iColumn]=status_[jColumn];
05098   }
05099   savedSolution_ = wholeModel->savedSolution_;
05100   if (savedSolution_) {
05101     wholeModel->savedSolution_ = new double [numberTotal];
05102     for (iColumn=0;iColumn<numberTotal;iColumn++) {
05103       int jColumn = mapping[iColumn];
05104       wholeModel->savedSolution_[iColumn]=savedSolution_[jColumn];
05105     }
05106   }
05107   saveStatus_ = wholeModel->saveStatus_;
05108   if (saveStatus_) {
05109     wholeModel->saveStatus_ = new unsigned char [numberTotal];
05110     for (iColumn=0;iColumn<numberTotal;iColumn++) {
05111       int jColumn = mapping[iColumn];
05112       wholeModel->saveStatus_[iColumn]=saveStatus_[jColumn];
05113     }
05114   }
05115   
05116   wholeModel->numberColumns_ = numberColumns;
05117   // Initialize weights
05118   wholeModel->primalColumnPivot_->saveWeights(wholeModel,2);
05119   // Costs
05120   wholeModel->nonLinearCost_ = new ClpNonLinearCost(wholeModel);
05121   wholeModel->nonLinearCost_->checkInfeasibilities();
05122   printf("after contraction %d infeasibilities summing to %g\n",
05123          nonLinearCost_->numberInfeasibilities(),nonLinearCost_->sumInfeasibilities());
05124   // Redo some stuff
05125   wholeModel->reducedCostWork_ = wholeModel->dj_;
05126   wholeModel->rowReducedCost_ = wholeModel->dj_+wholeModel->numberColumns_;
05127   wholeModel->columnActivityWork_ = wholeModel->solution_;
05128   wholeModel->rowActivityWork_ = wholeModel->solution_+wholeModel->numberColumns_;
05129   wholeModel->objectiveWork_ = wholeModel->cost_;
05130   wholeModel->rowObjectiveWork_ = wholeModel->cost_+wholeModel->numberColumns_;
05131   wholeModel->rowLowerWork_ = wholeModel->lower_+wholeModel->numberColumns_;
05132   wholeModel->columnLowerWork_ = wholeModel->lower_;
05133   wholeModel->rowUpperWork_ = wholeModel->upper_+wholeModel->numberColumns_;
05134   wholeModel->columnUpperWork_ = wholeModel->upper_;
05135 #ifndef NDEBUG
05136   // Check status
05137   ClpSimplex * xxxx = wholeModel;
05138   int nBasic=0;
05139   for (iColumn=0;iColumn<xxxx->numberRows_+xxxx->numberColumns_;iColumn++)
05140     if (xxxx->getStatus(iColumn)==basic)
05141       nBasic++;
05142   assert (nBasic==xxxx->numberRows_);
05143   for (iRow=0;iRow<xxxx->numberRows_;iRow++) {
05144     int iPivot=xxxx->pivotVariable_[iRow];
05145     assert (xxxx->getStatus(iPivot)==basic);
05146   }
05147 #endif
05148 }
05149 /* This copies back stuff from miniModel and then deletes miniModel.
05150    Only to be used with mini constructor */
05151 void 
05152 ClpSimplex::originalModel(ClpSimplex * miniModel)
05153 {
05154   int numberSmall = numberColumns_;
05155   numberColumns_ = miniModel->numberColumns_;
05156   int numberTotal = numberSmall+numberRows_;
05157   // copy back
05158   int iColumn;
05159   int * mapping = (int *) miniModel->rowUpper_;
05160 #ifdef CLP_DEBUG
05161   for (iColumn=0;iColumn<numberRows_+numberColumns_;iColumn++) 
05162     printf("mapb %d %d\n",iColumn,mapping[iColumn]);
05163 #endif
05164   // miniModel actually has full arrays
05165   // now see what variables left out do to row solution
05166   double * fullSolution = miniModel->solution_;
05167   double * sumFixed = new double[numberRows_];
05168   memset (sumFixed,0,numberRows_*sizeof(double));
05169   miniModel->matrix_->times(1.0,fullSolution,sumFixed,rowScale_,miniModel->columnScale_);
05170       
05171   for (iColumn=0;iColumn<numberTotal;iColumn++) {
05172     int jColumn = mapping[iColumn];
05173     miniModel->lower_[jColumn]=lower_[iColumn];
05174     miniModel->upper_[jColumn]=upper_[iColumn];
05175     miniModel->cost_[jColumn]=cost_[iColumn];
05176     miniModel->dj_[jColumn]=dj_[iColumn];
05177     miniModel->solution_[jColumn]=solution_[iColumn];
05178     miniModel->status_[jColumn]=status_[iColumn];
05179 #ifdef CLP_DEBUG
05180     printf("%d in small -> %d in original\n",iColumn,jColumn);
05181 #endif
05182   }
05183   delete [] lower_;
05184   lower_ =  miniModel->lower_;
05185   delete [] upper_;
05186   upper_ =  miniModel->upper_;
05187   delete [] cost_;
05188   cost_ =  miniModel->cost_;
05189   delete [] dj_;
05190   dj_ =  miniModel->dj_;
05191   delete [] solution_;
05192   solution_ =  miniModel->solution_;
05193   delete [] status_;
05194   status_ =  miniModel->status_;
05195   if (columnScale_) {
05196     for (iColumn=0;iColumn<numberSmall;iColumn++) {
05197       int jColumn = mapping[iColumn];
05198       miniModel->columnScale_[jColumn]=columnScale_[iColumn];
05199     }
05200     delete [] columnScale_;
05201     columnScale_ =  miniModel->columnScale_;
05202   }
05203   if (savedSolution_) {
05204     if (!miniModel->savedSolution_) {
05205       miniModel->savedSolution_ = ClpCopyOfArray(solution_,numberColumns_+numberRows_);
05206     } else {
05207       for (iColumn=0;iColumn<numberTotal;iColumn++) {
05208         int jColumn = mapping[iColumn];
05209         miniModel->savedSolution_[jColumn]=savedSolution_[iColumn];
05210       }
05211     }
05212     delete [] savedSolution_;
05213     savedSolution_ =  miniModel->savedSolution_;
05214   }
05215   if (saveStatus_) {
05216     if (!miniModel->saveStatus_) {
05217       miniModel->saveStatus_ = ClpCopyOfArray(status_,numberColumns_+numberRows_);
05218     } else {
05219       for (iColumn=0;iColumn<numberTotal;iColumn++) {
05220         int jColumn = mapping[iColumn];
05221         miniModel->saveStatus_[jColumn]=saveStatus_[iColumn];
05222       }
05223     }
05224     delete [] saveStatus_;
05225     saveStatus_ =  miniModel->saveStatus_;
05226   }
05227   // Re-define pivotVariable_
05228   int iRow;
05229   for (iRow=0;iRow<numberRows_;iRow++) {
05230     int iPivot = pivotVariable_[iRow];
05231 #ifdef CLP_DEBUG
05232     printf("pb row %d, pivot %d -> %d\n",iRow,iPivot,mapping[iPivot]);
05233 #endif
05234     pivotVariable_[iRow]=mapping[iPivot];
05235     assert (pivotVariable_[iRow]>=0);
05236   }
05237   // delete stuff and move back
05238   delete matrix_;
05239   delete rowCopy_;
05240   delete primalColumnPivot_;
05241   delete nonLinearCost_;
05242   matrix_ = miniModel->matrix_;
05243   rowCopy_ = miniModel->rowCopy_;
05244   nonLinearCost_ = miniModel->nonLinearCost_;
05245   double originalOffset;
05246   miniModel->getDblParam(ClpObjOffset,originalOffset);
05247   setDblParam(ClpObjOffset,originalOffset);
05248   // Redo some stuff
05249   reducedCostWork_ = dj_;
05250   rowReducedCost_ = dj_+numberColumns_;
05251   columnActivityWork_ = solution_;
05252   rowActivityWork_ = solution_+numberColumns_;
05253   objectiveWork_ = cost_;
05254   rowObjectiveWork_ = cost_+numberColumns_;
05255   rowLowerWork_ = lower_+numberColumns_;
05256   columnLowerWork_ = lower_;
05257   rowUpperWork_ = upper_+numberColumns_;
05258   columnUpperWork_ = upper_;
05259   // Cleanup
05260   for (iRow=0;iRow<numberRows_;iRow++) {
05261     double value = rowActivityWork_[iRow] + sumFixed[iRow];
05262     rowActivityWork_[iRow] = value;
05263     switch(getRowStatus(iRow)) {
05264       
05265     case basic:
05266       break;
05267     case atUpperBound:
05268       //rowActivityWork_[iRow]=rowUpperWork_[iRow];
05269       break;
05270     case ClpSimplex::isFixed:
05271     case atLowerBound:
05272       //rowActivityWork_[iRow]=rowLowerWork_[iRow];
05273       break;
05274     case isFree:
05275       break;
05276       // superbasic
05277     case superBasic:
05278       break;
05279     }
05280   }
05281   delete [] sumFixed;
05282   nonLinearCost_->checkInfeasibilities();
05283   printf("in original %d infeasibilities summing to %g\n",
05284          nonLinearCost_->numberInfeasibilities(),nonLinearCost_->sumInfeasibilities());
05285   // Initialize weights
05286   primalColumnPivot_ = new ClpPrimalColumnSteepest(10);
05287   primalColumnPivot_->saveWeights(this,2);
05288 #ifndef NDEBUG
05289   // Check status
05290   ClpSimplex * xxxx = this;
05291   int nBasic=0;
05292   for (iColumn=0;iColumn<xxxx->numberRows_+xxxx->numberColumns_;iColumn++)
05293     if (xxxx->getStatus(iColumn)==basic)
05294       nBasic++;
05295   assert (nBasic==xxxx->numberRows_);
05296   for (iRow=0;iRow<xxxx->numberRows_;iRow++) {
05297     int iPivot=xxxx->pivotVariable_[iRow];
05298     assert (xxxx->getStatus(iPivot)==basic);
05299   }
05300 #endif
05301 }

Generated on Wed Dec 3 14:37:32 2003 for CLP by doxygen 1.3.5