Changeset 1780 for trunk


Ignore:
Timestamp:
Aug 11, 2011 3:15:40 AM (8 years ago)
Author:
forrest
Message:

stuff for parametrics

Location:
trunk/Clp/src
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Clp/src/ClpModel.hpp

    r1722 r1780  
    10141014         524288 - Clp fast dual
    10151015         1048576 - don't need to finish dual (can return 3)
     1016         2097152 - zero costs!
    10161017         NOTE - many applications can call Clp but there may be some short cuts
    10171018                which are taken which are not guaranteed safe from all applications.
  • trunk/Clp/src/ClpPackedMatrix.cpp

    r1726 r1780  
    38843884          for (i = columnStart[iColumn];
    38853885                    i < columnStart[iColumn] + columnLength[iColumn]; i++) {
    3886                rowArray->add(row[i], elementByColumn[i]);
     3886               rowArray->quickAdd(row[i], elementByColumn[i]);
    38873887          }
    38883888     } else {
     
    38923892                    i < columnStart[iColumn] + columnLength[iColumn]; i++) {
    38933893               int iRow = row[i];
    3894                rowArray->add(iRow, elementByColumn[i]*scale * rowScale[iRow]);
     3894               rowArray->quickAdd(iRow, elementByColumn[i]*scale * rowScale[iRow]);
    38953895          }
    38963896     }
  • trunk/Clp/src/ClpPresolve.cpp

    r1723 r1780  
    9696                            int numberPasses,
    9797                            bool dropNames,
    98                             bool doRowObjective)
     98                            bool doRowObjective,
     99                            const char * prohibitedRows,
     100                            const char * prohibitedColumns)
    99101{
    100102     // Check matrix
     
    105107     else
    106108          return gutsOfPresolvedModel(&si, feasibilityTolerance, keepIntegers, numberPasses, dropNames,
    107                                       doRowObjective);
     109                                      doRowObjective,
     110                                      prohibitedRows,
     111                                      prohibitedColumns);
    108112}
    109113#ifndef CLP_NO_STD
     
    15421546
    15431547     for (int j = 0; j < ncols1; j++) {
     1548#ifdef COIN_SLOW_PRESOLVE
     1549       if (hincol_[j]) {
     1550#endif
    15441551          CoinBigIndex kcs = mcstrt_[j];
    15451552          CoinBigIndex kce = kcs + hincol_[j];
     
    15481555          }
    15491556          link_[kce-1] = NO_LINK ;
     1557#ifdef COIN_SLOW_PRESOLVE
     1558       }
     1559#endif
    15501560     }
    15511561     {
     
    15741584                                  int numberPasses,
    15751585                                  bool dropNames,
    1576                                   bool doRowObjective)
     1586                                  bool doRowObjective,
     1587                                  const char * prohibitedRows,
     1588                                  const char * prohibitedColumns)
    15771589{
    15781590     ncols_ = originalModel->getNumCols();
     
    16471659                                  presolvedModel_,
    16481660                                  nrows_, nelems_, true, nonLinearValue_, ratio);
     1661          if (prohibitedRows) {
     1662            prob.setAnyProhibited();
     1663            for (int i=0;i<nrows_;i++) {
     1664              if (prohibitedRows[i])
     1665                prob.setRowProhibited(i);
     1666            }
     1667          }
     1668          if (prohibitedColumns) {
     1669            prob.setAnyProhibited();
     1670            for (int i=0;i<ncols_;i++) {
     1671              if (prohibitedColumns[i])
     1672                prob.setColProhibited(i);
     1673            }
     1674          }
    16491675          prob.setMaximumSubstitutionLevel(substitution_);
    16501676          if (doRowObjective)
  • trunk/Clp/src/ClpPresolve.hpp

    r1699 r1780  
    4444                                 int numberPasses = 5,
    4545                                 bool dropNames = false,
    46                                  bool doRowObjective = false);
     46                                 bool doRowObjective = false,
     47                                 const char * prohibitedRows=NULL,
     48                                 const char * prohibitedColumns=NULL);
    4749#ifndef CLP_NO_STD
    4850     /** This version saves data in a file.  The passed in model
     
    258260               int numberPasses,
    259261               bool dropNames,
    260                bool doRowObjective);
     262                                               bool doRowObjective,
     263                                               const char * prohibitedRows=NULL,
     264                                               const char * prohibitedColumns=NULL);
    261265};
    262266#endif
  • trunk/Clp/src/ClpSimplex.hpp

    r1769 r1780  
    358358                                 const double * newUpper=NULL,
    359359                                 const double * newObjective=NULL);
     360     /** Take out duplicate rows (includes scaled rows and intersections).
     361         On exit whichRows has rows to delete - return code is number can be deleted
     362         or -1 if would be infeasible.
     363         If tolerance is -1.0 use primalTolerance for equality rows and infeasibility
     364         If cleanUp not zero then spend more time trying to leave more stable row
     365         and make row bounds exact multiple of cleanUp if close enough
     366     */
     367     int outDuplicateRows(int numberLook,int * whichRows, double tolerance=-1.0,
     368                          double cleanUp=0.0);
     369     /** Try simple crash like techniques to get closer to primal feasibility
     370         returns final sum of infeasibilities */
     371     double moveTowardsPrimalFeasible();
     372     /** Try simple crash like techniques to remove super basic slacks
     373         but only if > threshold */
     374     void removeSuperBasicSlacks(int threshold=0);
    360375     /** Write the basis in MPS format to the specified file.
    361376         If writeValues true writes values of structurals
  • trunk/Clp/src/ClpSimplexDual.cpp

    r1761 r1780  
    46664666                         if (lastCleaned < numberIterations_ && numberTimesOptimal_ < 4 &&
    46674667                                   (numberChanged_ || (specialOptions_ & 4096) == 0)) {
     4668                           if ((specialOptions_&2097152)==0) {
    46684669                              doOriginalTolerance = 2;
    46694670                              numberTimesOptimal_++;
     
    46804681                              }
    46814682                              cleanDuals = 2; // If nothing changed optimal else primal
     4683                           } else {
     4684                             // no cost - skip checks
     4685                             problemStatus_=0;
     4686                           }
    46824687                         } else {
    46834688                              problemStatus_ = 0; // optimal
  • trunk/Clp/src/ClpSimplexOther.cpp

    r1762 r1780  
    18651865int
    18661866ClpSimplexOther::parametrics(double startingTheta, double & endingTheta, double reportIncrement,
    1867                              const double * changeLowerBound, const double * changeUpperBound,
    1868                              const double * changeLowerRhs, const double * changeUpperRhs,
     1867                             const double * lowerChangeBound, const double * upperChangeBound,
     1868                             const double * lowerChangeRhs, const double * upperChangeRhs,
    18691869                             const double * changeObjective)
    18701870{
     
    18811881          // save data
    18821882          ClpDataSave data = saveData();
     1883          // Dantzig
     1884          ClpDualRowPivot * savePivot = dualRowPivot_;
     1885          dualRowPivot_ = new ClpDualRowDantzig();
     1886          dualRowPivot_->setModel(this);
    18831887          int returnCode = reinterpret_cast<ClpSimplexDual *> (this)->startupSolve(0, NULL, 0);
    18841888          int iRow, iColumn;
     
    18871891          double * chgObjective = NULL;
    18881892
    1889           // Dantzig (as will not be used) (out later)
    1890           ClpDualRowPivot * savePivot = dualRowPivot_;
    1891           dualRowPivot_ = new ClpDualRowDantzig();
    1892           dualRowPivot_->setModel(this);
    18931893
    18941894          if (!returnCode) {
     
    19031903               assert (!rowScale_);
    19041904               double maxTheta = 1.0e50;
    1905                if (changeLowerRhs || changeUpperRhs) {
     1905               if (lowerChangeRhs || upperChangeRhs) {
    19061906                    for (iRow = 0; iRow < numberRows_; iRow++) {
    19071907                         double lower = rowLower_[iRow];
     
    19111911                              break;
    19121912                         }
    1913                          double changeLower = (changeLowerRhs) ? changeLowerRhs[iRow] : 0.0;
    1914                          double changeUpper = (changeUpperRhs) ? changeUpperRhs[iRow] : 0.0;
     1913                         double lowerChange = (lowerChangeRhs) ? lowerChangeRhs[iRow] : 0.0;
     1914                         double upperChange = (upperChangeRhs) ? upperChangeRhs[iRow] : 0.0;
    19151915                         if (lower > -1.0e20 && upper < 1.0e20) {
    1916                               if (lower + maxTheta * changeLower > upper + maxTheta * changeUpper) {
    1917                                    maxTheta = (upper - lower) / (changeLower - changeUpper);
     1916                              if (lower + maxTheta * lowerChange > upper + maxTheta * upperChange) {
     1917                                   maxTheta = (upper - lower) / (lowerChange - upperChange);
    19181918                              }
    19191919                         }
    19201920                         if (lower > -1.0e20) {
    1921                               lower_[numberColumns_+iRow] += startingTheta * changeLower;
    1922                               chgLower[numberColumns_+iRow] = changeLower;
     1921                              lower_[numberColumns_+iRow] += startingTheta * lowerChange;
     1922                              chgLower[numberColumns_+iRow] = lowerChange;
    19231923                         }
    19241924                         if (upper < 1.0e20) {
    1925                               upper_[numberColumns_+iRow] += startingTheta * changeUpper;
    1926                               chgUpper[numberColumns_+iRow] = changeUpper;
     1925                              upper_[numberColumns_+iRow] += startingTheta * upperChange;
     1926                              chgUpper[numberColumns_+iRow] = upperChange;
    19271927                         }
    19281928                    }
    19291929               }
    19301930               if (maxTheta > 0.0) {
    1931                     if (changeLowerBound || changeUpperBound) {
     1931                    if (lowerChangeBound || upperChangeBound) {
    19321932                         for (iColumn = 0; iColumn < numberColumns_; iColumn++) {
    19331933                              double lower = columnLower_[iColumn];
     
    19371937                                   break;
    19381938                              }
    1939                               double changeLower = (changeLowerBound) ? changeLowerBound[iColumn] : 0.0;
    1940                               double changeUpper = (changeUpperBound) ? changeUpperBound[iColumn] : 0.0;
     1939                              double lowerChange = (lowerChangeBound) ? lowerChangeBound[iColumn] : 0.0;
     1940                              double upperChange = (upperChangeBound) ? upperChangeBound[iColumn] : 0.0;
    19411941                              if (lower > -1.0e20 && upper < 1.0e20) {
    1942                                    if (lower + maxTheta * changeLower > upper + maxTheta * changeUpper) {
    1943                                         maxTheta = (upper - lower) / (changeLower - changeUpper);
     1942                                   if (lower + maxTheta * lowerChange > upper + maxTheta * upperChange) {
     1943                                        maxTheta = (upper - lower) / (lowerChange - upperChange);
    19441944                                   }
    19451945                              }
    19461946                              if (lower > -1.0e20) {
    1947                                    lower_[iColumn] += startingTheta * changeLower;
    1948                                    chgLower[iColumn] = changeLower;
     1947                                   lower_[iColumn] += startingTheta * lowerChange;
     1948                                   chgLower[iColumn] = lowerChange;
    19491949                              }
    19501950                              if (upper < 1.0e20) {
    1951                                    upper_[iColumn] += startingTheta * changeUpper;
    1952                                    chgUpper[iColumn] = changeUpper;
     1951                                   upper_[iColumn] += startingTheta * upperChange;
     1952                                   chgUpper[iColumn] = upperChange;
    19531953                              }
    19541954                         }
     
    20972097     return problemStatus_;
    20982098}
    2099 /* Parametrics
    2100    This is an initial slow version.
    2101    The code uses current bounds + theta * change (if change array not NULL)
    2102    It starts at startingTheta and returns ending theta in endingTheta.
    2103    If it can not reach input endingTheta return code will be 1 for infeasible,
    2104    2 for unbounded, if error on ranges -1,  otherwise 0.
    2105    Event handler may do more
    2106    On exit endingTheta is maximum reached (can be used for next startingTheta)
    2107 */
    2108 int
    2109 ClpSimplexOther::parametrics(double startingTheta, double & endingTheta,
    2110                              const double * changeLowerBound, const double * changeUpperBound,
    2111                              const double * changeLowerRhs, const double * changeUpperRhs)
    2112 {
    2113   int savePerturbation = perturbation_;
    2114   perturbation_ = 102; // switch off
    2115   algorithm_ = -1;
    2116  
    2117   // save data
    2118   ClpDataSave data = saveData();
    2119   // Dantzig (as will not be used) (out later)
    2120   ClpDualRowPivot * savePivot = dualRowPivot_;
    2121   dualRowPivot_ = new ClpDualRowDantzig();
    2122   dualRowPivot_->setModel(this);
    2123   int numberTotal = numberRows_ + numberColumns_;
    2124   /*
    2125     Save information and modify
    2126   */
    2127   double * saveLower = new double [3*numberTotal];
    2128   double * saveUpper = new double [3*numberTotal];
    2129   double * lowerCopy = saveLower+2*numberTotal;
    2130   double * upperCopy = saveUpper+2*numberTotal;
    2131   double * lowerChange = saveLower+numberTotal;
    2132   double * upperChange = saveUpper+numberTotal;
    2133   // Find theta when bounds will cross over and create arrays
    2134   memset(lowerChange, 0, numberTotal * sizeof(double));
    2135   memset(upperChange, 0, numberTotal * sizeof(double));
    2136   if (changeLowerBound)
    2137     memcpy(lowerChange,changeLowerBound,numberColumns_*sizeof(double));
    2138   if (changeUpperBound)
    2139     memcpy(upperChange,changeUpperBound,numberColumns_*sizeof(double));
    2140   if (changeLowerRhs)
    2141     memcpy(lowerChange+numberColumns_,
    2142            changeLowerRhs,numberRows_*sizeof(double));
    2143   if (changeUpperRhs)
    2144     memcpy(upperChange+numberColumns_,
    2145            changeUpperRhs,numberRows_*sizeof(double));
    2146   memcpy(lowerCopy,columnLower_,numberColumns_*sizeof(double));
    2147   memcpy(upperCopy,columnUpper_,numberColumns_*sizeof(double));
    2148   memcpy(lowerCopy+numberColumns_,
    2149          rowLower_,numberRows_*sizeof(double));
    2150   memcpy(upperCopy+numberColumns_,
    2151          rowUpper_,numberRows_*sizeof(double));
    2152   assert (!rowScale_);
    2153   double maxTheta = 1.0e50;
    2154   for (int iRow = 0; iRow < numberRows_; iRow++) {
    2155     double lower = rowLower_[iRow];
    2156     double upper = rowUpper_[iRow];
    2157     if (lower<-1.0e30)
    2158       lowerChange[numberColumns_+iRow]=0.0;
    2159     double chgLower = lowerChange[numberColumns_+iRow];
    2160     if (upper>1.0e30)
    2161       upperChange[numberColumns_+iRow]=0.0;
    2162     double chgUpper = upperChange[numberColumns_+iRow];
    2163     if (lower > -1.0e30 && upper < 1.0e30) {
    2164       if (lower + maxTheta * chgLower > upper + maxTheta * chgUpper) {
    2165         maxTheta = (upper - lower) / (chgLower - chgUpper);
    2166       }
    2167     }
    2168     lower+=startingTheta*chgLower;
    2169     upper+=startingTheta*chgUpper;
    2170     if (lower > upper) {
    2171       maxTheta = -1.0;
    2172       break;
    2173     }
    2174     rowLower_[iRow]=lower;
    2175     rowUpper_[iRow]=upper;
    2176   }
    2177   for (int iColumn = 0; iColumn < numberColumns_; iColumn++) {
    2178     double lower = columnLower_[iColumn];
    2179     double upper = columnUpper_[iColumn];
    2180     if (lower<-1.0e30)
    2181       lowerChange[iColumn]=0.0;
    2182     double chgLower = lowerChange[iColumn];
    2183     if (upper>1.0e30)
    2184       upperChange[iColumn]=0.0;
    2185     double chgUpper = upperChange[iColumn];
    2186     if (lower > -1.0e30 && upper < 1.0e30) {
    2187       if (lower + maxTheta * chgLower > upper + maxTheta * chgUpper) {
    2188         maxTheta = (upper - lower) / (chgLower - chgUpper);
    2189       }
    2190     }
    2191     lower+=startingTheta*chgLower;
    2192     upper+=startingTheta*chgUpper;
    2193     if (lower > upper) {
    2194       maxTheta = -1.0;
    2195       break;
    2196     }
    2197     columnLower_[iColumn]=lower;
    2198     columnUpper_[iColumn]=upper;
    2199   }
    2200   if (maxTheta == 1.0e50)
    2201     maxTheta = COIN_DBL_MAX;
    2202   int returnCode=0;
    2203   if (maxTheta < 0.0) {
    2204     // bad ranges or initial
    2205     returnCode = -1;
    2206   }
    2207   if (maxTheta < endingTheta) {
    2208     char line[100];
    2209     sprintf(line,"Crossover considerations reduce ending  theta from %g to %g\n",
    2210             endingTheta,maxTheta);
    2211     handler_->message(CLP_GENERAL,messages_)
    2212       << line << CoinMessageEol;
    2213     endingTheta = maxTheta;
    2214   }
    2215   if (endingTheta < startingTheta) {
    2216     // bad initial
    2217     returnCode = -2;
    2218   }
    2219   bool swapped=false;
    2220   if (!returnCode) {
    2221     returnCode = reinterpret_cast<ClpSimplexDual *> (this)->startupSolve(0, NULL, 0);
    2222     if (!returnCode) {
    2223       swapped=true;
    2224       double * temp;
    2225       memcpy(saveLower,lower_,numberTotal*sizeof(double));
    2226       temp=saveLower;
    2227       saveLower=lower_;
    2228       lower_=temp;
    2229       memcpy(saveUpper,upper_,numberTotal*sizeof(double));
    2230       temp=saveUpper;
    2231       saveUpper=upper_;
    2232       upper_=temp;
    2233       double saveEndingTheta = endingTheta;
    2234       double * saveDuals = NULL;
    2235       reinterpret_cast<ClpSimplexDual *> (this)->gutsOfDual(0, saveDuals, -1, data);
    2236       assert (!problemStatus_);
    2237       for (int i=0;i<numberRows_+numberColumns_;i++)
    2238         setFakeBound(i, noFake);
    2239       // Now do parametrics
    2240       handler_->message(CLP_PARAMETRICS_STATS, messages_)
    2241         << startingTheta << objectiveValue() << CoinMessageEol;
    2242       while (!returnCode) {
    2243         returnCode = parametricsLoop(startingTheta, endingTheta,
    2244                                      data);
    2245         if (!returnCode) {
    2246           startingTheta = endingTheta;
    2247           endingTheta = saveEndingTheta;
    2248           handler_->message(CLP_PARAMETRICS_STATS, messages_)
    2249             << startingTheta << objectiveValue() << CoinMessageEol;
    2250           if (startingTheta >= endingTheta)
    2251             break;
    2252         } else if (returnCode == -1) {
    2253           // trouble - do external solve
    2254           abort(); //needToDoSomething = true;
    2255         } else if (problemStatus_==1) {
    2256           // can't move any further
    2257           handler_->message(CLP_PARAMETRICS_STATS, messages_)
    2258             << endingTheta << objectiveValue() << CoinMessageEol;
    2259           problemStatus_=0;
    2260         }
    2261       }
    2262     }
    2263     reinterpret_cast<ClpSimplexDual *> (this)->finishSolve(0);
    2264     if (swapped&&lower_) {
    2265       double * temp=saveLower;
    2266       saveLower=lower_;
    2267       lower_=temp;
    2268       temp=saveUpper;
    2269       saveUpper=upper_;
    2270       upper_=temp;
    2271     }
    2272   }   
    2273   memcpy(columnLower_,lowerCopy,numberColumns_*sizeof(double));
    2274   memcpy(columnUpper_,upperCopy,numberColumns_*sizeof(double));
    2275   memcpy(rowLower_,lowerCopy+numberColumns_,
    2276          numberRows_*sizeof(double));
    2277   memcpy(rowUpper_,upperCopy+numberColumns_,
    2278          numberRows_*sizeof(double));
    2279   delete [] saveLower;
    2280   delete [] saveUpper;
    2281   delete dualRowPivot_;
    2282   dualRowPivot_ = savePivot;
    2283   // Restore any saved stuff
    2284   restoreData(data);
    2285   perturbation_ = savePerturbation;
    2286   char line[100];
    2287   sprintf(line,"Ending theta %g\n", endingTheta);
    2288   handler_->message(CLP_GENERAL,messages_)
    2289     << line << CoinMessageEol;
    2290   return problemStatus_;
    2291 }
    22922099/* Version of parametrics which reads from file
    22932100   See CbcClpParam.cpp for details of format
     
    28502657int
    28512658ClpSimplexOther::parametricsLoop(double startingTheta, double & endingTheta, double reportIncrement,
    2852                                  const double * changeLower, const double * changeUpper,
     2659                                 const double * lowerChange, const double * upperChange,
    28532660                                 const double * changeObjective, ClpDataSave & data,
    28542661                                 bool canTryQuick)
     
    28642671     int i;
    28652672     for ( i = 0; i < numberTotal; i++) {
    2866           lower_[i] += change * changeLower[i];
    2867           upper_[i] += change * changeUpper[i];
     2673          lower_[i] += change * lowerChange[i];
     2674          upper_[i] += change * upperChange[i];
    28682675          switch(getStatus(i)) {
    28692676
     
    29512758          } else {
    29522759               whileIterating(startingTheta,  endingTheta, reportIncrement,
    2953                               changeLower, changeUpper,
     2760                              lowerChange, upperChange,
    29542761                              changeObjective);
    29552762               startingTheta = endingTheta;
     
    29662773     }
    29672774}
     2775/* Parametrics
     2776   The code uses current bounds + theta * change (if change array not NULL)
     2777   It starts at startingTheta and returns ending theta in endingTheta.
     2778   If it can not reach input endingTheta return code will be 1 for infeasible,
     2779   2 for unbounded, if error on ranges -1,  otherwise 0.
     2780   Event handler may do more
     2781   On exit endingTheta is maximum reached (can be used for next startingTheta)
     2782*/
    29682783int
    2969 ClpSimplexOther::parametricsLoop(double startingTheta, double & endingTheta,
    2970                                  ClpDataSave & data)
     2784ClpSimplexOther::parametrics(double startingTheta, double & endingTheta,
     2785                             const double * lowerChangeBound, const double * upperChangeBound,
     2786                             const double * lowerChangeRhs, const double * upperChangeRhs)
     2787{
     2788  int savePerturbation = perturbation_;
     2789  perturbation_ = 102; // switch off
     2790  algorithm_ = -1;
     2791  // extra region
     2792  int maximumPivots = factorization_->maximumPivots();
     2793  int numberDense = factorization_->numberDense();
     2794  int length = numberRows_ + numberDense + maximumPivots;
     2795  assert (!rowArray_[4]);
     2796  rowArray_[4]=new CoinIndexedVector(length);
     2797  assert (!rowArray_[5]);
     2798  rowArray_[5]=new CoinIndexedVector(length);
     2799
     2800  // save data
     2801  ClpDataSave data = saveData();
     2802  int numberTotal = numberRows_ + numberColumns_;
     2803  int ratio = (2*sizeof(int))/sizeof(double);
     2804  assert (ratio==1||ratio==2);
     2805  // allow for unscaled - even if not needed
     2806  int lengthArrays = 4*numberTotal+(numberTotal+2)*ratio;
     2807  /*
     2808    Save information and modify
     2809  */
     2810  double * saveLower = new double [lengthArrays];
     2811  double * saveUpper = new double [lengthArrays];
     2812  double * lowerCopy = saveLower+2*numberTotal;
     2813  double * upperCopy = saveUpper+2*numberTotal;
     2814  double * lowerChange = saveLower+numberTotal;
     2815  double * upperChange = saveUpper+numberTotal;
     2816  int * lowerList = (reinterpret_cast<int *>(saveLower+4*numberTotal))+2;
     2817  int * upperList = (reinterpret_cast<int *>(saveUpper+4*numberTotal))+2;
     2818  // To mark as odd
     2819  char * markDone = reinterpret_cast<char *>(lowerList+numberTotal);
     2820  memset(markDone,0,numberTotal);
     2821  // Find theta when bounds will cross over and create arrays
     2822  memset(lowerChange, 0, numberTotal * sizeof(double));
     2823  memset(upperChange, 0, numberTotal * sizeof(double));
     2824  if (lowerChangeBound)
     2825    memcpy(lowerChange,lowerChangeBound,numberColumns_*sizeof(double));
     2826  if (upperChangeBound)
     2827    memcpy(upperChange,upperChangeBound,numberColumns_*sizeof(double));
     2828  if (lowerChangeRhs)
     2829    memcpy(lowerChange+numberColumns_,
     2830           lowerChangeRhs,numberRows_*sizeof(double));
     2831  if (upperChangeRhs)
     2832    memcpy(upperChange+numberColumns_,
     2833           upperChangeRhs,numberRows_*sizeof(double));
     2834  int nLowerChange=0;
     2835  int nUpperChange=0;
     2836  for (int i=0;i<numberColumns_;i++) {
     2837    if (lowerChange[i]) {
     2838      lowerList[nLowerChange++]=i;
     2839    }
     2840    if (upperChange[i]) {
     2841      upperList[nUpperChange++]=i;
     2842    }
     2843  }
     2844  lowerList[-2]=nLowerChange;
     2845  upperList[-2]=nUpperChange;
     2846  for (int i=numberColumns_;i<numberTotal;i++) {
     2847    if (lowerChange[i]) {
     2848      lowerList[nLowerChange++]=i;
     2849    }
     2850    if (upperChange[i]) {
     2851      upperList[nUpperChange++]=i;
     2852    }
     2853  }
     2854  lowerList[-1]=nLowerChange;
     2855  upperList[-1]=nUpperChange;
     2856  memcpy(lowerCopy,columnLower_,numberColumns_*sizeof(double));
     2857  memcpy(upperCopy,columnUpper_,numberColumns_*sizeof(double));
     2858  memcpy(lowerCopy+numberColumns_,
     2859         rowLower_,numberRows_*sizeof(double));
     2860  memcpy(upperCopy+numberColumns_,
     2861         rowUpper_,numberRows_*sizeof(double));
     2862  {
     2863    //  extra for unscaled
     2864    double * unscaledCopy;
     2865    unscaledCopy = lowerCopy + numberTotal;
     2866    memcpy(unscaledCopy,columnLower_,numberColumns_*sizeof(double));
     2867    memcpy(unscaledCopy+numberColumns_,
     2868           rowLower_,numberRows_*sizeof(double));
     2869    unscaledCopy = upperCopy + numberTotal;
     2870    memcpy(unscaledCopy,columnUpper_,numberColumns_*sizeof(double));
     2871    memcpy(unscaledCopy+numberColumns_,
     2872           rowUpper_,numberRows_*sizeof(double));
     2873  }
     2874  double maxTheta = 1.0e50;
     2875  for (int iRow = 0; iRow < numberRows_; iRow++) {
     2876    double lower = rowLower_[iRow];
     2877    double upper = rowUpper_[iRow];
     2878    if (lower<-1.0e30)
     2879      lowerChange[numberColumns_+iRow]=0.0;
     2880    double chgLower = lowerChange[numberColumns_+iRow];
     2881    if (upper>1.0e30)
     2882      upperChange[numberColumns_+iRow]=0.0;
     2883    double chgUpper = upperChange[numberColumns_+iRow];
     2884    if (lower > -1.0e30 && upper < 1.0e30) {
     2885      if (lower + maxTheta * chgLower > upper + maxTheta * chgUpper) {
     2886        maxTheta = (upper - lower) / (chgLower - chgUpper);
     2887      }
     2888    }
     2889    lower+=startingTheta*chgLower;
     2890    upper+=startingTheta*chgUpper;
     2891    if (lower > upper) {
     2892      maxTheta = -1.0;
     2893      break;
     2894    }
     2895    rowLower_[iRow]=lower;
     2896    rowUpper_[iRow]=upper;
     2897  }
     2898  for (int iColumn = 0; iColumn < numberColumns_; iColumn++) {
     2899    double lower = columnLower_[iColumn];
     2900    double upper = columnUpper_[iColumn];
     2901    if (lower<-1.0e30)
     2902      lowerChange[iColumn]=0.0;
     2903    double chgLower = lowerChange[iColumn];
     2904    if (upper>1.0e30)
     2905      upperChange[iColumn]=0.0;
     2906    double chgUpper = upperChange[iColumn];
     2907    if (lower > -1.0e30 && upper < 1.0e30) {
     2908      if (lower + maxTheta * chgLower > upper + maxTheta * chgUpper) {
     2909        maxTheta = (upper - lower) / (chgLower - chgUpper);
     2910      }
     2911    }
     2912    lower+=startingTheta*chgLower;
     2913    upper+=startingTheta*chgUpper;
     2914    if (lower > upper) {
     2915      maxTheta = -1.0;
     2916      break;
     2917    }
     2918    columnLower_[iColumn]=lower;
     2919    columnUpper_[iColumn]=upper;
     2920  }
     2921  if (maxTheta == 1.0e50)
     2922    maxTheta = COIN_DBL_MAX;
     2923  int returnCode=0;
     2924  if (maxTheta < 0.0) {
     2925    // bad ranges or initial
     2926    returnCode = -1;
     2927  }
     2928  if (maxTheta < endingTheta) {
     2929    char line[100];
     2930    sprintf(line,"Crossover considerations reduce ending  theta from %g to %g\n",
     2931            endingTheta,maxTheta);
     2932    handler_->message(CLP_GENERAL,messages_)
     2933      << line << CoinMessageEol;
     2934    endingTheta = maxTheta;
     2935  }
     2936  if (endingTheta < startingTheta) {
     2937    // bad initial
     2938    returnCode = -2;
     2939  }
     2940  bool swapped=false;
     2941  // Dantzig
     2942#define ALL_DANTZIG
     2943#ifdef ALL_DANTZIG
     2944  ClpDualRowPivot * savePivot = dualRowPivot_;
     2945  dualRowPivot_ = new ClpDualRowDantzig();
     2946  dualRowPivot_->setModel(this);
     2947#else
     2948  ClpDualRowPivot * savePivot = NULL;
     2949#endif
     2950  if (!returnCode) {
     2951    returnCode = reinterpret_cast<ClpSimplexDual *> (this)->startupSolve(0, NULL, 0);
     2952    if (!returnCode) {
     2953      swapped=true;
     2954      double * temp;
     2955      memcpy(saveLower,lower_,numberTotal*sizeof(double));
     2956      temp=saveLower;
     2957      saveLower=lower_;
     2958      lower_=temp;
     2959      //columnLowerWork_ = lower_;
     2960      //rowLowerWork_ = lower_ + numberColumns_;
     2961      memcpy(saveUpper,upper_,numberTotal*sizeof(double));
     2962      temp=saveUpper;
     2963      saveUpper=upper_;
     2964      upper_=temp;
     2965      //columnUpperWork_ = upper_;
     2966      //rowUpperWork_ = upper_ + numberColumns_;
     2967      if (rowScale_) {
     2968        // scale saved and change arrays
     2969        double * lowerChange = lower_+numberTotal;
     2970        double * upperChange = upper_+numberTotal;
     2971        double * lowerSave = lowerChange+numberTotal;
     2972        double * upperSave = upperChange+numberTotal;
     2973        for (int i=0;i<numberColumns_;i++) {
     2974          double multiplier = inverseColumnScale_[i];
     2975          if (lowerSave[i]>-1.0e20)
     2976            lowerSave[i] *= multiplier;
     2977          if (upperSave[i]<1.0e20)
     2978            upperSave[i] *= multiplier;
     2979          lowerChange[i] *= multiplier;
     2980          upperChange[i] *= multiplier;
     2981        }
     2982        lowerChange += numberColumns_;
     2983        upperChange += numberColumns_;
     2984        lowerSave += numberColumns_;
     2985        upperSave += numberColumns_;
     2986        for (int i=0;i<numberRows_;i++) {
     2987          double multiplier = rowScale_[i];
     2988          if (lowerSave[i]>-1.0e20)
     2989            lowerSave[i] *= multiplier;
     2990          if (upperSave[i]<1.0e20)
     2991            upperSave[i] *= multiplier;
     2992          lowerChange[i] *= multiplier;
     2993          upperChange[i] *= multiplier;
     2994        }
     2995      }
     2996      //double saveEndingTheta = endingTheta;
     2997      double * saveDuals = NULL;
     2998      reinterpret_cast<ClpSimplexDual *> (this)->gutsOfDual(0, saveDuals, -1, data);
     2999      if (numberPrimalInfeasibilities_&&sumPrimalInfeasibilities_<1.0e-4) {
     3000        // probably can get rid of this if we adjust every change in theta
     3001        //printf("INFEAS_A %d %g\n",numberPrimalInfeasibilities_,
     3002        //   sumPrimalInfeasibilities_);
     3003        int pass=100;
     3004        while(sumPrimalInfeasibilities_) {
     3005          pass--;
     3006          if (!pass)
     3007            break;
     3008          problemStatus_=-1;
     3009          for (int iSequence=numberColumns_;iSequence<numberTotal;iSequence++) {
     3010            double value=solution_[iSequence];
     3011            // remember scaling
     3012            if (value<lower_[iSequence]-1.0e-9) {
     3013              lower_[iSequence]=value;
     3014              lowerCopy[iSequence]=value;
     3015            } else if (value>upper_[iSequence]+1.0e-9) {
     3016              upper_[iSequence]=value;
     3017              upperCopy[iSequence]=value;
     3018            }
     3019          }
     3020          reinterpret_cast<ClpSimplexDual *> (this)->gutsOfDual(1, saveDuals, -1, data);
     3021        }
     3022      }
     3023      assert (!problemStatus_);
     3024      if (nLowerChange||nUpperChange) {
     3025#ifndef ALL_DANTZIG
     3026        // Dantzig
     3027        savePivot = dualRowPivot_;
     3028        dualRowPivot_ = new ClpDualRowDantzig();
     3029        dualRowPivot_->setModel(this);
     3030#endif
     3031        for (int i=0;i<numberRows_+numberColumns_;i++)
     3032          setFakeBound(i, noFake);
     3033        // Now do parametrics
     3034        handler_->message(CLP_PARAMETRICS_STATS, messages_)
     3035          << startingTheta << objectiveValue() << CoinMessageEol;
     3036        bool canSkipFactorization=true;
     3037        while (!returnCode) {
     3038          returnCode = parametricsLoop(startingTheta, endingTheta,
     3039                                       data,canSkipFactorization);
     3040          canSkipFactorization=false;
     3041          if (!returnCode) {
     3042            //startingTheta = endingTheta;
     3043            //endingTheta = saveEndingTheta;
     3044            handler_->message(CLP_PARAMETRICS_STATS, messages_)
     3045              << startingTheta << objectiveValue() << CoinMessageEol;
     3046            if (startingTheta >= endingTheta-primalTolerance_
     3047                ||problemStatus_==2)
     3048              break;
     3049          } else if (returnCode == -1) {
     3050            // trouble - do external solve
     3051            abort(); //needToDoSomething = true;
     3052          } else if (problemStatus_==1) {
     3053            // can't move any further
     3054            handler_->message(CLP_PARAMETRICS_STATS, messages_)
     3055              << endingTheta << objectiveValue() << CoinMessageEol;
     3056            problemStatus_=0;
     3057          }
     3058        }
     3059      }
     3060      //reinterpret_cast<ClpSimplexDual *> (this)->gutsOfDual(0, saveDuals, -1, data);
     3061    }
     3062    if (problemStatus_==2) {
     3063      delete [] ray_;
     3064      ray_ = new double [numberColumns_];
     3065    }
     3066    reinterpret_cast<ClpSimplexDual *> (this)->finishSolve(1);
     3067    if (swapped&&lower_) {
     3068      double * temp=saveLower;
     3069      saveLower=lower_;
     3070      lower_=temp;
     3071      temp=saveUpper;
     3072      saveUpper=upper_;
     3073      upper_=temp;
     3074    }
     3075  }   
     3076  if (!scalingFlag_) {
     3077    memcpy(columnLower_,lowerCopy,numberColumns_*sizeof(double));
     3078    memcpy(columnUpper_,upperCopy,numberColumns_*sizeof(double));
     3079    memcpy(rowLower_,lowerCopy+numberColumns_,
     3080           numberRows_*sizeof(double));
     3081    memcpy(rowUpper_,upperCopy+numberColumns_,
     3082           numberRows_*sizeof(double));
     3083  } else {
     3084    //  extra for unscaled
     3085    double * unscaledCopy;
     3086    unscaledCopy = lowerCopy + numberTotal;
     3087    memcpy(columnLower_,unscaledCopy,numberColumns_*sizeof(double));
     3088    memcpy(rowLower_,unscaledCopy+numberColumns_,
     3089           numberRows_*sizeof(double));
     3090    unscaledCopy = upperCopy + numberTotal;
     3091    memcpy(columnUpper_,unscaledCopy,numberColumns_*sizeof(double));
     3092    memcpy(rowUpper_,unscaledCopy+numberColumns_,
     3093           numberRows_*sizeof(double));
     3094  }
     3095  delete [] saveLower;
     3096  delete [] saveUpper;
     3097#ifdef ALL_DANTZIG
     3098  if (savePivot) {
     3099#endif
     3100    delete dualRowPivot_;
     3101    dualRowPivot_ = savePivot;
     3102#ifdef ALL_DANTZIG
     3103  }
     3104#endif
     3105  // Restore any saved stuff
     3106  restoreData(data);
     3107  perturbation_ = savePerturbation;
     3108  delete rowArray_[4];
     3109  rowArray_[4]=NULL;
     3110  delete rowArray_[5];
     3111  rowArray_[5]=NULL;
     3112  char line[100];
     3113  sprintf(line,"Ending theta %g\n", endingTheta);
     3114  handler_->message(CLP_GENERAL,messages_)
     3115    << line << CoinMessageEol;
     3116  return problemStatus_;
     3117}
     3118int
     3119ClpSimplexOther::parametricsLoop(double & startingTheta, double & endingTheta,
     3120                                 ClpDataSave & data,bool canSkipFactorization)
    29713121{
    29723122  int numberTotal = numberRows_+numberColumns_;
    2973   const double * changeLower = lower_+numberTotal;
    2974   const double * changeUpper = upper_+numberTotal;
     3123  const double * lowerChange = lower_+numberTotal;
     3124  const double * upperChange = upper_+numberTotal;
    29753125  // stuff is already at starting
    2976   // For this crude version just try and go to end
    2977   double change = 0.0;
    2978   int i;
    2979   for ( i = 0; i < numberTotal; i++) {
    2980     lower_[i] += change * changeLower[i];
    2981     upper_[i] += change * changeUpper[i];
    2982     switch(getStatus(i)) {
    2983      
    2984     case basic:
    2985     case isFree:
    2986     case superBasic:
    2987       break;
    2988     case isFixed:
    2989     case atUpperBound:
    2990       solution_[i] = upper_[i];
    2991       break;
    2992     case atLowerBound:
    2993       solution_[i] = lower_[i];
    2994       break;
    2995     }
    2996   }
     3126  int * lowerList = (reinterpret_cast<int *>(lower_+4*numberTotal))+2;
     3127  int * upperList = (reinterpret_cast<int *>(upper_+4*numberTotal))+2;
    29973128  problemStatus_ = -1;
     3129  //double saveEndingTheta=endingTheta;
    29983130
    29993131  // This says whether to restore things etc
     
    30173149    int iRow, iColumn;
    30183150    // clear
    3019     for (iRow = 0; iRow < 4; iRow++) {
     3151    for (iRow = 0; iRow < 6; iRow++) {
    30203152      rowArray_[iRow]->clear();
    30213153    }
     
    30293161    matrix_->refresh(this);
    30303162    // may factorize, checks if problem finished
    3031     statusOfProblemInParametrics(factorType, data);
     3163    if (!canSkipFactorization)
     3164      statusOfProblemInParametrics(factorType, data);
     3165    canSkipFactorization=false;
     3166    if (numberPrimalInfeasibilities_) {
     3167      // probably can get rid of this if we adjust every change in theta
     3168      //printf("INFEAS %d %g\n",numberPrimalInfeasibilities_,
     3169      //     sumPrimalInfeasibilities_);
     3170      const double * lowerChange = lower_+numberTotal;
     3171      const double * upperChange = upper_+numberTotal;
     3172      const double * startLower = lowerChange+numberTotal;
     3173      const double * startUpper = upperChange+numberTotal;
     3174      //startingTheta -= 1.0e-7;
     3175      int nLowerChange = lowerList[-1];
     3176      for (int i = 0; i < nLowerChange; i++) {
     3177        int iSequence = lowerList[i];
     3178        lower_[iSequence] = startLower[iSequence] + startingTheta * lowerChange[iSequence];
     3179      }
     3180      int nUpperChange = upperList[-1];
     3181      for (int i = 0; i < nUpperChange; i++) {
     3182        int iSequence = upperList[i];
     3183        upper_[iSequence] = startUpper[iSequence] + startingTheta * upperChange[iSequence];
     3184      }
     3185      // adjust rhs in case dual uses
     3186      memcpy(columnLower_,lower_,numberColumns_*sizeof(double));
     3187      memcpy(rowLower_,lower_+numberColumns_,numberRows_*sizeof(double));
     3188      memcpy(columnUpper_,upper_,numberColumns_*sizeof(double));
     3189      memcpy(rowUpper_,upper_+numberColumns_,numberRows_*sizeof(double));
     3190      if (rowScale_) {
     3191        for (int i=0;i<numberColumns_;i++) {
     3192          double multiplier = columnScale_[i];
     3193          if (columnLower_[i]>-1.0e20)
     3194            columnLower_[i] *= multiplier;
     3195          if (columnUpper_[i]<1.0e20)
     3196            columnUpper_[i] *= multiplier;
     3197        }
     3198        for (int i=0;i<numberRows_;i++) {
     3199          double multiplier = inverseRowScale_[i];
     3200          if (rowLower_[i]>-1.0e20)
     3201            rowLower_[i] *= multiplier;
     3202          if (rowUpper_[i]<1.0e20)
     3203            rowUpper_[i] *= multiplier;
     3204        }
     3205      }
     3206      double * saveDuals = NULL;
     3207      problemStatus_=-1;
     3208      reinterpret_cast<ClpSimplexDual *> (this)->gutsOfDual(0, saveDuals, -1, data);
     3209      int pass=100;
     3210      double moved=0.0;
     3211      while(sumPrimalInfeasibilities_) {
     3212        pass--;
     3213        if (!pass)
     3214          break;
     3215        problemStatus_=-1;
     3216        for (int iSequence=numberColumns_;iSequence<numberTotal;iSequence++) {
     3217          double value=solution_[iSequence];
     3218          if (value<lower_[iSequence]-1.0e-9) {
     3219            moved += lower_[iSequence]-value;
     3220            lower_[iSequence]=value;
     3221          } else if (value>upper_[iSequence]+1.0e-9) {
     3222            moved = upper_[iSequence]-value;
     3223            upper_[iSequence]=value;
     3224          }
     3225        }
     3226        reinterpret_cast<ClpSimplexDual *> (this)->gutsOfDual(1, saveDuals, -1, data);
     3227      }
     3228      // adjust
     3229      //printf("Should adjust - moved %g\n",moved);
     3230    }
    30323231    // Say good factorization
    30333232    factorType = 1;
     
    30473246      break;
    30483247    }
     3248#ifdef CLP_USER_DRIVEN
    30493249    // Check event
    30503250    {
     
    30563256      }
    30573257    }
     3258#endif
    30583259    // Do iterations
    30593260    problemStatus_=-1;
    30603261    whileIterating(startingTheta,  endingTheta, 0.0,
    3061                    changeLower, changeUpper,
     3262                   lowerChange, upperChange,
    30623263                   NULL);
    3063     startingTheta = endingTheta;
     3264    //startingTheta = endingTheta;
     3265    //endingTheta = saveEndingTheta;
    30643266  }
    3065   if (!problemStatus_) {
    3066     theta_ = change + startingTheta;
    3067     eventHandler_->event(ClpEventHandler::theta);
     3267  if (!problemStatus_/*||problemStatus_==2*/) {
     3268    theta_ = endingTheta;
     3269#ifdef CLP_USER_DRIVEN
     3270    {
     3271      double saveTheta=theta_;
     3272      theta_ = endingTheta;
     3273      int status=eventHandler_->event(ClpEventHandler::theta);
     3274      if (status>=0&&status<10) {
     3275        endingTheta=theta_;
     3276        theta_=saveTheta;
     3277        problemStatus_=-1;
     3278      } else {
     3279        if (status>=10) {
     3280          problemStatus_=status-10;
     3281          startingTheta=endingTheta;
     3282        }
     3283        theta_=saveTheta;
     3284      }
     3285    }
     3286#endif
    30683287    return 0;
    30693288  } else if (problemStatus_ == 10) {
     
    31863405     matrix_->correctSequence(this, fake, fake);
    31873406}
     3407//static double lastThetaX=0.0;
    31883408/* This has the flow between re-factorizations
    31893409   Reasons to come out:
     
    31973417*/
    31983418int
    3199 ClpSimplexOther::whileIterating(double startingTheta, double & endingTheta, double /*reportIncrement*/,
    3200                                 const double * changeLower, const double * changeUpper,
    3201                                 const double * changeObjective)
     3419ClpSimplexOther::whileIterating(double & startingTheta, double & endingTheta, double /*reportIncrement*/,
     3420                                const double * lowerChange, const double * upperChange,
     3421                                const double * /*changeObjective*/)
    32023422{
     3423  int numberTotal = numberColumns_ + numberRows_;
     3424  const int * lowerList = (reinterpret_cast<int *>(lower_+4*numberTotal))+2;
     3425  const int * upperList = (reinterpret_cast<int *>(upper_+4*numberTotal))+2;
    32033426     {
    32043427          int i;
     
    32203443     double lastTheta = startingTheta;
    32213444     double useTheta = startingTheta;
    3222      int numberTotal = numberColumns_ + numberRows_;
    3223      double * primalChange = new double[numberTotal];
    3224      double * dualChange = new double[numberTotal];
    3225      int iSequence;
    3226      // See if bounds
    3227      int type = 0;
    3228      for (iSequence = 0; iSequence < numberTotal; iSequence++) {
    3229           if (changeLower[iSequence] || changeUpper[iSequence]) {
    3230                type = 1;
    3231                break;
    3232           }
    3233      }
    3234 #if 0
    3235      // See if objective
    3236      for (iSequence = 0; iSequence < numberTotal; iSequence++) {
    3237           if (changeObjective[iSequence]) {
    3238                type |= 2;
    3239                break;
    3240           }
    3241      }
    3242 #endif
    3243      if (!type) {
    3244        problemStatus_=0;
    3245        return 0;
    3246      }
    32473445     while (problemStatus_ == -1) {
    32483446          double increaseTheta = CoinMin(endingTheta - lastTheta, 1.0e50);
    3249 
    32503447          // Get theta for bounds - we know can't crossover
    3251           int pivotType = nextTheta(type, increaseTheta, primalChange, dualChange,
    3252                                     changeLower, changeUpper, changeObjective);
     3448          int pivotType = nextTheta(1, increaseTheta,
     3449                                    lowerChange, upperChange, NULL);
    32533450          useTheta += theta_;
    32543451          double change = useTheta - lastTheta;
    3255           for (int i = 0; i < numberTotal; i++) {
    3256             if (changeLower[i]||changeUpper[i]) {
    3257               lower_[i] += change * changeLower[i];
    3258               upper_[i] += change * changeUpper[i];
    3259               switch(getStatus(i)) {
    3260                
    3261               case basic:
    3262               case isFree:
    3263               case superBasic:
    3264                 break;
    3265               case isFixed:
    3266               case atUpperBound:
    3267                 solution_[i] = upper_[i];
    3268                 break;
    3269               case atLowerBound:
    3270                 solution_[i] = lower_[i];
    3271                 break;
     3452          if (change>1.0e-14) {
     3453            int n;
     3454            n=lowerList[-1];
     3455            for (int i=0;i<n;i++) {
     3456              int iSequence = lowerList[i];
     3457              lower_[iSequence] += change * lowerChange[iSequence];
     3458              if(getStatus(iSequence)==atLowerBound) {
     3459                solution_[iSequence] = lower_[iSequence];
    32723460              }
    32733461            }
    3274 #if 0
    3275             cost_[i] += change * changeObjective[i];
    3276 #endif
    3277             assert (solution_[i]>lower_[i]-1.0e-5&&
    3278                     solution_[i]<upper_[i]+1.0e-5);
     3462            n=upperList[-1];
     3463            for (int i=0;i<n;i++) {
     3464              int iSequence = upperList[i];
     3465              upper_[iSequence] += change * upperChange[iSequence];
     3466              if(getStatus(iSequence)==atUpperBound||
     3467                 getStatus(iSequence)==isFixed) {
     3468                solution_[iSequence] = upper_[iSequence];
     3469              }
     3470            }
    32793471          }
    32803472          sequenceIn_=-1;
    32813473          if (pivotType) {
    3282               problemStatus_ = -2;
    3283               if (!factorization_->pivots()&&pivotRow_<0)
    3284                 problemStatus_=2;
    3285               endingTheta = useTheta;
    3286               return 4;
     3474            if (useTheta>lastTheta+1.0e-9) {
     3475              handler_->message(CLP_PARAMETRICS_STATS, messages_)
     3476                << useTheta << objectiveValue() << CoinMessageEol;
     3477              lastTheta = useTheta;
     3478            }
     3479            problemStatus_ = -2;
     3480            if (!factorization_->pivots()&&pivotRow_<0)
     3481              problemStatus_=2;
     3482#ifdef CLP_USER_DRIVEN
     3483            {
     3484              double saveTheta=theta_;
     3485              theta_ = endingTheta;
     3486              int status=eventHandler_->event(ClpEventHandler::theta);
     3487              if (status>=0&&status<10) {
     3488                endingTheta=theta_;
     3489                theta_=saveTheta;
     3490                problemStatus_=-1;
     3491                continue;
     3492              } else {
     3493                if (status>=10)
     3494                  problemStatus_=status-10;
     3495                if (status<0)
     3496                  startingTheta = useTheta;
     3497                theta_=saveTheta;
     3498              }
     3499            }
     3500#else
     3501            startingTheta = useTheta;
     3502#endif
     3503            return 4;
    32873504          }
    32883505          // choose row to go out
     
    33043521                    double btranAlpha = -alpha_ * directionOut_; // for check
    33053522                    unpackPacked(rowArray_[1]);
    3306                     // moved into updateWeights factorization_->updateColumnFT(rowArray_[2],rowArray_[1]);
    33073523                    // and update dual weights (can do in parallel - with extra array)
     3524                    rowArray_[2]->clear();
    33083525                    alpha_ = dualRowPivot_->updateWeights(rowArray_[0],
    33093526                                                          rowArray_[2],
     
    33253542                                   << alpha_
    33263543                                   << CoinMessageEol;
     3544                         // clear arrays
     3545                         rowArray_[4]->clear();
    33273546                         if (factorization_->pivots()) {
    33283547                              dualRowPivot_->unrollWeights();
     
    33753594                               rowArray_[2], theta_,
    33763595                               objectiveChange, false);
    3377 
     3596                    assert (!nswapped);
    33783597                    // which will change basic solution
    33793598                    if (nswapped) {
     
    34003619                                     objectiveChange, movement, dualIn_);
    34013620#endif
     3621                         assert (objectiveChange + fabs(movement * dualIn_) >= -1.0e-5);
    34023622                         if(factorization_->pivots()) {
    34033623                              // going backwards - factorize
     
    34643684                         problemStatus_ = -2; // factorize now
    34653685                    }
     3686                    // update change vector
     3687                    {
     3688                      double * work = rowArray_[1]->denseVector();
     3689                      int number = rowArray_[1]->getNumElements();
     3690                      int * which = rowArray_[1]->getIndices();
     3691                      assert (!rowArray_[4]->packedMode());
     3692                      assert (rowArray_[1]->packedMode());
     3693                      double pivotValue = rowArray_[4]->denseVector()[pivotRow_];
     3694                      double multiplier = -pivotValue/alpha_;
     3695                      if (multiplier) {
     3696                        for (int i = 0; i < number; i++) {
     3697                          int iRow = which[i];
     3698                          rowArray_[4]->quickAddNonZero(iRow,multiplier*work[i]);
     3699                        }
     3700                      }
     3701                      pivotValue = rowArray_[4]->denseVector()[pivotRow_];
     3702                      // we want pivot to be -multiplier
     3703                      rowArray_[4]->quickAdd(pivotRow_,-multiplier-pivotValue);
     3704                    }
    34663705                    // update primal solution
    34673706                    if (theta_ < 0.0) {
     
    34963735                    objectiveChange -= objectiveValue_;
    34973736                    // outgoing
    3498                     originalBound(sequenceOut_,useTheta,changeLower,changeUpper);
     3737                    originalBound(sequenceOut_,useTheta,lowerChange,upperChange);
    34993738                    lowerOut_=lower_[sequenceOut_];
    35003739                    upperOut_=upper_[sequenceOut_];
     
    35473786                    }
    35483787                    // and set bounds correctly
    3549                     originalBound(sequenceIn_,useTheta,changeLower,changeUpper);
     3788                    originalBound(sequenceIn_,useTheta,lowerChange,upperChange);
    35503789                    reinterpret_cast<ClpSimplexDual *> ( this)->changeBound(sequenceOut_);
    35513790                    if (whatNext == 1) {
     
    35573796                         break;
    35583797                    }
     3798#ifdef CLP_USER_DRIVEN
    35593799                    // Check event
    35603800                    {
     
    35673807                         }
    35683808                    }
     3809#endif
    35693810               } else {
    35703811                    // no incoming column is valid
    3571                  int savePivotRow = pivotRow_;
     3812#ifdef CLP_USER_DRIVEN
     3813                 rowArray_[0]->clear();
     3814                 columnArray_[0]->clear();
     3815                 theta_ = useTheta;
     3816                 lastTheta = useTheta;
     3817                 int action = eventHandler_->event(ClpEventHandler::noTheta);
     3818                 if (action>=0) {
     3819                   endingTheta=theta_;
     3820                   theta_ = 0.0;
     3821                   //adjust [4] from handler - but
     3822                   rowArray_[4]->clear(); // temp
     3823                   if (action>=0&&action<10)
     3824                     problemStatus_=-1; // carry on
     3825                   else if (action==15)
     3826                     problemStatus_ =5; // say stopped
     3827                   returnCode = 1;
     3828                   if (action==0||action>=10)
     3829                     break;
     3830                   else
     3831                     continue;
     3832                 } else {
     3833                 theta_ = 0.0;
     3834                 }
     3835#endif
    35723836                    pivotRow_ = -1;
    35733837#ifdef CLP_DEBUG
     
    35753839                         printf("** no column pivot\n");
    35763840#endif
    3577                     if (factorization_->pivots() < 5) {
    3578 #if 0
    3579                          // If not in branch and bound etc save ray
    3580                          if ((specialOptions_&(1024 | 4096)) == 0) {
    3581                               // create ray anyway
    3582                               delete [] ray_;
    3583                               ray_ = new double [ numberRows_];
    3584                               rowArray_[0]->expand(); // in case packed
    3585                               ClpDisjointCopyN(rowArray_[0]->denseVector(), numberRows_, ray_);
    3586                          }
    3587 #endif
     3841                    if (factorization_->pivots() < 10) {
    35883842                         // If we have just factorized and infeasibility reasonable say infeas
    35893843                         if (((specialOptions_ & 4096) != 0 || bestPossiblePivot < 1.0e-11) && dualBound_ > 1.0e8) {
     
    35993853                                   rowArray_[0]->clear();
    36003854                                   columnArray_[0]->clear();
    3601                                    pivotRow_ = savePivotRow;
    3602                                    int action = eventHandler_->event(ClpEventHandler::noTheta);
    3603                                    if (action==-2)
    3604                                      problemStatus_=-1; // carry on
    3605                                    returnCode = 1;
    3606                                    break;
    36073855                              }
    36083856                         }
     
    36313879          } else {
    36323880               // no pivot row
     3881#ifdef CLP_USER_DRIVEN
     3882            {
     3883              double saveTheta=theta_;
     3884              theta_ = endingTheta;
     3885              int status=eventHandler_->event(ClpEventHandler::theta);
     3886              if (status>=0&&status<10) {
     3887                endingTheta=theta_;
     3888                theta_=saveTheta;
     3889                continue;
     3890              } else {
     3891                theta_=saveTheta;
     3892              }
     3893            }
     3894#endif
    36333895#ifdef CLP_DEBUG
    36343896               if (handler_->logLevel() & 32)
     
    37514013          }
    37524014     }
    3753      delete [] primalChange;
    3754      delete [] dualChange;
    3755      endingTheta = lastTheta+theta_;
     4015     startingTheta = lastTheta+theta_;
    37564016     return returnCode;
    37574017}
     
    37954055// Computes next theta and says if objective or bounds (0= bounds, 1 objective, -1 none)
    37964056int
    3797 ClpSimplexOther::nextTheta(int type, double maxTheta, double * primalChange, double * /*dualChange*/,
    3798                            const double * changeLower, const double * changeUpper,
     4057ClpSimplexOther::nextTheta(int type, double maxTheta,
     4058                           const double * lowerChange, const double * upperChange,
    37994059                           const double * /*changeObjective*/)
    38004060{
    3801      int numberTotal = numberColumns_ + numberRows_;
    3802      int iSequence;
    3803      int iRow;
    3804      theta_ = maxTheta;
    3805      bool toLower = false;
    3806      if ((type & 1) != 0) {
    3807           // get change
    3808           for (iSequence = 0; iSequence < numberTotal; iSequence++) {
    3809                primalChange[iSequence] = 0.0;
    3810                switch(getStatus(iSequence)) {
    3811 
    3812                case basic:
    3813                case isFree:
    3814                case superBasic:
    3815                     break;
    3816                case isFixed:
    3817                case atUpperBound:
    3818                     primalChange[iSequence] = changeUpper[iSequence];
    3819                     break;
    3820                case atLowerBound:
    3821                     primalChange[iSequence] = changeLower[iSequence];
    3822                     break;
    3823                }
    3824           }
    3825           // use array
    3826           double * array = rowArray_[1]->denseVector();
    3827           // put slacks in
    3828           for (int i=0;i<numberRows_;i++)
    3829             array[i] = - primalChange[i+numberColumns_];
    3830           times(1.0, primalChange, array);
    3831           int * index = rowArray_[1]->getIndices();
    3832           int number = 0;
    3833           pivotRow_ = -1;
    3834           for (iRow = 0; iRow < numberRows_; iRow++) {
    3835                double value = array[iRow];
    3836                if (value) {
    3837                     index[number++] = iRow;
    3838                }
    3839           }
    3840           // ftran it
    3841           rowArray_[1]->setNumElements(number);
    3842           factorization_->updateColumn(rowArray_[0], rowArray_[1]);
    3843           //number = rowArray_[1]->getNumElements();
    3844           for (int iPivot = 0; iPivot < numberRows_; iPivot++) {
    3845             //int iPivot = index[iRow];
    3846                iSequence = pivotVariable_[iPivot];
    3847                // solution value will be sol - theta*alpha
    3848                // bounds will be bounds + change *theta
    3849                double currentSolution = solution_[iSequence];
    3850                double currentLower = lower_[iSequence];
    3851                double currentUpper = upper_[iSequence];
    3852                double alpha = array[iPivot];
    3853                assert (currentSolution >= currentLower - primalTolerance_);
    3854                assert (currentSolution <= currentUpper + primalTolerance_);
    3855                double thetaCoefficient;
    3856                double hitsLower = COIN_DBL_MAX;
    3857                thetaCoefficient = changeLower[iSequence] + alpha;
    3858                if (thetaCoefficient > 1.0e-8)
    3859                  hitsLower = (currentSolution - currentLower) / thetaCoefficient;
    3860                //if (hitsLower < 0.0) {
    3861                     // does not hit - but should we check further
    3862                //   hitsLower = COIN_DBL_MAX;
    3863                //}
    3864                double hitsUpper = COIN_DBL_MAX;
    3865                thetaCoefficient = changeUpper[iSequence] + alpha;
    3866                if (thetaCoefficient < -1.0e-8)
    3867                     hitsUpper = (currentSolution - currentUpper) / thetaCoefficient;
    3868                //if (hitsUpper < 0.0) {
    3869                     // does not hit - but should we check further
    3870                //   hitsUpper = COIN_DBL_MAX;
    3871                //}
    3872                if (CoinMin(hitsLower, hitsUpper) < theta_) {
    3873                     theta_ = CoinMin(hitsLower, hitsUpper);
    3874                     toLower = hitsLower < hitsUpper;
    3875                     pivotRow_ = iPivot;
    3876                }
    3877           }
    3878      }
    3879      if ((type & 2) != 0) {
    3880           abort();
    3881      }
    3882      theta_ = CoinMax(theta_,0.0);
    3883      // update solution
    3884      double * array = rowArray_[1]->denseVector();
    3885      int * index = rowArray_[1]->getIndices();
    3886      int number = rowArray_[1]->getNumElements();
    3887      for (int iRow = 0; iRow < number; iRow++) {
    3888        int iPivot = index[iRow];
    3889        iSequence = pivotVariable_[iPivot];
    3890        // solution value will be sol - theta*alpha
    3891        double alpha = array[iPivot];
    3892        solution_[iSequence] -= theta_ * alpha;
    3893      }
    3894      if (pivotRow_ >= 0) {
    3895           sequenceOut_ = pivotVariable_[pivotRow_];
    3896           valueOut_ = solution_[sequenceOut_];
    3897           lowerOut_ = lower_[sequenceOut_]+theta_*changeLower[sequenceOut_];
    3898           upperOut_ = upper_[sequenceOut_]+theta_*changeUpper[sequenceOut_];
    3899           if (!toLower) {
    3900                directionOut_ = -1;
    3901                dualOut_ = valueOut_ - upperOut_;
    3902           } else {
    3903                directionOut_ = 1;
    3904                dualOut_ = lowerOut_ - valueOut_;
    3905           }
    3906           return 0;
    3907      } else {
    3908           theta_=0.0;
    3909           return -1;
    3910      }
     4061  int numberTotal = numberColumns_ + numberRows_;
     4062  const int * lowerList = (reinterpret_cast<int *>(lower_+4*numberTotal))+2;
     4063  const int * upperList = (reinterpret_cast<int *>(upper_+4*numberTotal))+2;
     4064  int iSequence;
     4065  theta_ = maxTheta;
     4066  bool toLower = false;
     4067  assert (type==1);
     4068  // may need to decide based on model?
     4069  bool needFullUpdate = rowArray_[4]->getNumElements()==0;
     4070  double * array = rowArray_[4]->denseVector();
     4071  const int * row = matrix_->getIndices();
     4072  const int * columnLength = matrix_->getVectorLengths();
     4073  const CoinBigIndex * columnStart = matrix_->getVectorStarts();
     4074  const double * elementByColumn = matrix_->getElements();
     4075  if (!factorization_->pivots()||needFullUpdate) {
     4076    rowArray_[4]->clear();
     4077    // get change
     4078    if (!rowScale_) {
     4079      int n;
     4080      n=lowerList[-2];
     4081      int i;
     4082      for (i=0;i<n;i++) {
     4083        int iSequence = lowerList[i];
     4084        assert (iSequence<numberColumns_);
     4085        if (getColumnStatus(iSequence)==atLowerBound) {
     4086          double value=lowerChange[iSequence];
     4087          for (CoinBigIndex j = columnStart[iSequence];
     4088               j < columnStart[iSequence] + columnLength[iSequence]; j++) {
     4089            rowArray_[4]->quickAddNonZero(row[j], elementByColumn[j]*value);
     4090          }
     4091        }
     4092      }
     4093      n=lowerList[-1];
     4094      const double * change = lowerChange+numberColumns_;
     4095      for (;i<n;i++) {
     4096        int iSequence = lowerList[i]-numberColumns_;
     4097        assert (iSequence>=0);
     4098        if (getRowStatus(iSequence)==atLowerBound) {
     4099          double value=change[iSequence];
     4100          rowArray_[4]->quickAddNonZero(iSequence, -value);
     4101        }
     4102      }
     4103      n=upperList[-2];
     4104      for (i=0;i<n;i++) {
     4105        int iSequence = upperList[i];
     4106        assert (iSequence<numberColumns_);
     4107        if (getColumnStatus(iSequence)==atUpperBound) {
     4108          double value=upperChange[iSequence];
     4109          for (CoinBigIndex j = columnStart[iSequence];
     4110               j < columnStart[iSequence] + columnLength[iSequence]; j++) {
     4111            rowArray_[4]->quickAddNonZero(row[j], elementByColumn[j]*value);
     4112          }
     4113        }
     4114      }
     4115      n=upperList[-1];
     4116      change = upperChange+numberColumns_;
     4117      for (;i<n;i++) {
     4118        int iSequence = upperList[i]-numberColumns_;
     4119        assert (iSequence>=0);
     4120        if (getRowStatus(iSequence)==atUpperBound) {
     4121          double value=change[iSequence];
     4122          rowArray_[4]->quickAddNonZero(iSequence, -value);
     4123        }
     4124      }
     4125    } else {
     4126      int n;
     4127      n=lowerList[-2];
     4128      int i;
     4129      for (i=0;i<n;i++) {
     4130        int iSequence = lowerList[i];
     4131        assert (iSequence<numberColumns_);
     4132        if (getColumnStatus(iSequence)==atLowerBound) {
     4133          double value=lowerChange[iSequence];
     4134          // apply scaling
     4135          double scale = columnScale_[iSequence];
     4136          for (CoinBigIndex j = columnStart[iSequence];
     4137               j < columnStart[iSequence] + columnLength[iSequence]; j++) {
     4138            int iRow = row[j];
     4139            rowArray_[4]->quickAddNonZero(iRow, elementByColumn[j]*scale * rowScale_[iRow]*value);
     4140          }
     4141        }
     4142      }
     4143      n=lowerList[-1];
     4144      const double * change = lowerChange+numberColumns_;
     4145      for (;i<n;i++) {
     4146        int iSequence = lowerList[i]-numberColumns_;
     4147        assert (iSequence>=0);
     4148        if (getRowStatus(iSequence)==atLowerBound) {
     4149          double value=change[iSequence];
     4150          rowArray_[4]->quickAddNonZero(iSequence, -value);
     4151        }
     4152      }
     4153      n=upperList[-2];
     4154      for (i=0;i<n;i++) {
     4155        int iSequence = upperList[i];
     4156        assert (iSequence<numberColumns_);
     4157        if (getColumnStatus(iSequence)==atUpperBound) {
     4158          double value=upperChange[iSequence];
     4159          // apply scaling
     4160          double scale = columnScale_[iSequence];
     4161          for (CoinBigIndex j = columnStart[iSequence];
     4162               j < columnStart[iSequence] + columnLength[iSequence]; j++) {
     4163            int iRow = row[j];
     4164            rowArray_[4]->quickAddNonZero(iRow, elementByColumn[j]*scale * rowScale_[iRow]*value);
     4165          }
     4166        }
     4167      }
     4168      n=upperList[-1];
     4169      change = upperChange+numberColumns_;
     4170      for (;i<n;i++) {
     4171        int iSequence = upperList[i]-numberColumns_;
     4172        assert (iSequence>=0);
     4173        if (getRowStatus(iSequence)==atUpperBound) {
     4174          double value=change[iSequence];
     4175          rowArray_[4]->quickAddNonZero(iSequence, -value);
     4176        }
     4177      }
     4178    }
     4179    // ftran it
     4180    factorization_->updateColumn(rowArray_[0], rowArray_[4]);
     4181  } else {
     4182    assert (sequenceIn_>=0);
     4183    assert (sequenceOut_>=0);
     4184    assert (sequenceIn_!=sequenceOut_);
     4185    double change = (directionIn_>0) ? -lowerChange[sequenceIn_] : -upperChange[sequenceIn_];
     4186    int needed=0;
     4187    assert (!rowArray_[5]->getNumElements());
     4188    if (change) {
     4189      if (sequenceIn_<numberColumns_) {
     4190        if (!rowScale_) {
     4191          for (CoinBigIndex i = columnStart[sequenceIn_];
     4192               i < columnStart[sequenceIn_] + columnLength[sequenceIn_]; i++) {
     4193            rowArray_[5]->quickAddNonZero(row[i], elementByColumn[i]*change);
     4194          }
     4195        } else {
     4196          // apply scaling
     4197          double scale = columnScale_[sequenceIn_];
     4198          for (CoinBigIndex i = columnStart[sequenceIn_];
     4199               i < columnStart[sequenceIn_] + columnLength[sequenceIn_]; i++) {
     4200            int iRow = row[i];
     4201            rowArray_[5]->quickAddNonZero(iRow, elementByColumn[i]*scale * rowScale_[iRow]*change);
     4202          }
     4203        }
     4204      } else {
     4205        rowArray_[5]->insert(sequenceIn_-numberColumns_,-change);
     4206      }
     4207      needed++;
     4208    }
     4209    if (getStatus(sequenceOut_)==atLowerBound)
     4210      change=lowerChange[sequenceOut_];
     4211    else
     4212      change=upperChange[sequenceOut_];
     4213    if (change) {
     4214      if (sequenceOut_<numberColumns_) {
     4215        if (!rowScale_) {
     4216          for (CoinBigIndex i = columnStart[sequenceOut_];
     4217               i < columnStart[sequenceOut_] + columnLength[sequenceOut_]; i++) {
     4218            rowArray_[5]->quickAddNonZero(row[i], elementByColumn[i]*change);
     4219          }
     4220        } else {
     4221          // apply scaling
     4222          double scale = columnScale_[sequenceOut_];
     4223          for (CoinBigIndex i = columnStart[sequenceOut_];
     4224               i < columnStart[sequenceOut_] + columnLength[sequenceOut_]; i++) {
     4225            int iRow = row[i];
     4226            rowArray_[5]->quickAddNonZero(iRow, elementByColumn[i]*scale * rowScale_[iRow]*change);
     4227          }
     4228        }
     4229      } else {
     4230        rowArray_[5]->quickAddNonZero(sequenceOut_-numberColumns_,-change);
     4231      }
     4232      needed++;
     4233    }
     4234    //printf("seqin %d seqout %d needed %d\n",
     4235    //     sequenceIn_,sequenceOut_,needed);
     4236    if (needed) {
     4237      // ftran it
     4238      factorization_->updateColumn(rowArray_[0], rowArray_[5]);
     4239      // add
     4240      double * array5 = rowArray_[5]->denseVector();
     4241      int * index5 = rowArray_[5]->getIndices();
     4242      int number5 = rowArray_[5]->getNumElements();
     4243      for (int i = 0; i < number5; i++) {
     4244        int iPivot = index5[i];
     4245        rowArray_[4]->quickAddNonZero(iPivot,array5[iPivot]);
     4246        array5[iPivot]=0.0;
     4247      }
     4248      rowArray_[5]->setNumElements(0);
     4249    }
     4250  }
     4251  pivotRow_ = -1;
     4252  const int * index = rowArray_[4]->getIndices();
     4253  int number = rowArray_[4]->getNumElements();
     4254  int * lowerList2 = (reinterpret_cast<int *>(lower_+4*numberTotal))+2;
     4255  char * markDone = reinterpret_cast<char *>(lowerList2+numberTotal);
     4256#if 0
     4257  for (int iPivot = 0; iPivot < numberRows_; iPivot++) {
     4258    //int iPivot = index[iRow];
     4259    iSequence = pivotVariable_[iPivot];
     4260    // solution value will be sol - theta*alpha
     4261    // bounds will be bounds + change *theta
     4262    double currentSolution = solution_[iSequence];
     4263    double currentLower = lower_[iSequence];
     4264    double currentUpper = upper_[iSequence];
     4265    double alpha = array[iPivot];
     4266    assert (currentSolution >= currentLower - 100.0*primalTolerance_);
     4267    assert (currentSolution <= currentUpper + 100.0*primalTolerance_);
     4268    double thetaCoefficient;
     4269    double hitsLower = COIN_DBL_MAX;
     4270    thetaCoefficient = lowerChange[iSequence] + alpha;
     4271    if (thetaCoefficient > 1.0e-8)
     4272      hitsLower = (currentSolution - currentLower) / thetaCoefficient;
     4273    //if (hitsLower < 0.0) {
     4274    // does not hit - but should we check further
     4275    //   hitsLower = COIN_DBL_MAX;
     4276    //}
     4277    double hitsUpper = COIN_DBL_MAX;
     4278    thetaCoefficient = upperChange[iSequence] + alpha;
     4279    if (thetaCoefficient < -1.0e-8)
     4280      hitsUpper = (currentSolution - currentUpper) / thetaCoefficient;
     4281    //if (hitsUpper < 0.0) {
     4282    // does not hit - but should we check further
     4283    //   hitsUpper = COIN_DBL_MAX;
     4284    //}
     4285    if (CoinMin(hitsLower, hitsUpper) < theta_) {
     4286      theta_ = CoinMin(hitsLower, hitsUpper);
     4287      toLower = hitsLower < hitsUpper;
     4288      pivotRow_ = iPivot;
     4289    }
     4290  }
     4291#else
     4292  // first ones with alpha
     4293  for (int i=0;i<number;i++) {
     4294    int iPivot=index[i];
     4295    iSequence = pivotVariable_[iPivot];
     4296    assert(!markDone[iSequence]);
     4297    markDone[iSequence]=1;
     4298    // solution value will be sol - theta*alpha
     4299    // bounds will be bounds + change *theta
     4300    double currentSolution = solution_[iSequence];
     4301    double currentLower = lower_[iSequence];
     4302    double currentUpper = upper_[iSequence];
     4303    double alpha = array[iPivot];
     4304    assert (currentSolution >= currentLower - 100.0*primalTolerance_);
     4305    assert (currentSolution <= currentUpper + 100.0*primalTolerance_);
     4306    double thetaCoefficient;
     4307    thetaCoefficient = lowerChange[iSequence] + alpha;
     4308    if (thetaCoefficient > 1.0e-8) {
     4309      double gap=currentSolution-currentLower;
     4310      if (thetaCoefficient*theta_>gap) {
     4311        theta_ = gap/thetaCoefficient;
     4312        toLower=true;
     4313        pivotRow_=iPivot;
     4314      }
     4315    }
     4316    thetaCoefficient = upperChange[iSequence] + alpha;
     4317    if (thetaCoefficient < -1.0e-8) {
     4318      double gap=currentSolution-currentUpper; //negative
     4319      if (thetaCoefficient*theta_<gap) {
     4320        theta_ = gap/thetaCoefficient;
     4321        toLower=false;
     4322        pivotRow_=iPivot;
     4323      }
     4324    }
     4325  }
     4326  // now others
     4327  int nLook=lowerList[-1];
     4328  for (int i=0;i<nLook;i++) {
     4329    int iSequence = lowerList[i];
     4330    if (getColumnStatus(iSequence)==basic&&!markDone[iSequence]) {
     4331      double currentSolution = solution_[iSequence];
     4332      double currentLower = lower_[iSequence];
     4333      assert (currentSolution >= currentLower - 100.0*primalTolerance_);
     4334      double thetaCoefficient = lowerChange[iSequence];
     4335      if (thetaCoefficient > 0.0) {
     4336        double gap=currentSolution-currentLower;
     4337        if (thetaCoefficient*theta_>gap) {
     4338          theta_ = gap/thetaCoefficient;
     4339          toLower=true;
     4340          pivotRow_ = -2-iSequence;
     4341        }
     4342      }
     4343    }
     4344  }
     4345  nLook=upperList[-1];
     4346  for (int i=0;i<nLook;i++) {
     4347    int iSequence = upperList[i];
     4348    if (getColumnStatus(iSequence)==basic&&!markDone[iSequence]) {
     4349      double currentSolution = solution_[iSequence];
     4350      double currentUpper = upper_[iSequence];
     4351      assert (currentSolution <= currentUpper + 100.0*primalTolerance_);
     4352      double thetaCoefficient = upperChange[iSequence];
     4353      if (thetaCoefficient < 0) {
     4354        double gap=currentSolution-currentUpper; //negative
     4355        if (thetaCoefficient*theta_<gap) {
     4356          theta_ = gap/thetaCoefficient;
     4357          toLower=false;
     4358          pivotRow_ = -2-iSequence;
     4359        }
     4360      }
     4361    }
     4362  }
     4363  if (pivotRow_<-1) {
     4364    // find
     4365    int iSequence = -pivotRow_-2;
     4366    for (int iPivot = 0; iPivot < numberRows_; iPivot++) {
     4367      if (iSequence == pivotVariable_[iPivot]) {
     4368        pivotRow_=iPivot;
     4369        break;
     4370      }
     4371    }
     4372    assert (pivotRow_>=0);
     4373  }
     4374#endif
     4375  theta_ = CoinMax(theta_,0.0);
     4376  if (theta_>1.0e-15) {
     4377    // update solution
     4378    for (int iRow = 0; iRow < number; iRow++) {
     4379      int iPivot = index[iRow];
     4380      iSequence = pivotVariable_[iPivot];
     4381      markDone[iSequence]=0;
     4382      // solution value will be sol - theta*alpha
     4383      double alpha = array[iPivot];
     4384      solution_[iSequence] -= theta_ * alpha;
     4385    }
     4386  } else {
     4387    for (int iRow = 0; iRow < number; iRow++) {
     4388      int iPivot = index[iRow];
     4389      iSequence = pivotVariable_[iPivot];
     4390      markDone[iSequence]=0;
     4391    }
     4392  }
     4393#if 0
     4394  for (int i=0;i<numberTotal;i++)
     4395    assert(!markDone[i]);
     4396#endif
     4397  if (pivotRow_ >= 0) {
     4398    sequenceOut_ = pivotVariable_[pivotRow_];
     4399    valueOut_ = solution_[sequenceOut_];
     4400    lowerOut_ = lower_[sequenceOut_]+theta_*lowerChange[sequenceOut_];
     4401    upperOut_ = upper_[sequenceOut_]+theta_*upperChange[sequenceOut_];
     4402    if (!toLower) {
     4403      directionOut_ = -1;
     4404      dualOut_ = valueOut_ - upperOut_;
     4405    } else {
     4406      directionOut_ = 1;
     4407      dualOut_ = lowerOut_ - valueOut_;
     4408    }
     4409    return 0;
     4410  } else {
     4411    //theta_=0.0;
     4412    return -1;
     4413  }
    39114414}
    39124415// Restores bound to original bound
    39134416void
    39144417ClpSimplexOther::originalBound(int iSequence, double theta,
    3915                                const double * changeLower,
    3916                                const double * changeUpper)
     4418                               const double * lowerChange,
     4419                               const double * upperChange)
    39174420{
    39184421     if (getFakeBound(iSequence) != noFake) {
     
    39224425               // rows
    39234426               int iRow = iSequence - numberColumns_;
    3924                rowLowerWork_[iRow] = rowLower_[iRow]+theta*changeLower[iSequence];
    3925                rowUpperWork_[iRow] = rowUpper_[iRow]+theta*changeUpper[iSequence];
     4427               rowLowerWork_[iRow] = rowLower_[iRow]+theta*lowerChange[iSequence];
     4428               rowUpperWork_[iRow] = rowUpper_[iRow]+theta*upperChange[iSequence];
    39264429               if (rowScale_) {
    39274430                    if (rowLowerWork_[iRow] > -1.0e50)
     
    39374440          } else {
    39384441               // columns
    3939                columnLowerWork_[iSequence] = columnLower_[iSequence]+theta*changeLower[iSequence];
    3940                columnUpperWork_[iSequence] = columnUpper_[iSequence]+theta*changeUpper[iSequence];
     4442               columnLowerWork_[iSequence] = columnLower_[iSequence]+theta*lowerChange[iSequence];
     4443               columnUpperWork_[iSequence] = columnUpper_[iSequence]+theta*upperChange[iSequence];
    39414444               if (rowScale_) {
    39424445                    double multiplier = 1.0 * inverseColumnScale_[iSequence];
     
    61816684  return returnCode;
    61826685}
     6686#include "CoinPresolveMatrix.hpp"
     6687/* Take out duplicate rows (includes scaled rows and intersections).
     6688   On exit whichRows has rows to delete - return code is number can be deleted
     6689   or -1 if would be infeasible.
     6690   If tolerance is -1.0 use primalTolerance for equality rows and infeasibility
     6691   If cleanUp not zero then spend more time trying to leave more stable row
     6692   and make row bounds exact multiple of cleanUp if close enough
     6693   moves status to try and delete a basic slack
     6694*/
     6695int
     6696ClpSimplex::outDuplicateRows(int numberLook,int * whichRows, double tolerance,
     6697                          double cleanUp)
     6698{
     6699  double * weights = new double [numberLook+numberColumns_];
     6700  double * columnWeights = weights+numberLook;
     6701  coin_init_random_vec(columnWeights,numberColumns_);
     6702  // get row copy
     6703  CoinPackedMatrix rowCopy = *matrix();
     6704  rowCopy.reverseOrdering();
     6705  int * column = rowCopy.getMutableIndices();
     6706  CoinBigIndex * rowStart = rowCopy.getMutableVectorStarts();
     6707  int * rowLength = rowCopy.getMutableVectorLengths();
     6708  double * element = rowCopy.getMutableElements();
     6709  for (int i=0;i<numberLook;i++) {
     6710    int iRow=whichRows[i];
     6711    double value = 0.0;
     6712    CoinBigIndex start=rowStart[iRow];
     6713    CoinBigIndex end = start+rowLength[iRow];
     6714    // sort (probably in order anyway)
     6715    CoinSort_2(column+start,column+end,element+start);
     6716    for (CoinBigIndex j=start;j<end;j++) {
     6717      int iColumn = column[j];
     6718      value += columnWeights[iColumn];
     6719    }
     6720    weights[iRow]=value;
     6721    whichRows[iRow]=iRow;
     6722  }
     6723  CoinSort_2(weights,weights+numberLook,whichRows);
     6724  if (tolerance<0.0)
     6725    tolerance = primalTolerance_;
     6726  int nPossible=0;
     6727  int nDelete=0;
     6728  double value = weights[0];
     6729  double inverseCleanup = (cleanUp>0.0) ? 1.0/cleanUp : 0.0;
     6730  int firstSame=-1;
     6731  int lastSame=-1;
     6732  for (int iLook = 1; iLook < numberLook; iLook++) {
     6733    if (weights[iLook]==value) {
     6734      int iLast=whichRows[iLook-1];
     6735      if (firstSame<0) {
     6736        /* see how many same - if >2 but < ? may be
     6737           worth looking at all combinations
     6738        */
     6739        firstSame=iLook-1;
     6740        for (lastSame=iLook+1;lastSame<numberLook;lastSame++) {
     6741          if (weights[lastSame]!=value)
     6742            break;
     6743        }
     6744        //#define PRINT_DUP
     6745#ifdef PRINT_DUP
     6746        if (lastSame-firstSame>2)
     6747          printf("dupsame %d rows have same weight\n",lastSame-firstSame);
     6748#endif
     6749      }
     6750      int iThis=whichRows[iLook];
     6751      CoinBigIndex start = rowStart[iThis];
     6752      CoinBigIndex end = start + rowLength[iThis];
     6753      if (rowLength[iThis] == rowLength[iLast]) {
     6754        nPossible++;
     6755#ifdef PRINT_DUP
     6756        char line[520],temp[50];
     6757#endif
     6758        int ishift = rowStart[iLast] - start;
     6759        CoinBigIndex k;
     6760#ifdef PRINT_DUP
     6761        sprintf(line,"dupj %d,%d %d els ",
     6762                iThis,iLast,rowLength[iLast]);
     6763        int n=strlen(line);
     6764#endif
     6765        bool bad=false;
     6766        double multiplier=0.0;
     6767        for (k=start;k<end;k++) {
     6768          if (column[k] != column[k+ishift]) {
     6769            bad=true;
     6770            break;
     6771          } else {
     6772#ifdef PRINT_DUP
     6773            sprintf(temp,"(%g,%g) ",element[k],element[k+ishift]);
     6774#endif
     6775            if (!multiplier) {
     6776              multiplier = element[k]/element[k+ishift];
     6777            } else if(fabs(element[k+ishift]*multiplier-element[k])>1.0e-8) {
     6778              bad=true;
     6779            }
     6780#ifdef PRINT_DUP
     6781            int n2=strlen(temp);
     6782            if (n+n2<500) {
     6783              strcat(line,temp);
     6784              n += n2;
     6785            } else {
     6786              strcat(line,"...");
     6787              break;
     6788            }
     6789#endif
     6790          }
     6791        }
     6792        if (!bad) {
     6793#ifdef PRINT_DUP
     6794          printf("%s lo (%g,%g) up (%g,%g) - multiplier %g\n",line,rowLower_[iThis],rowUpper_[iThis],
     6795                 rowLower_[iLast],rowUpper_[iLast],multiplier);
     6796#endif
     6797          double rlo1=rowLower_[iLast];
     6798          double rup1=rowUpper_[iLast];
     6799          double rlo2=rowLower_[iThis];
     6800          double rup2=rowUpper_[iThis];
     6801          // scale
     6802          rlo1 *= multiplier;
     6803          rup1 *= multiplier;
     6804          //swap bounds if neg
     6805          if (multiplier<0.0) {
     6806            double temp = rup1;
     6807            rup1=rlo1;
     6808            rlo1=temp;
     6809          }
     6810          /* now check rhs to see what is what */
     6811#ifdef PRINT_DUP
     6812          printf("duplicate row %g %g, %g %g\n",
     6813                 rlo1,rup1,rlo2,rup2);
     6814#endif
     6815          /* we always keep this and delete last
     6816             later maybe keep better formed one */
     6817          rlo2 = CoinMax(rlo1,rlo2);
     6818          if (rlo2<-1.0e30)
     6819            rlo2=-COIN_DBL_MAX;
     6820          rup2 = CoinMin(rup1,rup2);
     6821          if (rup2>1.0e30)
     6822            rup2=COIN_DBL_MAX;
     6823#ifdef PRINT_DUP
     6824          printf("pre_duprow %dR %dR keep this\n",iLast,iThis);
     6825#endif
     6826          if (rup2<rlo2-tolerance) {
     6827            // infeasible
     6828            nDelete=-1;
     6829            break;
     6830          } else if (fabs(rup2-rlo2)<=tolerance) {
     6831            // equal - choose closer to zero
     6832            if (fabs(rup2)<fabs(rlo2))
     6833              rlo2=rup2;
     6834            else
     6835              rup2=rlo2;
     6836#ifdef PRINT_DUP
     6837            printf("Row %d has %d elements == %g\n",
     6838                   iThis,end-start,rlo2);
     6839#endif
     6840          }
     6841          if (cleanUp>0.0) {
     6842            /* see if close to multiple
     6843               always allow integer values */
     6844            if (rlo2>-1.0e30) {
     6845              double value = rlo2;
     6846              double value2 = floor(value+0.5);
     6847              if (fabs(value-value2)<1.0e-9) {
     6848                rlo2=value2;
     6849              } else {
     6850                value = rlo2*inverseCleanup;
     6851                value2 = floor(value+0.5);
     6852                if (fabs(value-value2)<1.0e-9)
     6853                  rlo2=value2*cleanUp;
     6854              }
     6855            }
     6856            if (rup2<1.0e30) {
     6857              double value = rup2;
     6858              double value2 = floor(value+0.5);
     6859              if (fabs(value-value2)<1.0e-9) {
     6860                rup2=value2;
     6861              } else {
     6862                value = rup2*inverseCleanup;
     6863                value2 = floor(value+0.5);
     6864                if (fabs(value-value2)<1.0e-9)
     6865                  rup2=value2*cleanUp;
     6866              }
     6867            }
     6868          }
     6869          rowLower_[iThis]=rlo2;
     6870          rowUpper_[iThis]=rup2;
     6871          whichRows[nDelete++]=iLast;
     6872          if (getRowStatus(iLast)!=basic) {
     6873            if (getRowStatus(iThis)==basic) {
     6874              setRowStatus(iThis,superBasic);
     6875              setRowStatus(iLast,basic);
     6876            }
     6877          }
     6878        } else {
     6879#ifdef PRINT_DUP
     6880          printf("%s lo (%g,%g) up (%g,%g) - ODD\n",line,rowLower_[iThis],rowUpper_[iThis],
     6881                 rowLower_[iLast],rowUpper_[iLast]);
     6882#endif
     6883        }
     6884      }
     6885    } else {
     6886      // say no match
     6887      firstSame=-1;
     6888      value=weights[iLook];
     6889    }
     6890  }
     6891#ifdef PRINT_DUP
     6892  printf("%d possible duplicate rows - deleting %d\n",
     6893         nPossible,nDelete);
     6894#endif
     6895  delete [] weights;
     6896  return nDelete;
     6897}
     6898/* Try simple crash like techniques to get closer to primal feasibility
     6899   returns final sum of infeasibilities */
     6900double
     6901ClpSimplex::moveTowardsPrimalFeasible()
     6902{
     6903  memset (rowActivity_,0,numberRows_*sizeof(double));
     6904  matrix()->times(columnActivity_,rowActivity_);
     6905  double sum=0.0;
     6906  int * which = new int[numberRows_];
     6907  int numberLook=0;
     6908  for (int iRow=0;iRow<numberRows_;iRow++) {
     6909    double value = rowActivity_[iRow];
     6910    double infeasibility = 0.0;
     6911    if (value<rowLower_[iRow]-primalTolerance_)
     6912      infeasibility = rowLower_[iRow]-value;
     6913    else if (value>rowUpper_[iRow]+primalTolerance_)
     6914      infeasibility = value-rowUpper_[iRow];
     6915    if (infeasibility) {
     6916      sum += infeasibility;
     6917      which[numberLook++]=iRow;
     6918    }
     6919  }
     6920  if (numberLook) {
     6921    const int * row = matrix_->getIndices();
     6922    const CoinBigIndex * columnStart = matrix_->getVectorStarts();
     6923    const int * columnLength = matrix_->getVectorLengths();
     6924    const double * element = matrix_->getElements();
     6925    // get row copy
     6926    CoinPackedMatrix rowCopy = *matrix();
     6927    rowCopy.reverseOrdering();
     6928    const int * column = rowCopy.getIndices();
     6929    const CoinBigIndex * rowStart = rowCopy.getVectorStarts();
     6930    const int * rowLength = rowCopy.getVectorLengths();
     6931    const double * elementByRow = rowCopy.getElements();
     6932    double lastSum=COIN_DBL_MAX;
     6933    while (sum>primalTolerance_&&numberLook) {
     6934      sum =0.0;
     6935      double worst=primalTolerance_;
     6936      int iWorst=-1;
     6937      int n=numberLook;
     6938      numberLook=0;
     6939      for (int iLook=0;iLook<n;iLook++) {
     6940        int iRow=which[iLook];
     6941        double value = rowActivity_[iRow];
     6942        double infeasibility = 0.0;
     6943        if (value<rowLower_[iRow]-primalTolerance_)
     6944          infeasibility = rowLower_[iRow]-value;
     6945        else if (value>rowUpper_[iRow]+primalTolerance_)
     6946          infeasibility = value-rowUpper_[iRow];
     6947        if (infeasibility) {
     6948          sum += infeasibility;
     6949          which[numberLook++]=iRow;
     6950          if (infeasibility>worst) {
     6951            worst = infeasibility;
     6952            iWorst=iRow;
     6953          }
     6954        }
     6955      }
     6956      if (sum==0.0||sum>=lastSum)
     6957        break;
     6958      lastSum=sum;
     6959      double direction;
     6960      if (rowActivity_[iWorst]<rowLower_[iWorst])
     6961        direction=1.0; // increase
     6962      else
     6963        direction=-1.0;
     6964      for (CoinBigIndex k=rowStart[iWorst];
     6965           k<rowStart[iWorst]+rowLength[iWorst];k++) {
     6966        if (worst<primalTolerance_)
     6967          break;
     6968        int iColumn = column[k];
     6969        double value=elementByRow[k]*direction;
     6970        double distance=worst;
     6971        double multiplier = (value>0.0) ? 1.0 : -1.0;
     6972        // but allow for column bounds
     6973        double currentValue = columnActivity_[iColumn];
     6974        if (multiplier>0.0)
     6975          distance = CoinMin(worst,columnUpper_[iColumn]-currentValue);
     6976        else
     6977          distance = CoinMin(worst,currentValue-columnLower_[iColumn]);
     6978        distance /= fabs(value);
     6979        for (CoinBigIndex i=columnStart[iColumn];
     6980             i<columnStart[iColumn]+columnLength[iColumn];i++) {
     6981          int iRow=row[i];
     6982          if (iRow!=iWorst) {
     6983            double value2=element[i]*multiplier;
     6984            if (value2>0.0) {
     6985              double distance2 = rowUpper_[iRow]-rowActivity_[iRow];
     6986              if (value2*distance>distance2)
     6987                distance = distance2/value2;
     6988            } else {
     6989              double distance2 = rowLower_[iRow]-rowActivity_[iRow];
     6990              if (value2*distance<distance2)
     6991                distance = distance2/value2;
     6992            }
     6993          }
     6994        }
     6995        if (distance>1.0e-12) {
     6996          worst-=distance*fabs(value);
     6997          distance *= multiplier;
     6998          columnActivity_[iColumn] = currentValue+distance;
     6999          for (CoinBigIndex i=columnStart[iColumn];
     7000               i<columnStart[iColumn]+columnLength[iColumn];i++) {
     7001            int iRow=row[i];
     7002            rowActivity_[iRow] += distance*element[i];
     7003          }
     7004        }
     7005      }
     7006    }
     7007  }
     7008  delete [] which;
     7009  return sum;
     7010}
     7011/* Try simple crash like techniques to remove super basic slacks
     7012   but only if > threshold */
     7013void
     7014ClpSimplex::removeSuperBasicSlacks(int threshold)
     7015{
     7016  // could try going both ways - for first attempt to nearer bound
     7017  memset (rowActivity_,0,numberRows_*sizeof(double));
     7018  matrix()->times(columnActivity_,rowActivity_);
     7019  double * distance = new double [numberRows_];
     7020  int * whichRows = new int [numberRows_];
     7021  int numberLook=0;
     7022  for (int iRow=0;iRow<numberRows_;iRow++) {
     7023    if (getRowStatus(iRow)!=basic) {
     7024      double value = rowActivity_[iRow];
     7025      if (value>rowLower_[iRow]+primalTolerance_&&
     7026          value<rowUpper_[iRow]-primalTolerance_) {
     7027        setRowStatus(iRow,superBasic);
     7028        distance[numberLook]=CoinMin(value-rowLower_[iRow],
     7029                                      rowUpper_[iRow]-value);
     7030        whichRows[numberLook++]=iRow;
     7031      }
     7032    }
     7033  }
     7034  if (numberLook>threshold) {
     7035    CoinSort_2(distance,distance+numberLook,whichRows);
     7036    const int * row = matrix_->getIndices();
     7037    const CoinBigIndex * columnStart = matrix_->getVectorStarts();
     7038    const int * columnLength = matrix_->getVectorLengths();
     7039    const double * element = matrix_->getElements();
     7040    // get row copy
     7041    CoinPackedMatrix rowCopy = *matrix();
     7042    rowCopy.reverseOrdering();
     7043    const int * column = rowCopy.getIndices();
     7044    const CoinBigIndex * rowStart = rowCopy.getVectorStarts();
     7045    const int * rowLength = rowCopy.getVectorLengths();
     7046    const double * elementByRow = rowCopy.getElements();
     7047    int nMoved=0;
     7048    for (int iLook=0;iLook<numberLook;iLook++) {
     7049      int kRow = whichRows[iLook];
     7050      double direction;
     7051      double needed;
     7052      if (rowUpper_[kRow]-rowActivity_[kRow]<rowActivity_[kRow]-rowLower_[kRow]) {
     7053        direction=1.0; // increase
     7054        needed = rowUpper_[kRow]-rowActivity_[kRow];
     7055      } else {
     7056        direction=-1.0;
     7057        needed = rowActivity_[kRow]-rowLower_[kRow];
     7058      }
     7059      for (CoinBigIndex k=rowStart[kRow];
     7060         k<rowStart[kRow]+rowLength[kRow];k++) {
     7061        if (needed<primalTolerance_)
     7062          break;
     7063        int iColumn = column[k];
     7064        if (getColumnStatus(iColumn)!=basic)
     7065          continue;
     7066        double value=elementByRow[k]*direction;
     7067        double distance;
     7068        double multiplier = (value>0.0) ? 1.0 : -1.0;
     7069        // but allow for column bounds
     7070        double currentValue = columnActivity_[iColumn];
     7071        if (multiplier>0.0)
     7072          distance = columnUpper_[iColumn]-currentValue;
     7073        else
     7074          distance = currentValue-columnLower_[iColumn];
     7075        for (CoinBigIndex i=columnStart[iColumn];
     7076             i<columnStart[iColumn]+columnLength[iColumn];i++) {
     7077          int iRow=row[i];
     7078          double value2=element[i]*multiplier;
     7079          if (value2>0.0) {
     7080            double distance2 = rowUpper_[iRow]-rowActivity_[iRow];
     7081            if (value2*distance>distance2)
     7082              distance = distance2/value2;
     7083          } else {
     7084            double distance2 = rowLower_[iRow]-rowActivity_[iRow];
     7085            if (value2*distance<distance2)
     7086              distance = distance2/value2;
     7087          }
     7088        }
     7089        if (distance>1.0e-12) {
     7090          distance *= multiplier;
     7091          columnActivity_[iColumn] = currentValue+distance;
     7092          for (CoinBigIndex i=columnStart[iColumn];
     7093               i<columnStart[iColumn]+columnLength[iColumn];i++) {
     7094            int iRow=row[i];
     7095            rowActivity_[iRow] += distance*element[i];
     7096          }
     7097          if (direction>0.0) {
     7098            needed = rowUpper_[kRow]-rowActivity_[kRow];
     7099          } else {
     7100            needed = rowActivity_[kRow]-rowLower_[kRow];
     7101          }
     7102        }
     7103      }
     7104      if (needed<primalTolerance_) {
     7105        nMoved++;
     7106        if (rowUpper_[kRow]-rowActivity_[kRow]<primalTolerance_)
     7107          setRowStatus(kRow,atUpperBound);
     7108        else if (rowActivity_[kRow]-rowLower_[kRow]<primalTolerance_)
     7109          setRowStatus(kRow,atLowerBound);
     7110        else
     7111          assert (rowUpper_[kRow]-rowActivity_[kRow]<primalTolerance_||
     7112                  rowActivity_[kRow]-rowLower_[kRow]<primalTolerance_);
     7113      }
     7114    }
     7115    char line[100];
     7116    sprintf(line,"Threshold %d found %d fixed %d",threshold,numberLook,nMoved);
     7117    handler_->message(CLP_GENERAL,messages_)
     7118      << line << CoinMessageEol;
     7119  }
     7120  delete [] distance;
     7121  delete [] whichRows;
     7122}
  • trunk/Clp/src/ClpSimplexOther.hpp

    r1761 r1780  
    117117                         const double * changeObjective, ClpDataSave & data,
    118118                         bool canTryQuick);
    119      int parametricsLoop(double startingTheta, double & endingTheta,
    120                          ClpDataSave & data);
     119     int parametricsLoop(double & startingTheta, double & endingTheta,
     120                         ClpDataSave & data,bool canSkipFactorization=false);
    121121     /**  Refactorizes if necessary
    122122          Checks if finished.  Updates status.
     
    137137         +3 max iterations
    138138      */
    139      int whileIterating(double startingTheta, double & endingTheta, double reportIncrement,
     139     int whileIterating(double & startingTheta, double & endingTheta, double reportIncrement,
    140140                        const double * changeLower, const double * changeUpper,
    141141                        const double * changeObjective);
     
    144144         type 1 bounds, 2 objective, 3 both.
    145145     */
    146      int nextTheta(int type, double maxTheta, double * primalChange, double * dualChange,
     146     int nextTheta(int type, double maxTheta,
    147147                   const double * changeLower, const double * changeUpper,
    148148                   const double * changeObjective);
Note: See TracChangeset for help on using the changeset viewer.