source: trunk/Clp/src/ClpModel.cpp @ 1197

Last change on this file since 1197 was 1197, checked in by forrest, 11 years ago

many changes to try and improve performance

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 127.5 KB
RevLine 
[800]1// copyright (C) 2002, International Business Machines
[2]2// Corporation and others.  All Rights Reserved.
3
[1185]4#include <cstdlib>
[50]5#include <cmath>
[2]6#include <cassert>
7#include <cfloat>
8#include <string>
[50]9#include <cstdio>
[2]10#include <iostream>
[50]11
[63]12
13#include "CoinPragma.hpp"
[2]14
[50]15#include "CoinHelperFunctions.hpp"
[225]16#include "CoinTime.hpp"
[50]17#include "ClpModel.hpp"
[344]18#include "ClpEventHandler.hpp"
[50]19#include "ClpPackedMatrix.hpp"
[650]20#ifndef SLIM_CLP
[557]21#include "ClpPlusMinusOneMatrix.hpp"
[650]22#endif
[653]23#ifndef CLP_NO_VECTOR
[169]24#include "CoinPackedVector.hpp"
[653]25#endif
[50]26#include "CoinIndexedVector.hpp"
[651]27#if SLIM_CLP==2
28#define SLIM_NOIO
29#endif
30#ifndef SLIM_NOIO
[50]31#include "CoinMpsIO.hpp"
[603]32#include "CoinFileIO.hpp"
[651]33#include "CoinModel.hpp"
34#endif
[50]35#include "ClpMessage.hpp"
[701]36#include "CoinMessage.hpp"
[119]37#include "ClpLinearObjective.hpp"
[650]38#ifndef SLIM_CLP
[225]39#include "ClpQuadraticObjective.hpp"
[540]40#include "CoinBuild.hpp"
[650]41#endif
[50]42
[2]43//#############################################################################
[1034]44ClpModel::ClpModel (bool emptyMessages) :
[2]45
46  optimizationDirection_(1),
[114]47  objectiveValue_(0.0),
48  smallElement_(1.0e-20),
[389]49  objectiveScale_(1.0),
50  rhsScale_(1.0),
[2]51  numberRows_(0),
52  numberColumns_(0),
53  rowActivity_(NULL),
54  columnActivity_(NULL),
55  dual_(NULL),
56  reducedCost_(NULL),
57  rowLower_(NULL),
58  rowUpper_(NULL),
59  objective_(NULL),
60  rowObjective_(NULL),
61  columnLower_(NULL),
62  columnUpper_(NULL),
63  matrix_(NULL),
64  rowCopy_(NULL),
[1150]65  scaledMatrix_(NULL),
[2]66  ray_(NULL),
[372]67  rowScale_(NULL),
68  columnScale_(NULL),
[1197]69  inverseRowScale_(NULL),
70  inverseColumnScale_(NULL),
[749]71  scalingFlag_(3),
[114]72  status_(NULL),
73  integerType_(NULL),
[240]74  userPointer_(NULL),
[2]75  numberIterations_(0),
[109]76  solveType_(0),
[472]77  whatsChanged_(0),
[2]78  problemStatus_(-1),
[225]79  secondaryStatus_(0),
[114]80  lengthNames_(0),
[740]81  numberThreads_(0),
[1034]82  specialOptions_(0),
[653]83#ifndef CLP_NO_STD
[2]84  defaultHandler_(true),
85  rowNames_(),
[1147]86  columnNames_(),
[653]87#else
[1147]88  defaultHandler_(true),
[653]89#endif
[1147]90  maximumColumns_(-1),
91  maximumRows_(-1),
[1197]92  maximumInternalColumns_(-1),
93  maximumInternalRows_(-1),
[1147]94  savedRowScale_(NULL),
95  savedColumnScale_(NULL)
[2]96{
[676]97  intParam_[ClpMaxNumIteration] = 2147483647;
[50]98  intParam_[ClpMaxNumIterationHotStart] = 9999999;
[1015]99  intParam_[ClpNameDiscipline] = 0;
[2]100
[123]101  dblParam_[ClpDualObjectiveLimit] = COIN_DBL_MAX;
102  dblParam_[ClpPrimalObjectiveLimit] = COIN_DBL_MAX;
[50]103  dblParam_[ClpDualTolerance] = 1e-7;
104  dblParam_[ClpPrimalTolerance] = 1e-7;
105  dblParam_[ClpObjOffset] = 0.0;
[142]106  dblParam_[ClpMaxSeconds] = -1.0;
[708]107  dblParam_[ClpPresolveTolerance] = 1.0e-8;
[2]108
[653]109#ifndef CLP_NO_STD
[50]110  strParam_[ClpProbName] = "ClpDefaultName";
[653]111#endif
[50]112  handler_ = new CoinMessageHandler();
[225]113  handler_->setLogLevel(1);
[344]114  eventHandler_ = new ClpEventHandler();
[1034]115  if (!emptyMessages) {
116    messages_ = ClpMessage();
117    coinMessages_ = CoinMessage();
118  }
[1141]119  randomNumberGenerator_.setSeed(1234567);
[2]120}
121
122//-----------------------------------------------------------------------------
123
124ClpModel::~ClpModel ()
125{
126  if (defaultHandler_) {
127    delete handler_;
128    handler_ = NULL;
129  }
[1147]130  gutsOfDelete(0);
[2]131}
[1147]132// Does most of deletion (0 = all, 1 = most)
133void 
134ClpModel::gutsOfDelete(int type)
[2]135{
[1147]136  if (!type||!permanentArrays()) {
137    maximumRows_=-1;
138    maximumColumns_ = -1;
139    delete [] rowActivity_;
140    rowActivity_=NULL;
141    delete [] columnActivity_;
142    columnActivity_=NULL;
143    delete [] dual_;
144    dual_=NULL;
145    delete [] reducedCost_;
146    reducedCost_=NULL;
147    delete [] rowLower_;
148    delete [] rowUpper_;
149    delete [] rowObjective_;
150    rowLower_=NULL;
151    rowUpper_=NULL;
152    rowObjective_=NULL;
153    delete [] columnLower_;
154    delete [] columnUpper_;
155    delete objective_;
156    columnLower_=NULL;
157    columnUpper_=NULL;
158    objective_=NULL;
159    delete [] savedRowScale_;
160    if (rowScale_==savedRowScale_)
161      rowScale_=NULL;
162    savedRowScale_ = NULL;
163    delete [] savedColumnScale_;
164    if (columnScale_==savedColumnScale_)
165      columnScale_=NULL;
166    savedColumnScale_ = NULL;
167    delete [] rowScale_;
168    rowScale_ = NULL;
169    delete [] columnScale_;
170    columnScale_ = NULL;
171    delete [] integerType_;
172    integerType_ = NULL;
173    delete [] status_;
174    status_=NULL;
175    delete eventHandler_;
176    eventHandler_=NULL;
177  }
178  whatsChanged_=0;
[2]179  delete matrix_;
180  matrix_=NULL;
181  delete rowCopy_;
182  rowCopy_=NULL;
[1150]183  delete scaledMatrix_;
184  scaledMatrix_=NULL,
[2]185  delete [] ray_;
186  ray_ = NULL;
[1034]187  specialOptions_ = 0;
[2]188}
[1147]189void 
190ClpModel::setRowScale(double * scale) 
191{
192  if (!savedRowScale_) {
193    delete [] (double *) rowScale_; 
194    rowScale_ = scale;
195  } else {
196    assert (!scale);
197    rowScale_ = NULL;
198  }
199}
200void 
201ClpModel::setColumnScale(double * scale) 
202{
203  if (!savedColumnScale_) {
204    delete [] (double *) columnScale_; 
205    columnScale_ = scale;
206  } else {
207    assert (!scale);
208    columnScale_ = NULL;
209  }
210}
[2]211//#############################################################################
212void ClpModel::setPrimalTolerance( double value) 
213{
[647]214  if (value>0.0&&value<1.0e10) 
[50]215    dblParam_[ClpPrimalTolerance]=value;
[2]216}
217void ClpModel::setDualTolerance( double value) 
218{
219  if (value>0.0&&value<1.0e10)
[50]220    dblParam_[ClpDualTolerance]=value;
[2]221}
[225]222void ClpModel::setOptimizationDirection( double value) 
[2]223{
[225]224  optimizationDirection_=value;
[2]225}
226void
227ClpModel::gutsOfLoadModel (int numberRows, int numberColumns, 
228                     const double* collb, const double* colub,   
229                     const double* obj,
230                     const double* rowlb, const double* rowub,
231                                const double * rowObjective)
232{
[344]233  // save event handler in case already set
234  ClpEventHandler * handler = eventHandler_->clone();
[1053]235  // Save specialOptions
236  int saveOptions = specialOptions_;
[1147]237  gutsOfDelete(0);
[1053]238  specialOptions_ = saveOptions;
[344]239  eventHandler_ = handler;
[2]240  numberRows_=numberRows;
241  numberColumns_=numberColumns;
242  rowActivity_=new double[numberRows_];
243  columnActivity_=new double[numberColumns_];
244  dual_=new double[numberRows_];
245  reducedCost_=new double[numberColumns_];
246
[706]247  CoinZeroN(dual_,numberRows_);
248  CoinZeroN(reducedCost_,numberColumns_);
[2]249  int iRow,iColumn;
250
[123]251  rowLower_=ClpCopyOfArray(rowlb,numberRows_,-COIN_DBL_MAX);
252  rowUpper_=ClpCopyOfArray(rowub,numberRows_,COIN_DBL_MAX);
[119]253  double * objective=ClpCopyOfArray(obj,numberColumns_,0.0);
254  objective_ = new ClpLinearObjective(objective,numberColumns_);
255  delete [] objective;
[50]256  rowObjective_=ClpCopyOfArray(rowObjective,numberRows_);
257  columnLower_=ClpCopyOfArray(collb,numberColumns_,0.0);
[123]258  columnUpper_=ClpCopyOfArray(colub,numberColumns_,COIN_DBL_MAX);
[466]259  // set default solution and clean bounds
[2]260  for (iRow=0;iRow<numberRows_;iRow++) {
261    if (rowLower_[iRow]>0.0) {
262      rowActivity_[iRow]=rowLower_[iRow];
263    } else if (rowUpper_[iRow]<0.0) {
264      rowActivity_[iRow]=rowUpper_[iRow];
265    } else {
266      rowActivity_[iRow]=0.0;
267    }
[466]268    if (rowLower_[iRow]<-1.0e27)
269      rowLower_[iRow]=-COIN_DBL_MAX;
270    if (rowUpper_[iRow]>1.0e27)
271      rowUpper_[iRow]=COIN_DBL_MAX;
[2]272  }
273  for (iColumn=0;iColumn<numberColumns_;iColumn++) {
274    if (columnLower_[iColumn]>0.0) {
275      columnActivity_[iColumn]=columnLower_[iColumn];
276    } else if (columnUpper_[iColumn]<0.0) {
277      columnActivity_[iColumn]=columnUpper_[iColumn];
278    } else {
279      columnActivity_[iColumn]=0.0;
280    }
[466]281    if (columnLower_[iColumn]<-1.0e27)
282      columnLower_[iColumn]=-COIN_DBL_MAX;
283    if (columnUpper_[iColumn]>1.0e27)
284      columnUpper_[iColumn]=COIN_DBL_MAX;
[2]285  }
286}
[133]287// This just loads up a row objective
[134]288void ClpModel::setRowObjective(const double * rowObjective)
[133]289{
290  delete [] rowObjective_;
291  rowObjective_=ClpCopyOfArray(rowObjective,numberRows_);
[472]292  whatsChanged_=0;
[133]293}
[2]294void
295ClpModel::loadProblem (  const ClpMatrixBase& matrix,
296                     const double* collb, const double* colub,   
297                     const double* obj,
298                     const double* rowlb, const double* rowub,
299                                const double * rowObjective)
300{
301  gutsOfLoadModel(matrix.getNumRows(),matrix.getNumCols(),
302                  collb, colub, obj, rowlb, rowub, rowObjective);
303  if (matrix.isColOrdered()) {
304    matrix_=matrix.clone();
305  } else {
306    // later may want to keep as unknown class
[50]307    CoinPackedMatrix matrix2;
[2]308    matrix2.reverseOrderedCopyOf(*matrix.getPackedMatrix());
309    matrix.releasePackedMatrix();
310    matrix_=new ClpPackedMatrix(matrix2);
311  }   
[558]312  matrix_->setDimensions(numberRows_,numberColumns_);
[2]313}
314void
[50]315ClpModel::loadProblem (  const CoinPackedMatrix& matrix,
[2]316                     const double* collb, const double* colub,   
317                     const double* obj,
318                     const double* rowlb, const double* rowub,
319                                const double * rowObjective)
320{
321  gutsOfLoadModel(matrix.getNumRows(),matrix.getNumCols(),
322                  collb, colub, obj, rowlb, rowub, rowObjective);
323  if (matrix.isColOrdered()) {
324    matrix_=new ClpPackedMatrix(matrix);
325  } else {
[50]326    CoinPackedMatrix matrix2;
[2]327    matrix2.reverseOrderedCopyOf(matrix);
328    matrix_=new ClpPackedMatrix(matrix2);
329  }   
[558]330  matrix_->setDimensions(numberRows_,numberColumns_);
[2]331}
332void
333ClpModel::loadProblem ( 
334                              const int numcols, const int numrows,
[50]335                              const CoinBigIndex* start, const int* index,
[2]336                              const double* value,
337                              const double* collb, const double* colub,   
338                              const double* obj,
339                              const double* rowlb, const double* rowub,
340                              const double * rowObjective)
341{
342  gutsOfLoadModel(numrows, numcols,
343                  collb, colub, obj, rowlb, rowub, rowObjective);
[1034]344  int numberElements = start ? start[numcols] : 0;
345  CoinPackedMatrix matrix(true,numrows,numrows ? numcols : 0,numberElements,
[2]346                              value,index,start,NULL);
347  matrix_ = new ClpPackedMatrix(matrix);
[558]348  matrix_->setDimensions(numberRows_,numberColumns_);
[2]349}
350void
[50]351ClpModel::loadProblem ( 
352                              const int numcols, const int numrows,
353                              const CoinBigIndex* start, const int* index,
354                              const double* value,const int* length,
355                              const double* collb, const double* colub,   
356                              const double* obj,
357                              const double* rowlb, const double* rowub,
358                              const double * rowObjective)
359{
360  gutsOfLoadModel(numrows, numcols,
361                  collb, colub, obj, rowlb, rowub, rowObjective);
362  // Compute number of elements
363  int numberElements = 0;
364  int i;
365  for (i=0;i<numcols;i++) 
366    numberElements += length[i];
367  CoinPackedMatrix matrix(true,numrows,numcols,numberElements,
368                              value,index,start,length);
369  matrix_ = new ClpPackedMatrix(matrix);
370}
[651]371#ifndef SLIM_NOIO
[546]372// This loads a model from a coinModel object - returns number of errors
373int 
[557]374ClpModel::loadProblem (  CoinModel & modelObject,bool tryPlusMinusOne)
[546]375{
[1034]376  if (modelObject.numberColumns()==0&&modelObject.numberRows()==0)
[618]377    return 0;
[546]378  int numberErrors = 0;
379  // Set arrays for normal use
380  double * rowLower = modelObject.rowLowerArray();
381  double * rowUpper = modelObject.rowUpperArray();
382  double * columnLower = modelObject.columnLowerArray();
383  double * columnUpper = modelObject.columnUpperArray();
384  double * objective = modelObject.objectiveArray();
385  int * integerType = modelObject.integerTypeArray();
386  double * associated = modelObject.associatedArray();
387  // If strings then do copies
388  if (modelObject.stringsExist()) {
389    numberErrors = modelObject.createArrays(rowLower, rowUpper, columnLower, columnUpper,
390                                            objective, integerType,associated);
391  }
392  int numberRows = modelObject.numberRows();
393  int numberColumns = modelObject.numberColumns();
394  gutsOfLoadModel(numberRows, numberColumns,
395                  columnLower, columnUpper, objective, rowLower, rowUpper, NULL);
[558]396  CoinBigIndex * startPositive = NULL;
397  CoinBigIndex * startNegative = NULL;
398  delete matrix_;
399  if (tryPlusMinusOne) {
400    startPositive = new CoinBigIndex[numberColumns+1];
401    startNegative = new CoinBigIndex[numberColumns];
402    modelObject.countPlusMinusOne(startPositive,startNegative,associated);
403    if (startPositive[0]<0) {
404      // no good
405      tryPlusMinusOne=false;
406      delete [] startPositive;
407      delete [] startNegative;
408    }
409  }
[650]410#ifndef SLIM_CLP
[558]411  if (!tryPlusMinusOne) {
[650]412#endif
[558]413    CoinPackedMatrix matrix;
414    modelObject.createPackedMatrix(matrix,associated);
415    matrix_ = new ClpPackedMatrix(matrix);
[650]416#ifndef SLIM_CLP
[558]417  } else {
418    // create +-1 matrix
419    CoinBigIndex size = startPositive[numberColumns];
420    int * indices = new int[size];
421    modelObject.createPlusMinusOne(startPositive,startNegative,indices,
422                                   associated);
423    // Get good object
424    ClpPlusMinusOneMatrix * matrix = new ClpPlusMinusOneMatrix();
425    matrix->passInCopy(numberRows,numberColumns,
426                       true,indices,startPositive,startNegative);
427    matrix_=matrix;
428  }
[650]429#endif
[653]430#ifndef CLP_NO_STD
[546]431  // Do names if wanted
[637]432  int numberItems;
433  numberItems = modelObject.rowNames()->numberItems();
434  if (numberItems) {
[546]435    const char *const * rowNames=modelObject.rowNames()->names();
[637]436    copyRowNames(rowNames,0,numberItems);
[546]437  }
[637]438  numberItems = modelObject.columnNames()->numberItems();
439  if (numberItems) {
[546]440    const char *const * columnNames=modelObject.columnNames()->names();
[637]441    copyColumnNames(columnNames,0,numberItems);
[546]442  }
[653]443#endif
[546]444  // Do integers if wanted
445  assert(integerType);
446  for (int iColumn=0;iColumn<numberColumns;iColumn++) {
447    if (integerType[iColumn])
448      setInteger(iColumn);
449  }
450  if (rowLower!=modelObject.rowLowerArray()||
451      columnLower!=modelObject.columnLowerArray()) {
452    delete [] rowLower;
453    delete [] rowUpper;
454    delete [] columnLower;
455    delete [] columnUpper;
456    delete [] objective;
457    delete [] integerType;
[560]458    delete [] associated;
459    if (numberErrors)
460      handler_->message(CLP_BAD_STRING_VALUES,messages_)
461        <<numberErrors
462        <<CoinMessageEol;
[546]463  }
[558]464  matrix_->setDimensions(numberRows_,numberColumns_);
[546]465  return numberErrors;
466}
[651]467#endif
[50]468void
[2]469ClpModel::getRowBound(int iRow, double& lower, double& upper) const
470{
[123]471  lower=-COIN_DBL_MAX;
472  upper=COIN_DBL_MAX;
[2]473  if (rowUpper_)
474    upper=rowUpper_[iRow];
475  if (rowLower_)
476    lower=rowLower_[iRow];
477}
[470]478//------------------------------------------------------------------
[471]479#ifndef NDEBUG
480// For errors to make sure print to screen
481// only called in debug mode
482static void indexError(int index,
483                        std::string methodName)
484{
485  std::cerr<<"Illegal index "<<index<<" in ClpModel::"<<methodName<<std::endl;
486  throw CoinError("Illegal index",methodName,"ClpModel");
487}
488#endif
[470]489/* Set an objective function coefficient */
490void 
491ClpModel::setObjectiveCoefficient( int elementIndex, double elementValue )
492{
493#ifndef NDEBUG
494  if (elementIndex<0||elementIndex>=numberColumns_) {
495    indexError(elementIndex,"setObjectiveCoefficient");
496  }
497#endif
498  objective()[elementIndex] = elementValue;
[472]499  whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep)
[470]500}
501/* Set a single row lower bound<br>
502   Use -DBL_MAX for -infinity. */
503void 
504ClpModel::setRowLower( int elementIndex, double elementValue ) {
505  if (elementValue<-1.0e27)
506    elementValue=-COIN_DBL_MAX;
507  rowLower_[elementIndex] = elementValue;
[472]508  whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep)
[470]509}
510     
511/* Set a single row upper bound<br>
512   Use DBL_MAX for infinity. */
513void 
514ClpModel::setRowUpper( int elementIndex, double elementValue ) {
515  if (elementValue>1.0e27)
516    elementValue=COIN_DBL_MAX;
517  rowUpper_[elementIndex] = elementValue;
[472]518  whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep)
[470]519}
520   
521/* Set a single row lower and upper bound */
522void 
523ClpModel::setRowBounds( int elementIndex,
524              double lower, double upper ) {
525  if (lower<-1.0e27)
526    lower=-COIN_DBL_MAX;
527  if (upper>1.0e27)
528    upper=COIN_DBL_MAX;
[560]529  CoinAssert (upper>=lower);
[470]530  rowLower_[elementIndex] = lower;
531  rowUpper_[elementIndex] = upper;
[472]532  whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep)
[470]533}
534void ClpModel::setRowSetBounds(const int* indexFirst,
535                                            const int* indexLast,
536                                            const double* boundList)
537{
538#ifndef NDEBUG
539  int n = numberRows_;
540#endif
541  double * lower = rowLower_;
542  double * upper = rowUpper_;
[472]543  whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep)
[470]544  while (indexFirst != indexLast) {
545    const int iRow=*indexFirst++;
546#ifndef NDEBUG
547    if (iRow<0||iRow>=n) {
548      indexError(iRow,"setRowSetBounds");
549    }
550#endif
551    lower[iRow]= *boundList++;
552    upper[iRow]= *boundList++;
553    if (lower[iRow]<-1.0e27)
554      lower[iRow]=-COIN_DBL_MAX;
555    if (upper[iRow]>1.0e27)
556      upper[iRow]=COIN_DBL_MAX;
[560]557    CoinAssert (upper[iRow]>=lower[iRow]);
[470]558  }
559}
560//-----------------------------------------------------------------------------
561/* Set a single column lower bound<br>
562   Use -DBL_MAX for -infinity. */
563void 
564ClpModel::setColumnLower( int elementIndex, double elementValue )
565{
566#ifndef NDEBUG
567  int n = numberColumns_;
568  if (elementIndex<0||elementIndex>=n) {
569    indexError(elementIndex,"setColumnLower");
570  }
571#endif
572  if (elementValue<-1.0e27)
573    elementValue=-COIN_DBL_MAX;
574  columnLower_[elementIndex] = elementValue;
[472]575  whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep)
[470]576}
577     
578/* Set a single column upper bound<br>
579   Use DBL_MAX for infinity. */
580void 
581ClpModel::setColumnUpper( int elementIndex, double elementValue )
582{
583#ifndef NDEBUG
584  int n = numberColumns_;
585  if (elementIndex<0||elementIndex>=n) {
586    indexError(elementIndex,"setColumnUpper");
587  }
588#endif
589  if (elementValue>1.0e27)
590    elementValue=COIN_DBL_MAX;
591  columnUpper_[elementIndex] = elementValue;
[472]592  whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep)
[470]593}
594
595/* Set a single column lower and upper bound */
596void 
597ClpModel::setColumnBounds( int elementIndex,
598                                     double lower, double upper )
599{
600#ifndef NDEBUG
601  int n = numberColumns_;
602  if (elementIndex<0||elementIndex>=n) {
603    indexError(elementIndex,"setColumnBounds");
604  }
605#endif
606  if (lower<-1.0e27)
607    lower=-COIN_DBL_MAX;
608  if (upper>1.0e27)
609    upper=COIN_DBL_MAX;
610  columnLower_[elementIndex] = lower;
611  columnUpper_[elementIndex] = upper;
[560]612  CoinAssert (upper>=lower);
[472]613  whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep)
[470]614}
615void ClpModel::setColumnSetBounds(const int* indexFirst,
616                                            const int* indexLast,
617                                            const double* boundList)
618{
619  double * lower = columnLower_;
620  double * upper = columnUpper_;
[472]621  whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep)
[470]622#ifndef NDEBUG
623  int n = numberColumns_;
624#endif
625  while (indexFirst != indexLast) {
626    const int iColumn=*indexFirst++;
627#ifndef NDEBUG
628    if (iColumn<0||iColumn>=n) {
629      indexError(iColumn,"setColumnSetBounds");
630    }
631#endif
632    lower[iColumn]= *boundList++;
633    upper[iColumn]= *boundList++;
[560]634    CoinAssert (upper[iColumn]>=lower[iColumn]);
[470]635    if (lower[iColumn]<-1.0e27)
636      lower[iColumn]=-COIN_DBL_MAX;
637    if (upper[iColumn]>1.0e27)
638      upper[iColumn]=COIN_DBL_MAX;
639  }
640}
641//-----------------------------------------------------------------------------
[2]642//#############################################################################
643// Copy constructor.
[393]644ClpModel::ClpModel(const ClpModel &rhs, int scalingMode) :
[2]645  optimizationDirection_(rhs.optimizationDirection_),
646  numberRows_(rhs.numberRows_),
[1147]647  numberColumns_(rhs.numberColumns_),
648  specialOptions_(rhs.specialOptions_),
649  maximumColumns_(-1),
650  maximumRows_(-1),
[1197]651  maximumInternalColumns_(-1),
652  maximumInternalRows_(-1),
[1147]653  savedRowScale_(NULL),
654  savedColumnScale_(NULL)
[2]655{
656  gutsOfCopy(rhs);
[393]657  if (scalingMode>=0&&matrix_&&
658      matrix_->allElementsInRange(this,smallElement_,1.0e20)) {
659    // really do scaling
660    scalingFlag_=scalingMode;
[1147]661    setRowScale(NULL);
662    setColumnScale(NULL);
[634]663    delete rowCopy_; // in case odd
664    rowCopy_=NULL;
[1150]665    delete scaledMatrix_;
666    scaledMatrix_=NULL;
[634]667    if (scalingMode&&!matrix_->scale(this)) {
[393]668      // scaling worked - now apply
669      gutsOfScaling();
670      // pretend not scaled
671      scalingFlag_ = -scalingFlag_;
672    } else {
673      // not scaled
674      scalingFlag_=0;
675    }
676  }
[1141]677  randomNumberGenerator_.setSeed(1234567);
[2]678}
679// Assignment operator. This copies the data
680ClpModel & 
681ClpModel::operator=(const ClpModel & rhs)
682{
683  if (this != &rhs) {
684    if (defaultHandler_) {
[1147]685      //delete handler_;
686      //handler_ = NULL;
[2]687    }
[1147]688    gutsOfDelete(1);
[2]689    optimizationDirection_ = rhs.optimizationDirection_;
690    numberRows_ = rhs.numberRows_;
691    numberColumns_ = rhs.numberColumns_;
[1147]692    gutsOfCopy(rhs,-1);
[2]693  }
694  return *this;
695}
[1147]696/* Does most of copying
697   If trueCopy 0 then just points to arrays
698   If -1 leaves as much as possible */
[2]699void 
[1147]700ClpModel::gutsOfCopy(const ClpModel & rhs, int trueCopy)
[2]701{
702  defaultHandler_ = rhs.defaultHandler_;
[1147]703  if (trueCopy>=0) {
704    if (defaultHandler_) 
705      handler_ = new CoinMessageHandler(*rhs.handler_);
706    else 
707      handler_ = rhs.handler_;
708    eventHandler_ = rhs.eventHandler_->clone();
709    randomNumberGenerator_ = rhs.randomNumberGenerator_;
710    messages_ = rhs.messages_;
711    coinMessages_ = rhs.coinMessages_;
712  } else {
713    if (!eventHandler_&&rhs.eventHandler_)
714      eventHandler_ = rhs.eventHandler_->clone();
715  }
[50]716  intParam_[ClpMaxNumIteration] = rhs.intParam_[ClpMaxNumIteration];
717  intParam_[ClpMaxNumIterationHotStart] = 
718    rhs.intParam_[ClpMaxNumIterationHotStart];
[1015]719  intParam_[ClpNameDiscipline] = rhs.intParam_[ClpNameDiscipline] ;
[2]720
[50]721  dblParam_[ClpDualObjectiveLimit] = rhs.dblParam_[ClpDualObjectiveLimit];
722  dblParam_[ClpPrimalObjectiveLimit] = rhs.dblParam_[ClpPrimalObjectiveLimit];
723  dblParam_[ClpDualTolerance] = rhs.dblParam_[ClpDualTolerance];
724  dblParam_[ClpPrimalTolerance] = rhs.dblParam_[ClpPrimalTolerance];
725  dblParam_[ClpObjOffset] = rhs.dblParam_[ClpObjOffset];
[142]726  dblParam_[ClpMaxSeconds] = rhs.dblParam_[ClpMaxSeconds];
[708]727  dblParam_[ClpPresolveTolerance] = rhs.dblParam_[ClpPresolveTolerance];
[653]728#ifndef CLP_NO_STD
[2]729
[50]730  strParam_[ClpProbName] = rhs.strParam_[ClpProbName];
[653]731#endif
[2]732
[225]733  optimizationDirection_ = rhs.optimizationDirection_;
[2]734  objectiveValue_=rhs.objectiveValue_;
[112]735  smallElement_ = rhs.smallElement_;
[389]736  objectiveScale_ = rhs.objectiveScale_;
737  rhsScale_ = rhs.rhsScale_;
[2]738  numberIterations_ = rhs.numberIterations_;
[109]739  solveType_ = rhs.solveType_;
[472]740  whatsChanged_ = rhs.whatsChanged_;
[2]741  problemStatus_ = rhs.problemStatus_;
[225]742  secondaryStatus_ = rhs.secondaryStatus_;
743  numberRows_ = rhs.numberRows_;
744  numberColumns_ = rhs.numberColumns_;
[240]745  userPointer_ = rhs.userPointer_;
[372]746  scalingFlag_ = rhs.scalingFlag_;
[1034]747  specialOptions_ = rhs.specialOptions_;
[2]748  if (trueCopy) {
[653]749#ifndef CLP_NO_STD
[2]750    lengthNames_ = rhs.lengthNames_;
[589]751    if (lengthNames_) {
752      rowNames_ = rhs.rowNames_;
753      columnNames_ = rhs.columnNames_;
754    }
[653]755#endif
[740]756    numberThreads_ = rhs.numberThreads_;
[1147]757    if (maximumRows_<0) {
758      specialOptions_ &= ~65536;
759      savedRowScale_ = NULL;
760      savedColumnScale_ = NULL;
761      integerType_ = CoinCopyOfArray(rhs.integerType_,numberColumns_);
762      if (rhs.rowActivity_) {
763        rowActivity_=new double[numberRows_];
764        columnActivity_=new double[numberColumns_];
765        dual_=new double[numberRows_];
766        reducedCost_=new double[numberColumns_];
767        ClpDisjointCopyN ( rhs.rowActivity_, numberRows_ ,
768                           rowActivity_);
769        ClpDisjointCopyN ( rhs.columnActivity_, numberColumns_ ,
770                           columnActivity_);
771        ClpDisjointCopyN ( rhs.dual_, numberRows_ , 
772                           dual_);
773        ClpDisjointCopyN ( rhs.reducedCost_, numberColumns_ ,
774                           reducedCost_);
775      } else {
776        rowActivity_=NULL;
777        columnActivity_=NULL;
778        dual_=NULL;
779        reducedCost_=NULL;
780      }
781      rowLower_ = ClpCopyOfArray ( rhs.rowLower_, numberRows_ );
782      rowUpper_ = ClpCopyOfArray ( rhs.rowUpper_, numberRows_ );
783      columnLower_ = ClpCopyOfArray ( rhs.columnLower_, numberColumns_ );
784      int scaleLength = ((specialOptions_&131072)==0) ? 1 : 2;
785      columnUpper_ = ClpCopyOfArray ( rhs.columnUpper_, numberColumns_ );
786      rowScale_ = ClpCopyOfArray(rhs.rowScale_,numberRows_*scaleLength);
787      columnScale_ = ClpCopyOfArray(rhs.columnScale_,numberColumns_*scaleLength);
788      if (rhs.objective_)
789        objective_  = rhs.objective_->clone();
790      else
791        objective_ = NULL;
792      rowObjective_ = ClpCopyOfArray ( rhs.rowObjective_, numberRows_ );
793      status_ = ClpCopyOfArray( rhs.status_,numberColumns_+numberRows_);
794      ray_ = NULL;
795      if (problemStatus_==1&&!secondaryStatus_)
796        ray_ = ClpCopyOfArray (rhs.ray_,numberRows_);
797      else if (problemStatus_==2)
798        ray_ = ClpCopyOfArray (rhs.ray_,numberColumns_);
799      if (rhs.rowCopy_) {
800        rowCopy_ = rhs.rowCopy_->clone();
801      } else {
802        rowCopy_=NULL;
803      }
[1150]804      if (rhs.scaledMatrix_) {
805        scaledMatrix_ = new ClpPackedMatrix(*rhs.scaledMatrix_);
806      } else {
807        scaledMatrix_=NULL;
808      }
[1147]809      matrix_=NULL;
810      if (rhs.matrix_) {
811        matrix_ = rhs.matrix_->clone();
812      }
[2]813    } else {
[1147]814      // This already has arrays - just copy
[1197]815      savedRowScale_ = NULL;
816      savedColumnScale_ = NULL;
[1147]817      startPermanentArrays();
818      if (rhs.integerType_) {
819        assert (integerType_);
820        ClpDisjointCopyN(rhs.integerType_,numberColumns_,integerType_);
821      } else {
822        integerType_ = NULL;
823      }
824      if (rhs.rowActivity_) {
825        ClpDisjointCopyN ( rhs.rowActivity_, numberRows_ ,
826                           rowActivity_);
827        ClpDisjointCopyN ( rhs.columnActivity_, numberColumns_ ,
828                           columnActivity_);
829        ClpDisjointCopyN ( rhs.dual_, numberRows_ , 
830                           dual_);
831        ClpDisjointCopyN ( rhs.reducedCost_, numberColumns_ ,
832                           reducedCost_);
833      } else {
834        rowActivity_=NULL;
835        columnActivity_=NULL;
836        dual_=NULL;
837        reducedCost_=NULL;
838      }
839      ClpDisjointCopyN ( rhs.rowLower_, numberRows_,rowLower_ );
840      ClpDisjointCopyN ( rhs.rowUpper_, numberRows_,rowUpper_ );
841      ClpDisjointCopyN ( rhs.columnLower_, numberColumns_,columnLower_ );
842      assert ((specialOptions_&131072)==0);
843      ClpDisjointCopyN ( rhs.columnUpper_, numberColumns_,columnUpper_ );
844      if (rhs.objective_) {
845        abort(); //check if same
846        objective_  = rhs.objective_->clone();
847      } else {
848        objective_ = NULL;
849      }
850      assert (!rhs.rowObjective_);
851      ClpDisjointCopyN( rhs.status_,numberColumns_+numberRows_,status_);
852      ray_ = NULL;
853      if (problemStatus_==1&&!secondaryStatus_)
854        ray_ = ClpCopyOfArray (rhs.ray_,numberRows_);
855      else if (problemStatus_==2)
856        ray_ = ClpCopyOfArray (rhs.ray_,numberColumns_);
857      assert (!ray_);
858      delete rowCopy_;
859      if (rhs.rowCopy_) {
860        rowCopy_ = rhs.rowCopy_->clone();
861      } else {
862        rowCopy_=NULL;
863      }
[1150]864      delete scaledMatrix_;
865      if (rhs.scaledMatrix_) {
866        scaledMatrix_ = new ClpPackedMatrix(*rhs.scaledMatrix_);
867      } else {
868        scaledMatrix_=NULL;
869      }
[1147]870      delete matrix_;
871      matrix_=NULL;
872      if (rhs.matrix_) {
873        matrix_ = rhs.matrix_->clone();
874      }
875      if (rhs.savedRowScale_) {
876        assert (savedRowScale_);
877        assert (!rowScale_);
[1197]878        ClpDisjointCopyN(rhs.savedRowScale_,4*maximumInternalRows_,savedRowScale_);
879        ClpDisjointCopyN(rhs.savedColumnScale_,4*maximumInternalColumns_,savedColumnScale_);
[1147]880      } else {
881        assert (!savedRowScale_);
882        if (rowScale_) {
883          ClpDisjointCopyN(rhs.rowScale_,numberRows_,rowScale_);
884          ClpDisjointCopyN(rhs.columnScale_,numberColumns_,columnScale_);
885        } else {
886          rowScale_ =NULL;
887          columnScale_=NULL;
888        }
889      }
890      abort(); // look at resizeDouble and resize
[2]891    }
892  } else {
[1147]893    savedRowScale_ = rhs.savedRowScale_;
[1197]894    assert (!savedRowScale_);
[1147]895    savedColumnScale_ = rhs.savedColumnScale_;
[2]896    rowActivity_ = rhs.rowActivity_;
897    columnActivity_ = rhs.columnActivity_;
898    dual_ = rhs.dual_;
899    reducedCost_ = rhs.reducedCost_;
900    rowLower_ = rhs.rowLower_;
901    rowUpper_ = rhs.rowUpper_;
902    objective_ = rhs.objective_;
903    rowObjective_ = rhs.rowObjective_;
904    columnLower_ = rhs.columnLower_;
905    columnUpper_ = rhs.columnUpper_;
906    matrix_ = rhs.matrix_;
[164]907    rowCopy_ = NULL;
[1150]908    scaledMatrix_ = NULL;
[2]909    ray_ = rhs.ray_;
[393]910    //rowScale_ = rhs.rowScale_;
911    //columnScale_ = rhs.columnScale_;
[2]912    lengthNames_ = 0;
[740]913    numberThreads_ = rhs.numberThreads_;
[653]914#ifndef CLP_NO_STD
[2]915    rowNames_ = std::vector<std::string> ();
916    columnNames_ = std::vector<std::string> ();
[653]917#endif
[50]918    integerType_ = NULL;
919    status_ = rhs.status_;
[2]920  }
[1197]921  inverseRowScale_ = NULL;
922  inverseColumnScale_ = NULL;
[2]923}
[1147]924// Copy contents - resizing if necessary - otherwise re-use memory
925void 
926ClpModel::copy(const ClpMatrixBase * from, ClpMatrixBase * & to)
927{
928  assert (from);
929  const ClpPackedMatrix * matrixFrom = (dynamic_cast<const ClpPackedMatrix*>(from));
930  ClpPackedMatrix * matrixTo = (dynamic_cast< ClpPackedMatrix*>(to));
931  if (matrixFrom&&matrixTo) {
932    matrixTo->copy(matrixFrom);
933  } else {
934    delete to;
935    to =  from->clone();
936  }
937#if 0
[1197]938  delete modelPtr_->matrix_;
939  if (continuousModel_->matrix_) {
940    modelPtr_->matrix_ = continuousModel_->matrix_->clone();
941  } else {
942    modelPtr_->matrix_=NULL;
943  }
[1147]944#endif
945}
[2]946/* Borrow model.  This is so we dont have to copy large amounts
947   of data around.  It assumes a derived class wants to overwrite
948   an empty model with a real one - while it does an algorithm */
949void 
950ClpModel::borrowModel(ClpModel & rhs)
951{
952  if (defaultHandler_) {
953    delete handler_;
954    handler_ = NULL;
955  }
[1147]956  gutsOfDelete(1);
[2]957  optimizationDirection_ = rhs.optimizationDirection_;
958  numberRows_ = rhs.numberRows_;
959  numberColumns_ = rhs.numberColumns_;
[50]960  delete [] rhs.ray_;
961  rhs.ray_=NULL;
[1150]962  // make sure scaled matrix not copied
963  ClpPackedMatrix * save = rhs.scaledMatrix_;
964  rhs.scaledMatrix_ = NULL;
965  delete scaledMatrix_;
966  scaledMatrix_=NULL;
[1147]967  gutsOfCopy(rhs,0);
[1150]968  rhs.scaledMatrix_ = save;
[1147]969  specialOptions_ = rhs.specialOptions_ & ~65536;
970  savedRowScale_=NULL;
971  savedColumnScale_=NULL;
[1197]972  inverseRowScale_ = NULL;
973  inverseColumnScale_ = NULL;
[2]974}
975// Return model - nulls all arrays so can be deleted safely
976void 
977ClpModel::returnModel(ClpModel & otherModel)
978{
979  otherModel.objectiveValue_=objectiveValue_;
980  otherModel.numberIterations_ = numberIterations_;
981  otherModel.problemStatus_ = problemStatus_;
[225]982  otherModel.secondaryStatus_ = secondaryStatus_;
[2]983  rowActivity_ = NULL;
984  columnActivity_ = NULL;
985  dual_ = NULL;
986  reducedCost_ = NULL;
987  rowLower_ = NULL;
988  rowUpper_ = NULL;
989  objective_ = NULL;
990  rowObjective_ = NULL;
991  columnLower_ = NULL;
992  columnUpper_ = NULL;
993  matrix_ = NULL;
994  rowCopy_ = NULL;
[1150]995  delete scaledMatrix_;
996  scaledMatrix_ = NULL;
[50]997  delete [] otherModel.ray_;
998  otherModel.ray_ = ray_;
[2]999  ray_ = NULL;
[1152]1000  if (rowScale_&&otherModel.rowScale_!=rowScale_) {
1001    delete [] rowScale_;
1002    delete [] columnScale_;
1003  }
[1147]1004  rowScale_ = NULL;
1005  columnScale_ = NULL;
[393]1006  //rowScale_=NULL;
1007  //columnScale_=NULL;
[50]1008  // do status
1009  if (otherModel.status_!=status_) {
1010    delete [] otherModel.status_;
1011    otherModel.status_ = status_;
1012  }
1013  status_ = NULL;
[72]1014  if (defaultHandler_) {
1015    delete handler_;
1016    handler_ = NULL;
1017  }
[1197]1018  inverseRowScale_ = NULL;
1019  inverseColumnScale_ = NULL;
[2]1020}
1021//#############################################################################
1022// Parameter related methods
1023//#############################################################################
1024
1025bool
[50]1026ClpModel::setIntParam(ClpIntParam key, int value)
[2]1027{
1028  switch (key) {
[50]1029  case ClpMaxNumIteration:
[2]1030    if (value < 0)
1031      return false;
1032    break;
[50]1033  case ClpMaxNumIterationHotStart:
[2]1034    if (value < 0)
1035      return false;
1036    break;
[1015]1037  case ClpNameDiscipline:
1038    if (value < 0)
1039      return false;
1040    break;
[1034]1041  default:
[2]1042    return false;
1043  }
1044  intParam_[key] = value;
1045  return true;
1046}
1047
1048//-----------------------------------------------------------------------------
1049
1050bool
[50]1051ClpModel::setDblParam(ClpDblParam key, double value)
[2]1052{
1053
1054  switch (key) {
[50]1055  case ClpDualObjectiveLimit:
[2]1056    break;
1057
[50]1058  case ClpPrimalObjectiveLimit:
[2]1059    break;
1060
[50]1061  case ClpDualTolerance: 
[2]1062    if (value<=0.0||value>1.0e10)
1063      return false;
1064    break;
1065   
[50]1066  case ClpPrimalTolerance: 
[2]1067    if (value<=0.0||value>1.0e10)
1068      return false;
1069    break;
1070   
[50]1071  case ClpObjOffset: 
[2]1072    break;
1073
[142]1074  case ClpMaxSeconds: 
1075    if(value>=0)
[225]1076      value += CoinCpuTime();
[142]1077    else
1078      value = -1.0;
1079    break;
1080
[708]1081  case ClpPresolveTolerance: 
1082    if (value<=0.0||value>1.0e10)
1083      return false;
1084    break;
1085   
[1034]1086  default:
[2]1087    return false;
1088  }
1089  dblParam_[key] = value;
1090  return true;
1091}
1092
1093//-----------------------------------------------------------------------------
[653]1094#ifndef CLP_NO_STD
[2]1095
1096bool
[50]1097ClpModel::setStrParam(ClpStrParam key, const std::string & value)
[2]1098{
1099
1100  switch (key) {
[50]1101  case ClpProbName:
[2]1102    break;
1103
[1034]1104  default:
[2]1105    return false;
1106  }
1107  strParam_[key] = value;
1108  return true;
1109}
[653]1110#endif
[2]1111// Useful routines
1112// Returns resized array and deletes incoming
[77]1113double * resizeDouble(double * array , int size, int newSize, double fill,
1114                      bool createArray)
[2]1115{
[1147]1116  if ((array||createArray)&&size<newSize) {
[2]1117    int i;
1118    double * newArray = new double[newSize];
[77]1119    if (array)
[706]1120      CoinMemcpyN(array,CoinMin(newSize,size),newArray);
[2]1121    delete [] array;
1122    array = newArray;
1123    for (i=size;i<newSize;i++) 
1124      array[i]=fill;
1125  } 
1126  return array;
1127}
1128// Returns resized array and updates size
1129double * deleteDouble(double * array , int size, 
1130                      int number, const int * which,int & newSize)
1131{
1132  if (array) {
1133    int i ;
1134    char * deleted = new char[size];
1135    int numberDeleted=0;
[706]1136    CoinZeroN(deleted,size);
[2]1137    for (i=0;i<number;i++) {
1138      int j = which[i];
1139      if (j>=0&&j<size&&!deleted[j]) {
1140        numberDeleted++;
1141        deleted[j]=1;
1142      }
1143    }
1144    newSize = size-numberDeleted;
1145    double * newArray = new double[newSize];
1146    int put=0;
1147    for (i=0;i<size;i++) {
1148      if (!deleted[i]) {
1149        newArray[put++]=array[i];
1150      }
1151    }
1152    delete [] array;
1153    array = newArray;
1154    delete [] deleted;
1155  }
1156  return array;
1157}
[50]1158char * deleteChar(char * array , int size, 
1159                  int number, const int * which,int & newSize,
1160                  bool ifDelete)
1161{
1162  if (array) {
1163    int i ;
1164    char * deleted = new char[size];
1165    int numberDeleted=0;
[706]1166    CoinZeroN(deleted,size);
[50]1167    for (i=0;i<number;i++) {
1168      int j = which[i];
1169      if (j>=0&&j<size&&!deleted[j]) {
1170        numberDeleted++;
1171        deleted[j]=1;
1172      }
1173    }
1174    newSize = size-numberDeleted;
1175    char * newArray = new char[newSize];
1176    int put=0;
1177    for (i=0;i<size;i++) {
1178      if (!deleted[i]) {
1179        newArray[put++]=array[i];
1180      }
1181    }
1182    if (ifDelete)
1183      delete [] array;
1184    array = newArray;
1185    delete [] deleted;
1186  }
1187  return array;
1188}
[77]1189// Create empty ClpPackedMatrix
1190void 
1191ClpModel::createEmptyMatrix()
1192{
1193  delete matrix_;
[472]1194  whatsChanged_ = 0;
[77]1195  CoinPackedMatrix matrix2;
1196  matrix_=new ClpPackedMatrix(matrix2);
1197}
[1034]1198/* Really clean up matrix.
1199   a) eliminate all duplicate AND small elements in matrix
1200   b) remove all gaps and set extraGap_ and extraMajor_ to 0.0
1201   c) reallocate arrays and make max lengths equal to lengths
1202   d) orders elements
1203   returns number of elements eliminated or -1 if not ClpMatrix
1204*/
1205int 
1206ClpModel::cleanMatrix(double threshold)
1207{
1208  ClpPackedMatrix * matrix = (dynamic_cast< ClpPackedMatrix*>(matrix_));
1209  if (matrix) {
1210    return matrix->getPackedMatrix()->cleanMatrix(threshold);
1211  } else {
1212    return -1;
1213  }
1214}
[2]1215// Resizes
1216void 
1217ClpModel::resize (int newNumberRows, int newNumberColumns)
1218{
[472]1219  if (newNumberRows==numberRows_&&
1220      newNumberColumns==numberColumns_)
1221    return; // nothing to do
1222  whatsChanged_ = 0;
[1197]1223  int numberRows2=newNumberRows;
1224  int numberColumns2=newNumberColumns;
1225  if (numberRows2<maximumRows_)
1226    numberRows2=maximumRows_;
1227  if (numberColumns2<maximumColumns_)
1228    numberColumns2=maximumColumns_;
1229  if (numberRows2>maximumRows_) {
1230    rowActivity_ = resizeDouble(rowActivity_,numberRows_,
1231                                newNumberRows,0.0,true);
1232    dual_ = resizeDouble(dual_,numberRows_,
1233                         newNumberRows,0.0,true);
1234    rowObjective_ = resizeDouble(rowObjective_,numberRows_,
1235                                 newNumberRows,0.0,false);
1236    rowLower_ = resizeDouble(rowLower_,numberRows_,
1237                             newNumberRows,-COIN_DBL_MAX,true);
1238    rowUpper_ = resizeDouble(rowUpper_,numberRows_,
1239                             newNumberRows,COIN_DBL_MAX,true);
1240  }
1241  if (numberColumns2>maximumColumns_) {
1242    columnActivity_ = resizeDouble(columnActivity_,numberColumns_,
1243                                   newNumberColumns,0.0,true);
1244    reducedCost_ = resizeDouble(reducedCost_,numberColumns_,
1245                                newNumberColumns,0.0,true);
1246  }
1247  if (savedRowScale_&&numberRows2>maximumInternalRows_) {
1248    double * temp;
1249    temp = new double [4*newNumberRows];
1250    CoinFillN(temp,4*newNumberRows,1.0);
1251    CoinMemcpyN(savedRowScale_,numberRows_,temp);
1252    CoinMemcpyN(savedRowScale_+maximumInternalRows_,numberRows_,temp+newNumberRows);
1253    CoinMemcpyN(savedRowScale_+2*maximumInternalRows_,numberRows_,temp+2*newNumberRows);
1254    CoinMemcpyN(savedRowScale_+3*maximumInternalRows_,numberRows_,temp+3*newNumberRows);
1255    delete [] savedRowScale_;
1256    savedRowScale_ = temp;
1257  }
1258  if (savedColumnScale_&&numberColumns2>maximumInternalColumns_) {
1259    double * temp;
1260    temp = new double [4*newNumberColumns];
1261    CoinFillN(temp,4*newNumberColumns,1.0);
1262    CoinMemcpyN(savedColumnScale_,numberColumns_,temp);
1263    CoinMemcpyN(savedColumnScale_+maximumInternalColumns_,numberColumns_,temp+newNumberColumns);
1264    CoinMemcpyN(savedColumnScale_+2*maximumInternalColumns_,numberColumns_,temp+2*newNumberColumns);
1265    CoinMemcpyN(savedColumnScale_+3*maximumInternalColumns_,numberColumns_,temp+3*newNumberColumns);
1266    delete [] savedColumnScale_;
1267    savedColumnScale_ = temp;
1268  }
1269  if (objective_&&numberColumns2>maximumColumns_)
[123]1270    objective_->resize(newNumberColumns);
[1197]1271  else if (!objective_)
[123]1272    objective_ = new ClpLinearObjective(NULL,newNumberColumns);
[1197]1273  if (numberColumns2>maximumColumns_) {
1274    columnLower_ = resizeDouble(columnLower_,numberColumns_,
1275                                newNumberColumns,0.0,true);
1276    columnUpper_ = resizeDouble(columnUpper_,numberColumns_,
1277                                newNumberColumns,COIN_DBL_MAX,true);
1278  }
[2]1279  if (newNumberRows<numberRows_) {
1280    int * which = new int[numberRows_-newNumberRows];
1281    int i;
1282    for (i=newNumberRows;i<numberRows_;i++) 
1283      which[i-newNumberRows]=i;
1284    matrix_->deleteRows(numberRows_-newNumberRows,which);
1285    delete [] which;
1286  }
1287  if (numberRows_!=newNumberRows||numberColumns_!=newNumberColumns) {
1288    // set state back to unknown
1289    problemStatus_ = -1;
[225]1290    secondaryStatus_ = 0;
[2]1291    delete [] ray_;
1292    ray_ = NULL;
1293  }
[1147]1294  setRowScale(NULL);
1295  setColumnScale(NULL);
[50]1296  if (status_) {
[465]1297    if (newNumberColumns+newNumberRows) {
[1197]1298      if (newNumberColumns+newNumberRows>maximumRows_+maximumColumns_) {
1299        unsigned char * tempC = new unsigned char [newNumberColumns+newNumberRows];
1300        unsigned char * tempR = tempC + newNumberColumns;
1301        memset(tempC,3,newNumberColumns*sizeof(unsigned char));
1302        memset(tempR,1,newNumberRows*sizeof(unsigned char));
1303        CoinMemcpyN(status_,CoinMin(newNumberColumns,numberColumns_),tempC);
1304        CoinMemcpyN(status_+numberColumns_,CoinMin(newNumberRows,numberRows_),tempR);
1305        delete [] status_;
1306        status_ = tempC;
1307      } else if (newNumberColumns<numberColumns_) {
1308        memmove(status_+newNumberColumns,status_+numberColumns_,
1309                newNumberRows);
1310      } else if (newNumberColumns>numberColumns_) {
1311        memset(status_+numberColumns_,3,newNumberColumns-numberColumns_);
1312        memmove(status_+newNumberColumns,status_+numberColumns_,
1313                newNumberRows);
1314      }
[465]1315    } else {
1316      // empty model - some systems don't like new [0]
1317      delete [] status_;
1318      status_ = NULL;
1319    }
[50]1320  }
[733]1321#ifndef CLP_NO_STD
1322  if (lengthNames_) {
1323    // redo row and column names
1324    if (numberRows_ < newNumberRows) {
1325      rowNames_.resize(newNumberRows);
1326      lengthNames_ = CoinMax(lengthNames_,8);
1327      char name[9];
1328      for (int iRow = numberRows_;iRow<newNumberRows;iRow++) {
1329        sprintf(name,"R%7.7d",iRow);
1330        rowNames_[iRow]=name;
1331      }
1332    }
1333    if (numberColumns_ < newNumberColumns) {
1334      columnNames_.resize(newNumberColumns);
1335      lengthNames_ = CoinMax(lengthNames_,8);
1336      char name[9];
1337      for (int iColumn = numberColumns_;iColumn<newNumberColumns;iColumn++) {
1338        sprintf(name,"C%7.7d",iColumn);
1339        columnNames_[iColumn]=name;
1340      }
1341    }
1342  }
1343#endif
[2]1344  numberRows_ = newNumberRows;
[465]1345  if (newNumberColumns<numberColumns_&&matrix_->getNumCols()) {
[2]1346    int * which = new int[numberColumns_-newNumberColumns];
1347    int i;
1348    for (i=newNumberColumns;i<numberColumns_;i++) 
1349      which[i-newNumberColumns]=i;
1350    matrix_->deleteCols(numberColumns_-newNumberColumns,which);
1351    delete [] which;
1352  }
[1197]1353  if (integerType_&&numberColumns2>maximumColumns_) {
[50]1354    char * temp = new char [newNumberColumns];
[706]1355    CoinZeroN(temp,newNumberColumns);
1356    CoinMemcpyN(integerType_,
1357           CoinMin(newNumberColumns,numberColumns_),temp);
[50]1358    delete [] integerType_;
1359    integerType_ = temp;
1360  }
[2]1361  numberColumns_ = newNumberColumns;
[1197]1362  if ((specialOptions_&65536)!=0) {
1363    // leave until next create rim to up numbers
1364  }
1365  if (maximumRows_>=0) {
1366    if (numberRows_>maximumRows_)
1367      printf("resize %d rows, %d old maximum rows\n",
1368             numberRows_,maximumRows_);
1369    maximumRows_ = CoinMax(maximumRows_,numberRows_);
1370    maximumColumns_ = CoinMax(maximumColumns_,numberColumns_);
1371  }
[2]1372}
1373// Deletes rows
1374void 
1375ClpModel::deleteRows(int number, const int * which)
1376{
[472]1377  if (!number)
1378    return; // nothing to do
1379  whatsChanged_ &= ~(1+2+4+8+16+32); // all except columns changed
[2]1380  int newSize=0;
[1197]1381  if (maximumRows_<0) {
1382    rowActivity_ = deleteDouble(rowActivity_,numberRows_,
1383                                number, which, newSize);
1384    dual_ = deleteDouble(dual_,numberRows_,
1385                         number, which, newSize);
1386    rowObjective_ = deleteDouble(rowObjective_,numberRows_,
1387                                 number, which, newSize);
1388    rowLower_ = deleteDouble(rowLower_,numberRows_,
1389                             number, which, newSize);
1390    rowUpper_ = deleteDouble(rowUpper_,numberRows_,
1391                             number, which, newSize);
1392    if (matrix_->getNumRows())
1393      matrix_->deleteRows(number,which);
1394    //matrix_->removeGaps();
1395    // status
1396    if (status_) {
1397      if (numberColumns_+newSize) {
1398        unsigned char * tempR  = (unsigned char *) deleteChar((char *)status_+numberColumns_,
1399                                                              numberRows_,
1400                                                              number, which, newSize,false);
1401        unsigned char * tempC = new unsigned char [numberColumns_+newSize];
1402        CoinMemcpyN(status_,numberColumns_,tempC);
1403        CoinMemcpyN(tempR,newSize,tempC+numberColumns_);
1404        delete [] tempR;
1405        delete [] status_;
1406        status_ = tempC;
1407      } else {
1408        // empty model - some systems don't like new [0]
1409        delete [] status_;
1410        status_ = NULL;
1411      }
[465]1412    }
[1197]1413  } else {
1414    char * deleted = new char [numberRows_];
1415    int i;
1416    int numberDeleted=0;
1417    CoinZeroN(deleted,numberRows_);
1418    for (i=0;i<number;i++) {
1419      int j = which[i];
1420      if (j>=0&&j<numberRows_&&!deleted[j]) {
1421        numberDeleted++;
1422        deleted[j]=1;
1423      }
1424    }
1425    assert (!rowObjective_);
1426    unsigned char * status2 = status_+numberColumns_;
1427    for (i=0;i<numberRows_;i++) {
1428      if (!deleted[i]) {
1429        rowActivity_[newSize]=rowActivity_[i]; 
1430        dual_[newSize] = dual_[i]; 
1431        rowLower_[newSize] = rowLower_[i]; 
1432        rowUpper_[newSize] = rowUpper_[i]; 
1433        status2[newSize] = status2[i];
1434        newSize++;
1435      }
1436    }
1437    if (matrix_->getNumRows())
1438      matrix_->deleteRows(number,which);
1439    //matrix_->removeGaps();
1440    delete [] deleted;
[50]1441  }
[653]1442#ifndef CLP_NO_STD
[648]1443  // Now works if which out of order
[304]1444  if (lengthNames_) {
[648]1445    char * mark = new char [numberRows_];
[706]1446    CoinZeroN(mark,numberRows_);
[648]1447    int i;
1448    for (i=0;i<number;i++)
1449      mark[which[i]]=1;
1450    int k=0;
1451    for ( i = 0; i < numberRows_; ++i) {
1452      if (!mark[i]) 
[301]1453        rowNames_[k++] = rowNames_[i];
[304]1454    }
1455    rowNames_.erase(rowNames_.begin()+k, rowNames_.end());
[648]1456    delete [] mark;
[301]1457  }
1458#endif
[77]1459  numberRows_=newSize;
1460  // set state back to unknown
1461  problemStatus_ = -1;
[225]1462  secondaryStatus_ = 0;
[77]1463  delete [] ray_;
1464  ray_ = NULL;
[1147]1465  if (savedRowScale_!=rowScale_) {
1466    delete [] rowScale_;
1467    delete [] columnScale_;
1468  }
[372]1469  rowScale_ = NULL;
1470  columnScale_ = NULL;
[2]1471}
1472// Deletes columns
1473void 
1474ClpModel::deleteColumns(int number, const int * which)
1475{
[472]1476  if (!number)
1477    return; // nothing to do
[1197]1478  assert (maximumColumns_<0);
[472]1479  whatsChanged_ &= ~(1+2+4+8+64+128+256); // all except rows changed
[2]1480  int newSize=0;
1481  columnActivity_ = deleteDouble(columnActivity_,numberColumns_,
1482                              number, which, newSize);
1483  reducedCost_ = deleteDouble(reducedCost_,numberColumns_,
1484                              number, which, newSize);
[119]1485  objective_->deleteSome(number, which);
[2]1486  columnLower_ = deleteDouble(columnLower_,numberColumns_,
1487                              number, which, newSize);
1488  columnUpper_ = deleteDouble(columnUpper_,numberColumns_,
1489                              number, which, newSize);
[381]1490  // possible matrix is not full
1491  if (matrix_->getNumCols()<numberColumns_) {
1492    int * which2 = new int [number];
1493    int n=0;
1494    int nMatrix = matrix_->getNumCols();
1495    for (int i=0;i<number;i++) {
1496      if (which[i]<nMatrix)
1497        which2[n++]=which[i];
1498    }
1499    matrix_->deleteCols(n,which2);
1500    delete [] which2;
1501  } else {
1502    matrix_->deleteCols(number,which);
1503  }
[225]1504  //matrix_->removeGaps();
[50]1505  // status
1506  if (status_) {
[465]1507    if (numberRows_+newSize) {
1508      unsigned char * tempC  = (unsigned char *) deleteChar((char *)status_,
1509                                                            numberColumns_,
1510                                                            number, which, newSize,false);
1511      unsigned char * temp = new unsigned char [numberRows_+newSize];
[1197]1512      CoinMemcpyN(tempC,newSize,temp);
1513      CoinMemcpyN(status_+numberColumns_,       numberRows_,temp+newSize);
[465]1514      delete [] tempC;
1515      delete [] status_;
1516      status_ = temp;
1517    } else {
1518      // empty model - some systems don't like new [0]
1519      delete [] status_;
1520      status_ = NULL;
1521    }
[50]1522  }
[225]1523  integerType_ = deleteChar(integerType_,numberColumns_,
1524                            number, which, newSize,true);
[653]1525#ifndef CLP_NO_STD
[648]1526  // Now works if which out of order
[304]1527  if (lengthNames_) {
[648]1528    char * mark = new char [numberColumns_];
[706]1529    CoinZeroN(mark,numberColumns_);
[648]1530    int i;
1531    for (i=0;i<number;i++)
1532      mark[which[i]]=1;
1533    int k=0;
1534    for ( i = 0; i < numberColumns_; ++i) {
1535      if (!mark[i]) 
[301]1536        columnNames_[k++] = columnNames_[i];
[304]1537    }
1538    columnNames_.erase(columnNames_.begin()+k, columnNames_.end());
[648]1539    delete [] mark;
[301]1540  }
1541#endif
[77]1542  numberColumns_=newSize;
1543  // set state back to unknown
1544  problemStatus_ = -1;
[225]1545  secondaryStatus_ = 0;
[77]1546  delete [] ray_;
1547  ray_ = NULL;
[1147]1548  setRowScale(NULL);
1549  setColumnScale(NULL);
[2]1550}
[527]1551// Add one row
1552void 
1553ClpModel::addRow(int numberInRow, const int * columns,
1554                 const double * elements, double rowLower, double rowUpper)
1555{
[653]1556  CoinBigIndex starts[2];
1557  starts[0]=0;
1558  starts[1]=numberInRow;
1559  addRows(1, &rowLower, &rowUpper,starts,columns,elements);
[527]1560}
[169]1561// Add rows
1562void 
1563ClpModel::addRows(int number, const double * rowLower, 
1564                  const double * rowUpper,
1565                  const int * rowStarts, const int * columns,
1566                  const double * elements)
1567{
1568  if (number) {
[653]1569    whatsChanged_ &= ~(1+2+8+16+32); // all except columns changed
1570    int numberRowsNow = numberRows_;
1571    resize(numberRowsNow+number,numberColumns_);
1572    double * lower = rowLower_+numberRowsNow;
1573    double * upper = rowUpper_+numberRowsNow;
[169]1574    int iRow;
[653]1575    if (rowLower) {
1576      for (iRow = 0; iRow < number; iRow++) {
1577        double value = rowLower[iRow];
1578        if (value<-1.0e20)
1579          value = -COIN_DBL_MAX;
1580        lower[iRow]= value;
1581      }
1582    } else {
1583      for (iRow = 0; iRow < number; iRow++) {
1584        lower[iRow]= -COIN_DBL_MAX;
1585      }
[169]1586    }
[653]1587    if (rowUpper) {
1588      for (iRow = 0; iRow < number; iRow++) {
1589        double value = rowUpper[iRow];
1590        if (value>1.0e20)
1591          value = COIN_DBL_MAX;
1592        upper[iRow]= value;
1593      }
1594    } else {
1595      for (iRow = 0; iRow < number; iRow++) {
1596        upper[iRow]= COIN_DBL_MAX;
1597      }
1598    }
1599    // Deal with matrix
1600   
1601    delete rowCopy_;
1602    rowCopy_=NULL;
[1150]1603    delete scaledMatrix_;
1604    scaledMatrix_=NULL;
[653]1605    if (!matrix_)
1606      createEmptyMatrix();
[1147]1607    setRowScale(NULL);
1608    setColumnScale(NULL);
[653]1609#ifndef CLP_NO_STD
1610    if (lengthNames_) {
1611      rowNames_.resize(numberRows_);
1612    }
1613#endif
[1153]1614    if (rowStarts) 
1615      matrix_->appendMatrix(number,0,rowStarts,columns,elements);
[169]1616  }
1617}
[225]1618// Add rows
[169]1619void 
1620ClpModel::addRows(int number, const double * rowLower, 
1621                  const double * rowUpper,
[225]1622                  const int * rowStarts, 
1623                  const int * rowLengths, const int * columns,
1624                  const double * elements)
1625{
1626  if (number) {
[653]1627    CoinBigIndex numberElements=0;
[225]1628    int iRow;
[653]1629    for (iRow=0;iRow<number;iRow++) 
1630      numberElements += rowLengths[iRow];
1631    int * newStarts = new int[number+1];
1632    int * newIndex = new int[numberElements];
1633    double * newElements = new double[numberElements];
1634    numberElements=0;
1635    newStarts[0]=0;
[225]1636    for (iRow=0;iRow<number;iRow++) {
1637      int iStart = rowStarts[iRow];
[653]1638      int length = rowLengths[iRow];
[706]1639      CoinMemcpyN(columns+iStart,length,newIndex+numberElements);
1640      CoinMemcpyN(elements+iStart,length,newElements+numberElements);
[653]1641      numberElements += length;
1642      newStarts[iRow+1]=numberElements;
[225]1643    }
1644    addRows(number, rowLower, rowUpper,
[653]1645            newStarts,newIndex,newElements);
1646    delete [] newStarts;
1647    delete [] newIndex;
1648    delete [] newElements;
[225]1649  }
1650}
[653]1651#ifndef CLP_NO_VECTOR
[225]1652void 
1653ClpModel::addRows(int number, const double * rowLower, 
1654                  const double * rowUpper,
[169]1655                  const CoinPackedVectorBase * const * rows)
1656{
1657  if (!number)
1658    return;
[472]1659  whatsChanged_ &= ~(1+2+8+16+32); // all except columns changed
[169]1660  int numberRowsNow = numberRows_;
1661  resize(numberRowsNow+number,numberColumns_);
1662  double * lower = rowLower_+numberRowsNow;
1663  double * upper = rowUpper_+numberRowsNow;
1664  int iRow;
1665  if (rowLower) {
1666    for (iRow = 0; iRow < number; iRow++) {
1667      double value = rowLower[iRow];
1668      if (value<-1.0e20)
1669        value = -COIN_DBL_MAX;
1670      lower[iRow]= value;
1671    }
1672  } else {
1673    for (iRow = 0; iRow < number; iRow++) {
1674      lower[iRow]= -COIN_DBL_MAX;
1675    }
1676  }
1677  if (rowUpper) {
1678    for (iRow = 0; iRow < number; iRow++) {
1679      double value = rowUpper[iRow];
1680      if (value>1.0e20)
1681        value = COIN_DBL_MAX;
1682      upper[iRow]= value;
1683    }
1684  } else {
1685    for (iRow = 0; iRow < number; iRow++) {
1686      upper[iRow]= COIN_DBL_MAX;
1687    }
1688  }
1689  // Deal with matrix
1690
1691  delete rowCopy_;
1692  rowCopy_=NULL;
[1150]1693  delete scaledMatrix_;
1694  scaledMatrix_=NULL;
[169]1695  if (!matrix_)
1696    createEmptyMatrix();
[557]1697  if (rows)
1698    matrix_->appendRows(number,rows);
[1147]1699  setRowScale(NULL);
1700  setColumnScale(NULL);
[648]1701  if (lengthNames_) {
1702    rowNames_.resize(numberRows_);
1703  }
[169]1704}
[653]1705#endif
[650]1706#ifndef SLIM_CLP
[538]1707// Add rows from a build object
[577]1708int
1709ClpModel::addRows(const CoinBuild & buildObject,bool tryPlusMinusOne,bool checkDuplicates)
[538]1710{
[560]1711  CoinAssertHint (buildObject.type()==0,"Looks as if both addRows and addCols being used"); // check correct
[538]1712  int number = buildObject.numberRows();
[577]1713  int numberErrors=0;
[538]1714  if (number) {
[558]1715    CoinBigIndex size=0;
[538]1716    int iRow;
1717    double * lower = new double [number];
1718    double * upper = new double [number];
[559]1719    if ((!matrix_||!matrix_->getNumElements())&&tryPlusMinusOne) {
[558]1720      // See if can be +-1
1721      for (iRow=0;iRow<number;iRow++) {
1722        const int * columns;
1723        const double * elements;
1724        int numberElements = buildObject.row(iRow,lower[iRow],
1725                                                upper[iRow],
1726                                                columns,elements);
1727        for (int i=0;i<numberElements;i++) {
1728          // allow for zero elements
1729          if (elements[i]) {
1730            if (fabs(elements[i])==1.0) {
1731              size++;
1732            } else {
1733              // bad
1734              tryPlusMinusOne=false;
1735            }
1736          }
1737        }
1738        if (!tryPlusMinusOne)
1739          break;
1740      }
1741    } else {
1742      // Will add to whatever sort of matrix exists
1743      tryPlusMinusOne=false;
[538]1744    }
[558]1745    if (!tryPlusMinusOne) {
[577]1746      CoinBigIndex numberElements = buildObject.numberElements();
1747      CoinBigIndex * starts = new CoinBigIndex [number+1];
1748      int * column = new int[numberElements];
1749      double * element = new double[numberElements];
1750      starts[0]=0;
1751      numberElements=0;
1752      for (iRow=0;iRow<number;iRow++) {
1753        const int * columns;
1754        const double * elements;
1755        int numberElementsThis = buildObject.row(iRow,lower[iRow],upper[iRow],
1756                                             columns,elements);
1757        CoinMemcpyN(columns,numberElementsThis,column+numberElements);
1758        CoinMemcpyN(elements,numberElementsThis,element+numberElements);
1759        numberElements += numberElementsThis;
1760        starts[iRow+1]=numberElements;
1761      }
1762      addRows(number, lower, upper,NULL);
1763      // make sure matrix has enough columns
1764      matrix_->setDimensions(-1,numberColumns_);
1765      numberErrors=matrix_->appendMatrix(number,0,starts,column,element,
1766                            checkDuplicates ? numberColumns_ : -1);
1767      delete [] starts;
1768      delete [] column;
1769      delete [] element;
1770    } else {
1771      char * which=NULL; // for duplicates
1772      if (checkDuplicates) {
1773        which = new char[numberColumns_];
[706]1774        CoinZeroN(which,numberColumns_);
[577]1775      }
1776      // build +-1 matrix
1777      // arrays already filled in
1778      addRows(number, lower, upper,NULL);
1779      CoinBigIndex * startPositive = new CoinBigIndex [numberColumns_+1];
1780      CoinBigIndex * startNegative = new CoinBigIndex [numberColumns_];
1781      int * indices = new int [size];
[706]1782      CoinZeroN(startPositive,numberColumns_);
1783      CoinZeroN(startNegative,numberColumns_);
[577]1784      int maxColumn=-1;
1785      // need two passes
1786      for (iRow=0;iRow<number;iRow++) {
1787        const int * columns;
1788        const double * elements;
1789        int numberElements = buildObject.row(iRow,lower[iRow],
1790                                                upper[iRow],
1791                                                columns,elements);
1792        for (int i=0;i<numberElements;i++) {
1793          int iColumn=columns[i];
1794          if (checkDuplicates) {
1795            if (iColumn>=numberColumns_) {
1796              if(which[iColumn])
1797                numberErrors++;
1798              else
1799                which[iColumn]=1;
1800            } else {
1801              numberErrors++;
1802              // and may as well switch off
1803              checkDuplicates=false;
1804            }
1805          }
1806          maxColumn = CoinMax(maxColumn,iColumn);
1807          if (elements[i]==1.0) {
1808            startPositive[iColumn]++;
1809          } else if (elements[i]==-1.0) {
1810            startNegative[iColumn]++;
1811          }
1812        }
1813        if (checkDuplicates) {
1814          for (int i=0;i<numberElements;i++) {
1815            int iColumn=columns[i];
1816            which[iColumn]=0;
1817          }
1818        }
1819      }
1820      // check size
1821      int numberColumns = maxColumn+1;
1822      CoinAssertHint (numberColumns<=numberColumns_,
1823                      "rows having column indices >= numberColumns_");
1824      size=0;
1825      int iColumn;
1826      for (iColumn=0;iColumn<numberColumns_;iColumn++) {
1827        CoinBigIndex n=startPositive[iColumn];
1828        startPositive[iColumn]=size;
1829        size+= n;
1830        n=startNegative[iColumn];
1831        startNegative[iColumn]=size;
1832        size+= n;
1833      }
1834      startPositive[numberColumns_]=size;
1835      for (iRow=0;iRow<number;iRow++) {
1836        const int * columns;
1837        const double * elements;
1838        int numberElements = buildObject.row(iRow,lower[iRow],
1839                                                upper[iRow],
1840                                                columns,elements);
1841        for (int i=0;i<numberElements;i++) {
1842          int iColumn=columns[i];
1843          maxColumn = CoinMax(maxColumn,iColumn);
1844          if (elements[i]==1.0) {
1845            CoinBigIndex position = startPositive[iColumn];
1846            indices[position]=iRow;
1847            startPositive[iColumn]++;
1848          } else if (elements[i]==-1.0) {
1849            CoinBigIndex position = startNegative[iColumn];
1850            indices[position]=iRow;
1851            startNegative[iColumn]++;
1852          }
1853        }
1854      }
1855      // and now redo starts
1856      for (iColumn=numberColumns_-1;iColumn>=0;iColumn--) {
1857        startPositive[iColumn+1]=startNegative[iColumn];
1858        startNegative[iColumn]=startPositive[iColumn];
1859      }
1860      startPositive[0]=0;
1861      for (iColumn=0;iColumn<numberColumns_;iColumn++) {
1862        CoinBigIndex start = startPositive[iColumn];
1863        CoinBigIndex end = startNegative[iColumn];
1864        std::sort(indices+start,indices+end);
1865        start = startNegative[iColumn];
1866        end = startPositive[iColumn+1];
1867        std::sort(indices+start,indices+end);
1868      }
1869      // Get good object
1870      delete matrix_;
1871      ClpPlusMinusOneMatrix * matrix = new ClpPlusMinusOneMatrix();
1872      matrix->passInCopy(numberRows_,numberColumns,
1873                         true,indices,startPositive,startNegative);
1874      matrix_=matrix;
1875      delete [] which;
1876    }
1877    delete [] lower;
1878    delete [] upper;
1879    // make sure matrix correct size
1880    matrix_->setDimensions(numberRows_,numberColumns_);
1881  }
1882  return numberErrors;
1883}
[650]1884#endif
[651]1885#ifndef SLIM_NOIO
[577]1886// Add rows from a model object
1887int 
[580]1888ClpModel::addRows( CoinModel & modelObject,bool tryPlusMinusOne,bool checkDuplicates)
[577]1889{
[618]1890  if (modelObject.numberElements()==0)
1891    return 0;
[577]1892  bool goodState=true;
1893  int numberErrors=0;
1894  if (modelObject.columnLowerArray()) {
1895    // some column information exists
1896    int numberColumns2 = modelObject.numberColumns();
1897    const double * columnLower = modelObject.columnLowerArray();
1898    const double * columnUpper = modelObject.columnUpperArray();
1899    const double * objective = modelObject.objectiveArray();
1900    const int * integerType = modelObject.integerTypeArray();
1901    for (int i=0;i<numberColumns2;i++) {
1902      if (columnLower[i]!=0.0) 
1903        goodState=false;
1904      if (columnUpper[i]!=COIN_DBL_MAX) 
1905        goodState=false;
1906      if (objective[i]!=0.0) 
1907        goodState=false;
1908      if (integerType[i]!=0)
1909        goodState=false;
1910    }
1911  }
1912  if (goodState) {
1913    // can do addRows
1914    // Set arrays for normal use
1915    double * rowLower = modelObject.rowLowerArray();
1916    double * rowUpper = modelObject.rowUpperArray();
1917    double * columnLower = modelObject.columnLowerArray();
1918    double * columnUpper = modelObject.columnUpperArray();
1919    double * objective = modelObject.objectiveArray();
1920    int * integerType = modelObject.integerTypeArray();
1921    double * associated = modelObject.associatedArray();
1922    // If strings then do copies
1923    if (modelObject.stringsExist()) {
1924      numberErrors = modelObject.createArrays(rowLower, rowUpper, columnLower, columnUpper,
1925                                 objective, integerType,associated);
1926    }
1927    int numberRows = numberRows_; // save number of rows
1928    int numberRows2 = modelObject.numberRows();
1929    if (numberRows2&&!numberErrors) {
1930      CoinBigIndex * startPositive = NULL;
1931      CoinBigIndex * startNegative = NULL;
1932      int numberColumns = modelObject.numberColumns();
1933      if ((!matrix_||!matrix_->getNumElements())&&!numberRows&&tryPlusMinusOne) {
1934        startPositive = new CoinBigIndex[numberColumns+1];
1935        startNegative = new CoinBigIndex[numberColumns];
1936        modelObject.countPlusMinusOne(startPositive,startNegative,associated);
1937        if (startPositive[0]<0) {
1938          // no good
1939          tryPlusMinusOne=false;
1940          delete [] startPositive;
1941          delete [] startNegative;
1942        }
1943      } else {
1944        // Will add to whatever sort of matrix exists
1945        tryPlusMinusOne=false;
1946      }
1947      assert (rowLower);
[653]1948      addRows(numberRows2, rowLower, rowUpper,NULL,NULL,NULL);
[650]1949#ifndef SLIM_CLP
[577]1950      if (!tryPlusMinusOne) {
[650]1951#endif
[577]1952        CoinPackedMatrix matrix;
1953        modelObject.createPackedMatrix(matrix,associated);
1954        assert (!matrix.getExtraGap());
1955        if (matrix_->getNumRows()) {
1956          // matrix by rows
1957          matrix.reverseOrdering();
1958          assert (!matrix.getExtraGap());
1959          const int * column = matrix.getIndices();
1960          //const int * rowLength = matrix.getVectorLengths();
1961          const CoinBigIndex * rowStart = matrix.getVectorStarts();
1962          const double * element = matrix.getElements();
1963          // make sure matrix has enough columns
1964          matrix_->setDimensions(-1,numberColumns_);
1965          numberErrors+=matrix_->appendMatrix(numberRows2,0,rowStart,column,element,
1966                                checkDuplicates ? numberColumns_ : -1);
1967        } else {
1968          delete matrix_;
1969          matrix_ = new ClpPackedMatrix(matrix);
1970        }
[650]1971#ifndef SLIM_CLP
[577]1972      } else {
1973        // create +-1 matrix
1974        CoinBigIndex size = startPositive[numberColumns];
1975        int * indices = new int[size];
1976        modelObject.createPlusMinusOne(startPositive,startNegative,indices,
1977                                       associated);
1978        // Get good object
1979        ClpPlusMinusOneMatrix * matrix = new ClpPlusMinusOneMatrix();
1980        matrix->passInCopy(numberRows2,numberColumns,
1981                           true,indices,startPositive,startNegative);
1982        delete matrix_;
1983        matrix_=matrix;
1984      }
1985      // Do names if wanted
1986      if (modelObject.rowNames()->numberItems()) {
1987        const char *const * rowNames=modelObject.rowNames()->names();
1988        copyRowNames(rowNames,numberRows,numberRows_);
1989      }
[650]1990#endif
[577]1991    }
1992    if (rowLower!=modelObject.rowLowerArray()) {
1993      delete [] rowLower;
1994      delete [] rowUpper;
1995      delete [] columnLower;
1996      delete [] columnUpper;
1997      delete [] objective;
1998      delete [] integerType;
1999      delete [] associated;
2000      if (numberErrors)
2001        handler_->message(CLP_BAD_STRING_VALUES,messages_)
2002          <<numberErrors
2003          <<CoinMessageEol;
2004    }
2005    return numberErrors;
2006  } else {
2007    // not suitable for addRows
2008    handler_->message(CLP_COMPLICATED_MODEL,messages_)
2009      <<modelObject.numberRows()
2010      <<modelObject.numberColumns()
2011      <<CoinMessageEol;
2012    return -1;
2013  }
2014}
[651]2015#endif
[527]2016// Add one column
2017void 
2018ClpModel::addColumn(int numberInColumn,
2019                 const int * rows,
2020                 const double * elements,
2021                 double columnLower, 
2022                 double  columnUpper,
2023                 double  objective)
2024{
[653]2025  CoinBigIndex starts[2];
2026  starts[0]=0;
2027  starts[1]=numberInColumn;
2028  addColumns(1, &columnLower, &columnUpper,&objective,starts,rows,elements);
[527]2029}
[169]2030// Add columns
2031void 
2032ClpModel::addColumns(int number, const double * columnLower, 
2033                     const double * columnUpper,
2034                     const double * objIn,
2035                     const int * columnStarts, const int * rows,
2036                     const double * elements)
2037{
2038  // Create a list of CoinPackedVectors
2039  if (number) {
[472]2040    whatsChanged_ &= ~(1+2+4+64+128+256); // all except rows changed
[653]2041    int numberColumnsNow = numberColumns_;
2042    resize(numberRows_,numberColumnsNow+number);
2043    double * lower = columnLower_+numberColumnsNow;
2044    double * upper = columnUpper_+numberColumnsNow;
2045    double * obj = objective()+numberColumnsNow;
[169]2046    int iColumn;
[653]2047    if (columnLower) {
2048      for (iColumn = 0; iColumn < number; iColumn++) {
2049        double value = columnLower[iColumn];
2050        if (value<-1.0e20)
2051          value = -COIN_DBL_MAX;
2052        lower[iColumn]= value;
2053      }
2054    } else {
2055      for (iColumn = 0; iColumn < number; iColumn++) {
2056        lower[iColumn]= 0.0;
2057      }
[169]2058    }
[653]2059    if (columnUpper) {
2060      for (iColumn = 0; iColumn < number; iColumn++) {
2061        double value = columnUpper[iColumn];
2062        if (value>1.0e20)
2063          value = COIN_DBL_MAX;
2064        upper[iColumn]= value;
2065      }
2066    } else {
2067      for (iColumn = 0; iColumn < number; iColumn++) {
2068        upper[iColumn]= COIN_DBL_MAX;
2069      }
2070    }
2071    if (objIn) {
2072      for (iColumn = 0; iColumn < number; iColumn++) {
2073        obj[iColumn] = objIn[iColumn];
2074      }
2075    } else {
2076      for (iColumn = 0; iColumn < number; iColumn++) {
2077        obj[iColumn]= 0.0;
2078      }
2079    }
2080    // Deal with matrix
2081   
2082    delete rowCopy_;
2083    rowCopy_=NULL;
[1150]2084    delete scaledMatrix_;
2085    scaledMatrix_=NULL;
[653]2086    if (!matrix_)
2087      createEmptyMatrix();
[1147]2088    setRowScale(NULL);
2089    setColumnScale(NULL);
[653]2090#ifndef CLP_NO_STD
2091    if (lengthNames_) {
2092      columnNames_.resize(numberColumns_);
2093    }
2094#endif
[1034]2095    //if (elements)
2096    matrix_->appendMatrix(number,1,columnStarts,rows,elements);
[169]2097  }
2098}
[225]2099// Add columns
[169]2100void 
2101ClpModel::addColumns(int number, const double * columnLower, 
2102                     const double * columnUpper,
2103                     const double * objIn,
[225]2104                     const int * columnStarts, 
2105                     const int * columnLengths, const int * rows,
2106                     const double * elements)
2107{
2108  if (number) {
[653]2109    CoinBigIndex numberElements=0;
[225]2110    int iColumn;
[653]2111    for (iColumn=0;iColumn<number;iColumn++) 
2112      numberElements += columnLengths[iColumn];
2113    int * newStarts = new int[number+1];
2114    int * newIndex = new int[numberElements];
2115    double * newElements = new double[numberElements];
2116    numberElements=0;
2117    newStarts[0]=0;
[225]2118    for (iColumn=0;iColumn<number;iColumn++) {
2119      int iStart = columnStarts[iColumn];
[653]2120      int length = columnLengths[iColumn];
[706]2121      CoinMemcpyN(rows+iStart,length,newIndex+numberElements);
2122      CoinMemcpyN(elements+iStart,length,newElements+numberElements);
[653]2123      numberElements += length;
2124      newStarts[iColumn+1]=numberElements;
[225]2125    }
[653]2126    addColumns(number, columnLower, columnUpper,objIn,
2127            newStarts,newIndex,newElements);
2128    delete [] newStarts;
2129    delete [] newIndex;
2130    delete [] newElements;
[225]2131  }
2132}
[653]2133#ifndef CLP_NO_VECTOR
[225]2134void 
2135ClpModel::addColumns(int number, const double * columnLower, 
2136                     const double * columnUpper,
2137                     const double * objIn,
[169]2138                     const CoinPackedVectorBase * const * columns)
2139{
2140  if (!number)
2141    return;
[472]2142  whatsChanged_ &= ~(1+2+4+64+128+256); // all except rows changed
[169]2143  int numberColumnsNow = numberColumns_;
2144  resize(numberRows_,numberColumnsNow+number);
2145  double * lower = columnLower_+numberColumnsNow;
2146  double * upper = columnUpper_+numberColumnsNow;
2147  double * obj = objective()+numberColumnsNow;
2148  int iColumn;
2149  if (columnLower) {
2150    for (iColumn = 0; iColumn < number; iColumn++) {
2151      double value = columnLower[iColumn];
2152      if (value<-1.0e20)
2153        value = -COIN_DBL_MAX;
2154      lower[iColumn]= value;
2155    }
2156  } else {
2157    for (iColumn = 0; iColumn < number; iColumn++) {
2158      lower[iColumn]= 0.0;
2159    }
2160  }
2161  if (columnUpper) {
2162    for (iColumn = 0; iColumn < number; iColumn++) {
2163      double value = columnUpper[iColumn];
2164      if (value>1.0e20)
2165        value = COIN_DBL_MAX;
2166      upper[iColumn]= value;
2167    }
2168  } else {
2169    for (iColumn = 0; iColumn < number; iColumn++) {
2170      upper[iColumn]= COIN_DBL_MAX;
2171    }
2172  }
2173  if (objIn) {
2174    for (iColumn = 0; iColumn < number; iColumn++) {
2175      obj[iColumn] = objIn[iColumn];
2176    }
2177  } else {
2178    for (iColumn = 0; iColumn < number; iColumn++) {
2179      obj[iColumn]= 0.0;
2180    }
2181  }
2182  // Deal with matrix
2183
2184  delete rowCopy_;
2185  rowCopy_=NULL;
[1150]2186  delete scaledMatrix_;
2187  scaledMatrix_=NULL;
[169]2188  if (!matrix_)
2189    createEmptyMatrix();
[557]2190  if (columns)
2191    matrix_->appendCols(number,columns);
[1147]2192  setRowScale(NULL);
2193  setColumnScale(NULL);
[648]2194  if (lengthNames_) {
2195    columnNames_.resize(numberColumns_);
2196  }
[169]2197}
[653]2198#endif
[650]2199#ifndef SLIM_CLP
[545]2200// Add columns from a build object
[577]2201int 
2202ClpModel::addColumns(const CoinBuild & buildObject,bool tryPlusMinusOne,bool checkDuplicates)
[545]2203{
[560]2204  CoinAssertHint (buildObject.type()==1,"Looks as if both addRows and addCols being used"); // check correct
[545]2205  int number = buildObject.numberColumns();
[577]2206  int numberErrors=0;
[545]2207  if (number) {
[558]2208    CoinBigIndex size=0;
2209    int maximumLength=0;
[557]2210    double * lower = new double [number];
2211    double * upper = new double [number];
[545]2212    int iColumn;
2213    double * objective = new double [number];
[559]2214    if ((!matrix_||!matrix_->getNumElements())&&tryPlusMinusOne) {
[557]2215      // See if can be +-1
2216      for (iColumn=0;iColumn<number;iColumn++) {
2217        const int * rows;
2218        const double * elements;
2219        int numberElements = buildObject.column(iColumn,lower[iColumn],
2220                                                upper[iColumn],objective[iColumn],
2221                                                rows,elements);
2222        maximumLength = CoinMax(maximumLength,numberElements);
2223        for (int i=0;i<numberElements;i++) {
2224          // allow for zero elements
2225          if (elements[i]) {
2226            if (fabs(elements[i])==1.0) {
2227              size++;
2228            } else {
2229              // bad
2230              tryPlusMinusOne=false;
2231            }
2232          }
2233        }
2234        if (!tryPlusMinusOne)
2235          break;
2236      }
2237    } else {
2238      // Will add to whatever sort of matrix exists
2239      tryPlusMinusOne=false;
[545]2240    }
[557]2241    if (!tryPlusMinusOne) {
[577]2242      CoinBigIndex numberElements = buildObject.numberElements();
2243      CoinBigIndex * starts = new CoinBigIndex [number+1];
2244      int * row = new int[numberElements];
2245      double * element = new double[numberElements];
2246      starts[0]=0;
2247      numberElements=0;
2248      for (iColumn=0;iColumn<number;iColumn++) {
2249        const int * rows;
2250        const double * elements;
2251        int numberElementsThis = buildObject.column(iColumn,lower[iColumn],upper[iColumn],
2252                                             objective[iColumn],rows,elements);
2253        CoinMemcpyN(rows,numberElementsThis,row+numberElements);
2254        CoinMemcpyN(elements,numberElementsThis,element+numberElements);
2255        numberElements += numberElementsThis;
2256        starts[iColumn+1]=numberElements;
2257      }
2258      addColumns(number, lower, upper,objective,NULL);
2259      // make sure matrix has enough rows
2260      matrix_->setDimensions(numberRows_,-1);
2261      numberErrors=matrix_->appendMatrix(number,1,starts,row,element,
2262                            checkDuplicates ? numberRows_ : -1);
2263      delete [] starts;
2264      delete [] row;
2265      delete [] element;
2266    } else {
2267      // arrays already filled in
2268      addColumns(number, lower, upper,objective,NULL);
2269      char * which=NULL; // for duplicates
2270      if (checkDuplicates) {
2271        which = new char[numberRows_];
[706]2272        CoinZeroN(which,numberRows_);
[577]2273      }
2274      // build +-1 matrix
2275      CoinBigIndex * startPositive = new CoinBigIndex [number+1];
2276      CoinBigIndex * startNegative = new CoinBigIndex [number];
2277      int * indices = new int [size];
2278      int * neg = new int[maximumLength];
2279      startPositive[0]=0;
2280      size=0;
2281      int maxRow=-1;
2282      for (iColumn=0;iColumn<number;iColumn++) {
2283        const int * rows;
2284        const double * elements;
2285        int numberElements = buildObject.column(iColumn,lower[iColumn],
2286                                                upper[iColumn],objective[iColumn],
2287                                                rows,elements);
2288        int nNeg=0;
2289        CoinBigIndex start = size;
2290        for (int i=0;i<numberElements;i++) {
2291          int iRow=rows[i];
2292          if (checkDuplicates) {
2293            if (iRow>=numberRows_) {
2294              if(which[iRow])
2295                numberErrors++;
2296              else
2297                which[iRow]=1;
2298            } else {
2299              numberErrors++;
2300              // and may as well switch off
2301              checkDuplicates=false;
2302            }
2303          }
2304          maxRow = CoinMax(maxRow,iRow);
2305          if (elements[i]==1.0) {
2306            indices[size++]=iRow;
2307          } else if (elements[i]==-1.0) {
2308            neg[nNeg++]=iRow;
2309          }
2310        }
2311        std::sort(indices+start,indices+size);
2312        std::sort(neg,neg+nNeg);
2313        startNegative[iColumn]=size;
[706]2314        CoinMemcpyN(neg,nNeg,indices+size);
[577]2315        size += nNeg;
2316        startPositive[iColumn+1]=size;
2317      }
2318      delete [] neg;
2319      // check size
2320      assert (maxRow+1<=numberRows_);
2321      // Get good object
2322      delete matrix_;
2323      ClpPlusMinusOneMatrix * matrix = new ClpPlusMinusOneMatrix();
2324      matrix->passInCopy(numberRows_,number,true,indices,startPositive,startNegative);
2325      matrix_=matrix;
2326      delete [] which;
2327    }
2328    delete [] objective;
2329    delete [] lower;
2330    delete [] upper;
2331  }
2332  return 0;
2333}
[650]2334#endif
[651]2335#ifndef SLIM_NOIO
[577]2336// Add columns from a model object
2337int 
[580]2338ClpModel::addColumns( CoinModel & modelObject,bool tryPlusMinusOne,bool checkDuplicates)
[577]2339{
[618]2340  if (modelObject.numberElements()==0)
2341    return 0;
[577]2342  bool goodState=true;
2343  if (modelObject.rowLowerArray()) {
2344    // some row information exists
2345    int numberRows2 = modelObject.numberRows();
2346    const double * rowLower = modelObject.rowLowerArray();
2347    const double * rowUpper = modelObject.rowUpperArray();
2348    for (int i=0;i<numberRows2;i++) {
2349      if (rowLower[i]!=-COIN_DBL_MAX) 
2350        goodState=false;
2351      if (rowUpper[i]!=COIN_DBL_MAX) 
2352        goodState=false;
2353    }
2354  }
2355  if (goodState) {
2356    // can do addColumns
2357    int numberErrors = 0;
2358    // Set arrays for normal use
2359    double * rowLower = modelObject.rowLowerArray();
2360    double * rowUpper = modelObject.rowUpperArray();
2361    double * columnLower = modelObject.columnLowerArray();
2362    double * columnUpper = modelObject.columnUpperArray();
2363    double * objective = modelObject.objectiveArray();
2364    int * integerType = modelObject.integerTypeArray();
2365    double * associated = modelObject.associatedArray();
2366    // If strings then do copies
2367    if (modelObject.stringsExist()) {
2368      numberErrors = modelObject.createArrays(rowLower, rowUpper, columnLower, columnUpper,
2369                                 objective, integerType,associated);
2370    }
2371    int numberColumns = numberColumns_; // save number of columns
2372    int numberColumns2 = modelObject.numberColumns();
2373    if (numberColumns2&&!numberErrors) {
2374      CoinBigIndex * startPositive = NULL;
2375      CoinBigIndex * startNegative = NULL;
2376      if ((!matrix_||!matrix_->getNumElements())&&!numberColumns&&tryPlusMinusOne) {
2377        startPositive = new CoinBigIndex[numberColumns2+1];
2378        startNegative = new CoinBigIndex[numberColumns2];
2379        modelObject.countPlusMinusOne(startPositive,startNegative,associated);
2380        if (startPositive[0]<0) {
2381          // no good
2382          tryPlusMinusOne=false;
2383          delete [] startPositive;
2384          delete [] startNegative;
2385        }
2386      } else {
2387        // Will add to whatever sort of matrix exists
2388        tryPlusMinusOne=false;
2389      }
2390      assert (columnLower);
[653]2391      addColumns(numberColumns2, columnLower, columnUpper,objective, NULL,NULL,NULL);
[650]2392#ifndef SLIM_CLP
[577]2393      if (!tryPlusMinusOne) {
[650]2394#endif
[577]2395        CoinPackedMatrix matrix;
2396        modelObject.createPackedMatrix(matrix,associated);
2397        assert (!matrix.getExtraGap());
2398        if (matrix_->getNumCols()) {
2399          const int * row = matrix.getIndices();
2400          //const int * columnLength = matrix.getVectorLengths();
2401          const CoinBigIndex * columnStart = matrix.getVectorStarts();
2402          const double * element = matrix.getElements();
2403          // make sure matrix has enough rows
2404          matrix_->setDimensions(numberRows_,-1);
2405          numberErrors+=matrix_->appendMatrix(numberColumns2,1,columnStart,row,element,
2406                                checkDuplicates ? numberRows_ : -1);
2407        } else {
2408          delete matrix_;
2409          matrix_ = new ClpPackedMatrix(matrix);
2410        }
[650]2411#ifndef SLIM_CLP
[577]2412      } else {
2413        // create +-1 matrix
2414        CoinBigIndex size = startPositive[numberColumns2];
2415        int * indices = new int[size];
2416        modelObject.createPlusMinusOne(startPositive,startNegative,indices,
2417                                       associated);
2418        // Get good object
2419        ClpPlusMinusOneMatrix * matrix = new ClpPlusMinusOneMatrix();
2420        matrix->passInCopy(numberRows_,numberColumns2,
2421                           true,indices,startPositive,startNegative);
2422        delete matrix_;
2423        matrix_=matrix;
2424      }
[650]2425#endif
[653]2426#ifndef CLP_NO_STD
[577]2427      // Do names if wanted
2428      if (modelObject.columnNames()->numberItems()) {
2429        const char *const * columnNames=modelObject.columnNames()->names();
2430        copyColumnNames(columnNames,numberColumns,numberColumns_);
2431      }
[653]2432#endif
[577]2433      // Do integers if wanted
2434      assert(integerType);
2435      for (int iColumn=0;iColumn<numberColumns2;iColumn++) {
2436        if (integerType[iColumn])
2437          setInteger(iColumn+numberColumns);
2438      }
2439    }
2440    if (columnLower!=modelObject.columnLowerArray()) {
2441      delete [] rowLower;
2442      delete [] rowUpper;
2443      delete [] columnLower;
2444      delete [] columnUpper;
2445      delete [] objective;
2446      delete [] integerType;
2447      delete [] associated;
2448      if (numberErrors)
2449        handler_->message(CLP_BAD_STRING_VALUES,messages_)
2450          <<numberErrors
2451          <<CoinMessageEol;
2452    }
2453    return numberErrors;
2454  } else {
2455    // not suitable for addColumns
2456    handler_->message(CLP_COMPLICATED_MODEL,messages_)
2457      <<modelObject.numberRows()
2458      <<modelObject.numberColumns()
2459      <<CoinMessageEol;
2460    return -1;
2461  }
2462}
[651]2463#endif
[409]2464// chgRowLower
2465void 
2466ClpModel::chgRowLower(const double * rowLower) 
2467{
2468  int numberRows = numberRows_;
2469  int iRow;
[472]2470  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
[409]2471  if (rowLower) {
2472    for (iRow = 0; iRow < numberRows; iRow++) {
2473      double value = rowLower[iRow];
2474      if (value<-1.0e20)
2475                 value = -COIN_DBL_MAX;
2476      rowLower_[iRow]= value;
2477    }
2478  } else {
2479    for (iRow = 0; iRow < numberRows; iRow++) {
2480      rowLower_[iRow]= -COIN_DBL_MAX;
2481    }
2482  }
2483}
2484// chgRowUpper
2485void 
2486ClpModel::chgRowUpper(const double * rowUpper) 
2487{
[472]2488  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
[409]2489  int numberRows = numberRows_;
2490  int iRow;
2491  if (rowUpper) {
2492    for (iRow = 0; iRow < numberRows; iRow++) {
2493      double value = rowUpper[iRow];
2494      if (value>1.0e20)
2495                 value = COIN_DBL_MAX;
2496      rowUpper_[iRow]= value;
2497    }
2498  } else {
2499    for (iRow = 0; iRow < numberRows; iRow++) {
2500      rowUpper_[iRow]= COIN_DBL_MAX;;
2501    }
2502  }
2503}
2504// chgColumnLower
2505void 
2506ClpModel::chgColumnLower(const double * columnLower) 
2507{
[472]2508  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
[409]2509  int numberColumns = numberColumns_;
2510  int iColumn;
2511  if (columnLower) {
2512    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
2513      double value = columnLower[iColumn];
2514      if (value<-1.0e20)
2515                 value = -COIN_DBL_MAX;
2516      columnLower_[iColumn]= value;
2517    }
2518  } else {
2519    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
2520      columnLower_[iColumn]= 0.0;
2521    }
2522  }
2523}
2524// chgColumnUpper
2525void 
2526ClpModel::chgColumnUpper(const double * columnUpper) 
2527{
[472]2528  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
[409]2529  int numberColumns = numberColumns_;
2530  int iColumn;
2531  if (columnUpper) {
2532    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
2533      double value = columnUpper[iColumn];
2534      if (value>1.0e20)
2535                 value = COIN_DBL_MAX;
2536      columnUpper_[iColumn]= value;
2537    }
2538  } else {
2539    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
2540      columnUpper_[iColumn]= COIN_DBL_MAX;;
2541    }
2542  }
2543}
2544// chgObjCoefficients
2545void 
2546ClpModel::chgObjCoefficients(const double * objIn) 
2547{
[472]2548  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
[409]2549  double * obj = objective();
2550  int numberColumns = numberColumns_;
2551  int iColumn;
2552  if (objIn) {
2553    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
2554      obj[iColumn] = objIn[iColumn];
2555    }
2556  } else {
2557    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
2558      obj[iColumn]= 0.0;
2559    }
2560  }
2561}
[2]2562// Infeasibility/unbounded ray (NULL returned if none/wrong)
2563double * 
2564ClpModel::infeasibilityRay() const
2565{
2566  double * array = NULL;
[1034]2567  if (problemStatus_==1&&!secondaryStatus_) {
[50]2568    array = ClpCopyOfArray(ray_,numberRows_);
[1034]2569#if 0
2570    // clean up
2571    double largest=1.0e-30;
2572    double smallest=COIN_DBL_MAX;
2573    int i;
2574    for (i=0;i<numberRows_;i++) {
2575      double value = fabs(array[i]);
2576      smallest = CoinMin(smallest,value);
2577      largest = CoinMax(largest,value);
2578    }
2579#endif
2580  }
[2]2581  return array;
2582}
2583double * 
2584ClpModel::unboundedRay() const
2585{
2586  double * array = NULL;
2587  if (problemStatus_==2) 
[50]2588    array = ClpCopyOfArray(ray_,numberColumns_);
[2]2589  return array;
2590}
2591void 
2592ClpModel::setMaximumIterations(int value)
2593{
2594  if(value>=0)
[82]2595    intParam_[ClpMaxNumIteration]=value;
[2]2596}
[142]2597void 
2598ClpModel::setMaximumSeconds(double value)
2599{
2600  if(value>=0)
[225]2601    dblParam_[ClpMaxSeconds]=value+CoinCpuTime();
[142]2602  else
2603    dblParam_[ClpMaxSeconds]=-1.0;
2604}
2605// Returns true if hit maximum iterations (or time)
2606bool 
2607ClpModel::hitMaximumIterations() const
2608{
[453]2609  // replaced - compiler error? bool hitMax= (numberIterations_>=maximumIterations());
2610  bool hitMax = (numberIterations_ >= intParam_[ClpMaxNumIteration]);
[1060]2611  if (dblParam_[ClpMaxSeconds]>=0.0&&!hitMax) {
[225]2612    hitMax = (CoinCpuTime()>=dblParam_[ClpMaxSeconds]);
[1060]2613  }
[142]2614  return hitMax;
2615}
[1060]2616// On stopped - sets secondary status
2617void 
2618ClpModel::onStopped()
2619{
2620  if (problemStatus_==3) {
2621    secondaryStatus_=0;
[1197]2622    if (CoinCpuTime()>=dblParam_[ClpMaxSeconds]&&dblParam_[ClpMaxSeconds]>=0.0)
[1060]2623      secondaryStatus_=9;
2624  }
2625}
[2]2626// Pass in Message handler (not deleted at end)
2627void 
[50]2628ClpModel::passInMessageHandler(CoinMessageHandler * handler)
[2]2629{
[72]2630  if (defaultHandler_)
2631    delete handler_;
[2]2632  defaultHandler_=false;
2633  handler_=handler;
2634}
[356]2635// Pass in Message handler (not deleted at end) and return current
2636CoinMessageHandler *
2637ClpModel::pushMessageHandler(CoinMessageHandler * handler,
2638                             bool & oldDefault)
2639{
2640  CoinMessageHandler * returnValue = handler_;
2641  oldDefault = defaultHandler_;
2642  defaultHandler_=false;
2643  handler_=handler;
2644  return returnValue;
2645}
2646// back to previous message handler
2647void
2648ClpModel::popMessageHandler(CoinMessageHandler * oldHandler,bool oldDefault)
2649{
2650  if (defaultHandler_)
2651    delete handler_;
2652  defaultHandler_=oldDefault;
2653  handler_=oldHandler;
2654}
[2]2655// Set language
2656void 
[50]2657ClpModel::newLanguage(CoinMessages::Language language)
[2]2658{
2659  messages_ = ClpMessage(language);
2660}
[651]2661#ifndef SLIM_NOIO
[2]2662// Read an mps file from the given filename
2663int 
2664ClpModel::readMps(const char *fileName,
2665                  bool keepNames,
2666                  bool ignoreErrors)
2667{
[150]2668  if (!strcmp(fileName,"-")||!strcmp(fileName,"stdin")) {
[2]2669    // stdin
2670  } else {
[603]2671    std::string name=fileName;
2672    bool readable = fileCoinReadable(name);
[601]2673    if (!readable) {
[2]2674      handler_->message(CLP_UNABLE_OPEN,messages_)
[50]2675        <<fileName<<CoinMessageEol;
[2]2676      return -1;
2677    }
2678  }
[50]2679  CoinMpsIO m;
[242]2680  m.passInMessageHandler(handler_);
[701]2681  *m.messagesPointer()=coinMessages();
[225]2682  bool savePrefix =m.messageHandler()->prefix();
2683  m.messageHandler()->setPrefix(handler_->prefix());
2684  double time1 = CoinCpuTime(),time2;
[608]2685  int status=0;
2686  try {
2687    status=m.readMps(fileName,"");
2688  }
2689  catch (CoinError e) {
2690    e.print();
2691    status=-1;
2692  }
[225]2693  m.messageHandler()->setPrefix(savePrefix);
[1034]2694  if (!status||(ignoreErrors&&(status>0&&status<100000))) {
[2]2695    loadProblem(*m.getMatrixByCol(),
2696                m.getColLower(),m.getColUpper(),
2697                m.getObjCoefficients(),
2698                m.getRowLower(),m.getRowUpper());
[50]2699    if (m.integerColumns()) {
2700      integerType_ = new char[numberColumns_];
[706]2701      CoinMemcpyN(m.integerColumns(),numberColumns_,integerType_);
[50]2702    } else {
2703      integerType_ = NULL;
2704    }
[651]2705#ifndef SLIM_CLP
[389]2706    // get quadratic part
2707    if (m.reader()->whichSection (  ) == COIN_QUAD_SECTION ) {
2708      int * start=NULL;
2709      int * column = NULL;
2710      double * element = NULL;
2711      status=m.readQuadraticMps(NULL,start,column,element,2);
2712      if (!status||ignoreErrors) 
2713        loadQuadraticObjective(numberColumns_,start,column,element);
2714      delete [] start;
2715      delete [] column;
2716      delete [] element;
2717    }
[653]2718#endif
2719#ifndef CLP_NO_STD   
[50]2720    // set problem name
2721    setStrParam(ClpProbName,m.getProblemName());
[2]2722    // do names
2723    if (keepNames) {
2724      unsigned int maxLength=0;
2725      int iRow;
[225]2726      rowNames_ = std::vector<std::string> ();
2727      columnNames_ = std::vector<std::string> ();
[2]2728      rowNames_.reserve(numberRows_);
2729      for (iRow=0;iRow<numberRows_;iRow++) {
2730        const char * name = m.rowName(iRow);
[399]2731        maxLength = CoinMax(maxLength,(unsigned int) strlen(name));
[2]2732          rowNames_.push_back(name);
2733      }
2734     
2735      int iColumn;
2736      columnNames_.reserve(numberColumns_);
2737      for (iColumn=0;iColumn<numberColumns_;iColumn++) {
2738        const char * name = m.columnName(iColumn);
[399]2739        maxLength = CoinMax(maxLength,(unsigned int) strlen(name));
[2]2740        columnNames_.push_back(name);
2741      }
2742      lengthNames_=(int) maxLength;
2743    } else {
2744      lengthNames_=0;
2745    }
[653]2746#endif
[50]2747    setDblParam(ClpObjOffset,m.objectiveOffset());
[225]2748    time2 = CoinCpuTime();
[2]2749    handler_->message(CLP_IMPORT_RESULT,messages_)
2750      <<fileName
[50]2751      <<time2-time1<<CoinMessageEol;
[2]2752  } else {
2753    // errors
2754    handler_->message(CLP_IMPORT_ERRORS,messages_)
[50]2755      <<status<<fileName<<CoinMessageEol;
[2]2756  }
2757
2758  return status;
2759}
[575]2760// Read GMPL files from the given filenames
2761int 
2762ClpModel::readGMPL(const char *fileName,const char * dataName,
2763                   bool keepNames)
2764{
2765  FILE *fp=fopen(fileName,"r");
2766  if (fp) {
2767    // can open - lets go for it
2768    fclose(fp);
2769    if (dataName) {
2770      fp=fopen(dataName,"r");
2771      if (fp) {
2772        fclose(fp);
2773      } else {
2774        handler_->message(CLP_UNABLE_OPEN,messages_)
2775          <<dataName<<CoinMessageEol;
2776        return -1;
2777      }
2778    }
2779  } else {
2780    handler_->message(CLP_UNABLE_OPEN,messages_)
2781      <<fileName<<CoinMessageEol;
2782    return -1;
2783  }
2784  CoinMpsIO m;
2785  m.passInMessageHandler(handler_);
[701]2786  *m.messagesPointer()=coinMessages();
[575]2787  bool savePrefix =m.messageHandler()->prefix();
2788  m.messageHandler()->setPrefix(handler_->prefix());
2789  double time1 = CoinCpuTime(),time2;
2790  int status=m.readGMPL(fileName,dataName,keepNames);
2791  m.messageHandler()->setPrefix(savePrefix);
2792  if (!status) {
2793    loadProblem(*m.getMatrixByCol(),
2794                m.getColLower(),m.getColUpper(),
2795                m.getObjCoefficients(),
2796                m.getRowLower(),m.getRowUpper());
2797    if (m.integerColumns()) {
2798      integerType_ = new char[numberColumns_];
[706]2799      CoinMemcpyN(m.integerColumns(),numberColumns_,integerType_);
[575]2800    } else {
2801      integerType_ = NULL;
2802    }
[653]2803#ifndef CLP_NO_STD
[575]2804    // set problem name
2805    setStrParam(ClpProbName,m.getProblemName());
2806    // do names
2807    if (keepNames) {
2808      unsigned int maxLength=0;
2809      int iRow;
2810      rowNames_ = std::vector<std::string> ();
2811      columnNames_ = std::vector<std::string> ();
2812      rowNames_.reserve(numberRows_);
2813      for (iRow=0;iRow<numberRows_;iRow++) {
2814        const char * name = m.rowName(iRow);
2815        maxLength = CoinMax(maxLength,(unsigned int) strlen(name));
2816          rowNames_.push_back(name);
2817      }
2818     
2819      int iColumn;
2820      columnNames_.reserve(numberColumns_);
2821      for (iColumn=0;iColumn<numberColumns_;iColumn++) {
2822        const char * name = m.columnName(iColumn);
2823        maxLength = CoinMax(maxLength,(unsigned int) strlen(name));
2824        columnNames_.push_back(name);
2825      }
2826      lengthNames_=(int) maxLength;
2827    } else {
2828      lengthNames_=0;
2829    }
[653]2830#endif
[575]2831    setDblParam(ClpObjOffset,m.objectiveOffset());
2832    time2 = CoinCpuTime();
2833    handler_->message(CLP_IMPORT_RESULT,messages_)
2834      <<fileName
2835      <<time2-time1<<CoinMessageEol;
2836  } else {
2837    // errors
2838    handler_->message(CLP_IMPORT_ERRORS,messages_)
2839      <<status<<fileName<<CoinMessageEol;
2840  }
2841  return status;
2842}
[651]2843#endif
[50]2844bool ClpModel::isPrimalObjectiveLimitReached() const
2845{
2846  double limit = 0.0;
2847  getDblParam(ClpPrimalObjectiveLimit, limit);
2848  if (limit > 1e30) {
2849    // was not ever set
2850    return false;
2851  }
2852   
2853  const double obj = objectiveValue();
[225]2854  const double maxmin = optimizationDirection();
[50]2855
2856  if (problemStatus_ == 0) // optimal
[254]2857    return maxmin > 0 ? (obj < limit) /*minim*/ : (-obj < limit) /*maxim*/;
[50]2858  else if (problemStatus_==2)
2859    return true;
2860  else
2861    return false;
2862}
2863
2864bool ClpModel::isDualObjectiveLimitReached() const
2865{
2866
2867  double limit = 0.0;
2868  getDblParam(ClpDualObjectiveLimit, limit);
2869  if (limit > 1e30) {
2870    // was not ever set
2871    return false;
2872  }
2873   
2874  const double obj = objectiveValue();
[225]2875  const double maxmin = optimizationDirection();
[50]2876
2877  if (problemStatus_ == 0) // optimal
[254]2878    return maxmin > 0 ? (obj > limit) /*minim*/ : (-obj > limit) /*maxim*/;
[50]2879  else if (problemStatus_==1)
2880    return true;
2881  else
2882    return false;
2883
2884}
2885void 
2886ClpModel::copyInIntegerInformation(const char * information)
2887{
2888  delete [] integerType_;
2889  if (information) {
2890    integerType_ = new char[numberColumns_];
[706]2891    CoinMemcpyN(information,numberColumns_,integerType_);
[50]2892  } else {
2893    integerType_ = NULL;
2894  }
2895}
[537]2896void
2897ClpModel::setContinuous(int index)
2898{
2899
2900  if (integerType_) {
2901#ifndef NDEBUG
2902    if (index<0||index>=numberColumns_) {
2903      indexError(index,"setContinuous");
2904    }
2905#endif
2906    integerType_[index]=0;
2907  }
2908}
2909//-----------------------------------------------------------------------------
2910void
2911ClpModel::setInteger(int index)
2912{
2913  if (!integerType_) {
2914    integerType_ = new char[numberColumns_];
[706]2915    CoinZeroN ( integerType_, numberColumns_);
[537]2916  }
2917#ifndef NDEBUG
2918  if (index<0||index>=numberColumns_) {
2919    indexError(index,"setInteger");
2920  }
2921#endif
2922  integerType_[index]=1;
2923}
[627]2924/* Return true if the index-th variable is an integer variable */
2925bool 
2926ClpModel::isInteger(int index) const
2927{
2928  if (!integerType_) {
2929    return false;
2930  } else {
2931#ifndef NDEBUG
2932    if (index<0||index>=numberColumns_) {
2933      indexError(index,"isInteger");
2934    }
2935#endif
2936    return (integerType_[index]!=0);
2937  }
2938}
[653]2939#ifndef CLP_NO_STD
[50]2940// Drops names - makes lengthnames 0 and names empty
2941void 
2942ClpModel::dropNames()
2943{
2944  lengthNames_=0;
2945  rowNames_ = std::vector<std::string> ();
2946  columnNames_ = std::vector<std::string> ();
2947}
[653]2948#endif
[50]2949// Drop integer informations
2950void 
2951ClpModel::deleteIntegerInformation()
2952{
2953  delete [] integerType_;
2954  integerType_ = NULL;
2955}
2956/* Return copy of status array (char[numberRows+numberColumns]),
2957   use delete [] */
2958unsigned char * 
2959ClpModel::statusCopy() const
2960{
2961  return ClpCopyOfArray(status_,numberRows_+numberColumns_);
2962}
2963// Copy in status vector
2964void 
2965ClpModel::copyinStatus(const unsigned char * statusArray)
2966{
2967  delete [] status_;
2968  if (statusArray) {
2969    status_ = new unsigned char [numberRows_+numberColumns_];
[1197]2970    CoinMemcpyN(statusArray,(numberRows_+numberColumns_),status_);
[50]2971  } else {
2972    status_=NULL;
2973  }
2974}
[650]2975#ifndef SLIM_CLP
[152]2976// Load up quadratic objective
2977void 
2978ClpModel::loadQuadraticObjective(const int numberColumns, const CoinBigIndex * start,
2979                              const int * column, const double * element)
2980{
[472]2981  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
[560]2982  CoinAssert (numberColumns==numberColumns_);
[225]2983  assert ((dynamic_cast< ClpLinearObjective*>(objective_)));
2984  double offset;
[393]2985  ClpObjective * obj = new ClpQuadraticObjective(objective_->gradient(NULL,NULL,offset,false),
2986                                                 numberColumns,
2987                                                 start,column,element);
[225]2988  delete objective_;
2989  objective_ = obj;
2990
[152]2991}
2992void 
2993ClpModel::loadQuadraticObjective (  const CoinPackedMatrix& matrix)
2994{
[472]2995  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
[560]2996  CoinAssert (matrix.getNumCols()==numberColumns_);
[225]2997  assert ((dynamic_cast< ClpLinearObjective*>(objective_)));
2998  double offset;
2999  ClpQuadraticObjective * obj = 
[393]3000    new ClpQuadraticObjective(objective_->gradient(NULL,NULL,offset,false),
3001                              numberColumns_,
3002                              NULL,NULL,NULL);
[225]3003  delete objective_;
3004  objective_ = obj;
3005  obj->loadQuadraticObjective(matrix);
[152]3006}
3007// Get rid of quadratic objective
3008void 
3009ClpModel::deleteQuadraticObjective()
3010{
[472]3011  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
[225]3012  ClpQuadraticObjective * obj = (dynamic_cast< ClpQuadraticObjective*>(objective_));
3013  if (obj)
3014    obj->deleteQuadraticObjective();
[152]3015}
[650]3016#endif
[225]3017void 
3018ClpModel::setObjective(ClpObjective * objective)
3019{
[472]3020  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
[225]3021  delete objective_;
3022  objective_=objective->clone();
3023}
3024// Returns resized array and updates size
3025double * whichDouble(double * array , int number, const int * which)
3026{
3027  double * newArray=NULL;
3028  if (array&&number) {
3029    int i ;
3030    newArray = new double[number];
3031    for (i=0;i<number;i++) 
3032      newArray[i]=array[which[i]];
3033  }
3034  return newArray;
3035}
3036char * whichChar(char * array , int number, const int * which)
3037{
3038  char * newArray=NULL;
3039  if (array&&number) {
3040    int i ;
3041    newArray = new char[number];
3042    for (i=0;i<number;i++) 
3043      newArray[i]=array[which[i]];
3044  }
3045  return newArray;
3046}
3047unsigned char * whichUnsignedChar(unsigned char * array , 
3048                                  int number, const int * which)
3049{
3050  unsigned char * newArray=NULL;
3051  if (array&&number) {
3052    int i ;
3053    newArray = new unsigned char[number];
3054    for (i=0;i<number;i++) 
3055      newArray[i]=array[which[i]];
3056  }
3057  return newArray;
3058}
3059// Replace Clp Matrix (current is not deleted)
3060void 
[410]3061ClpModel::replaceMatrix( ClpMatrixBase * matrix,bool deleteCurrent)
[225]3062{
[410]3063  if (deleteCurrent)
3064    delete matrix_;
[225]3065  matrix_=matrix;
[472]3066  whatsChanged_ = 0; // Too big a change
[225]3067}
3068// Subproblem constructor
3069ClpModel::ClpModel ( const ClpModel * rhs,
3070                     int numberRows, const int * whichRow,
3071                     int numberColumns, const int * whichColumn,
3072                     bool dropNames, bool dropIntegers)
[1147]3073  :  specialOptions_(rhs->specialOptions_),
3074  maximumColumns_(-1),
3075  maximumRows_(-1),
[1197]3076  maximumInternalColumns_(-1),
3077  maximumInternalRows_(-1),
[1147]3078  savedRowScale_(NULL),
3079  savedColumnScale_(NULL)
[225]3080{
3081  defaultHandler_ = rhs->defaultHandler_;
3082  if (defaultHandler_) 
3083    handler_ = new CoinMessageHandler(*rhs->handler_);
3084   else 
3085    handler_ = rhs->handler_;
[344]3086  eventHandler_ = rhs->eventHandler_->clone();
[1141]3087  randomNumberGenerator_ = rhs->randomNumberGenerator_;
[225]3088  messages_ = rhs->messages_;
[701]3089  coinMessages_ = rhs->coinMessages_;
[1147]3090  maximumColumns_ = -1;
3091  maximumRows_ = -1;
[1197]3092  maximumInternalColumns_ = -1;
3093  maximumInternalRows_ = -1;
[1147]3094  savedRowScale_ = NULL;
3095  savedColumnScale_ = NULL;
[225]3096  intParam_[ClpMaxNumIteration] = rhs->intParam_[ClpMaxNumIteration];
3097  intParam_[ClpMaxNumIterationHotStart] = 
3098    rhs->intParam_[ClpMaxNumIterationHotStart];
[1015]3099  intParam_[ClpNameDiscipline] = rhs->intParam_[ClpNameDiscipline] ;
[225]3100
3101  dblParam_[ClpDualObjectiveLimit] = rhs->dblParam_[ClpDualObjectiveLimit];
3102  dblParam_[ClpPrimalObjectiveLimit] = rhs->dblParam_[ClpPrimalObjectiveLimit];
3103  dblParam_[ClpDualTolerance] = rhs->dblParam_[ClpDualTolerance];
3104  dblParam_[ClpPrimalTolerance] = rhs->dblParam_[ClpPrimalTolerance];
3105  dblParam_[ClpObjOffset] = rhs->dblParam_[ClpObjOffset];
3106  dblParam_[ClpMaxSeconds] = rhs->dblParam_[ClpMaxSeconds];
[708]3107  dblParam_[ClpPresolveTolerance] = rhs->dblParam_[ClpPresolveTolerance];
[653]3108#ifndef CLP_NO_STD
[225]3109  strParam_[ClpProbName] = rhs->strParam_[ClpProbName];
[653]3110#endif
[1034]3111  specialOptions_ = rhs->specialOptions_;
[225]3112  optimizationDirection_ = rhs->optimizationDirection_;
3113  objectiveValue_=rhs->objectiveValue_;
3114  smallElement_ = rhs->smallElement_;
[389]3115  objectiveScale_ = rhs->objectiveScale_;
3116  rhsScale_ = rhs->rhsScale_;
[225]3117  numberIterations_ = rhs->numberIterations_;
3118  solveType_ = rhs->solveType_;
[472]3119  whatsChanged_ = 0; // Too big a change
[225]3120  problemStatus_ = rhs->problemStatus_;
3121  secondaryStatus_ = rhs->secondaryStatus_;
3122  // check valid lists
3123  int numberBad=0;
3124  int i;
3125  for (i=0;i<numberRows;i++)
3126    if (whichRow[i]<0||whichRow[i]>=rhs->numberRows_)
3127      numberBad++;
[561]3128  CoinAssertHint(!numberBad,"Bad row list for subproblem constructor");
[225]3129  numberBad=0;
3130  for (i=0;i<numberColumns;i++)
3131    if (whichColumn[i]<0||whichColumn[i]>=rhs->numberColumns_)
3132      numberBad++;
[561]3133  CoinAssertHint(!numberBad,"Bad Column list for subproblem constructor");
[225]3134  numberRows_ = numberRows;
3135  numberColumns_ = numberColumns;
[240]3136  userPointer_ = rhs->userPointer_;
[740]3137  numberThreads_=0;
[653]3138#ifndef CLP_NO_STD
[225]3139  if (!dropNames) {
3140    unsigned int maxLength=0;
3141    int iRow;
3142    rowNames_ = std::vector<std::string> ();
3143    columnNames_ = std::vector<std::string> ();
3144    rowNames_.reserve(numberRows_);
3145    for (iRow=0;iRow<numberRows_;iRow++) {
[355]3146      rowNames_.push_back(rhs->rowNames_[whichRow[iRow]]);
[399]3147      maxLength = CoinMax(maxLength,(unsigned int) strlen(rowNames_[iRow].c_str()));
[225]3148    }
3149    int iColumn;
3150    columnNames_.reserve(numberColumns_);
3151    for (iColumn=0;iColumn<numberColumns_;iColumn++) {
[355]3152      columnNames_.push_back(rhs->columnNames_[whichColumn[iColumn]]);
[399]3153      maxLength = CoinMax(maxLength,(unsigned int) strlen(columnNames_[iColumn].c_str()));
[225]3154    }
3155    lengthNames_=(int) maxLength;
3156  } else {
3157    lengthNames_ = 0;
3158    rowNames_ = std::vector<std::string> ();
3159    columnNames_ = std::vector<std::string> ();
3160  }
[653]3161#endif
[225]3162  if (rhs->integerType_&&!dropIntegers) {
3163    integerType_ = whichChar(rhs->integerType_,numberColumns,whichColumn);
3164  } else {
3165    integerType_ = NULL;
3166  }
3167  if (rhs->rowActivity_) {
3168    rowActivity_=whichDouble(rhs->rowActivity_,numberRows,whichRow);
3169    dual_=whichDouble(rhs->dual_,numberRows,whichRow);
3170    columnActivity_=whichDouble(rhs->columnActivity_,numberColumns,
3171                                whichColumn);
3172    reducedCost_=whichDouble(rhs->reducedCost_,numberColumns,
3173                                whichColumn);
3174  } else {
3175    rowActivity_=NULL;
3176    columnActivity_=NULL;
3177    dual_=NULL;
3178    reducedCost_=NULL;
3179  }
3180  rowLower_=whichDouble(rhs->rowLower_,numberRows,whichRow);
3181  rowUpper_=whichDouble(rhs->rowUpper_,numberRows,whichRow);
3182  columnLower_=whichDouble(rhs->columnLower_,numberColumns,whichColumn);
3183  columnUpper_=whichDouble(rhs->columnUpper_,numberColumns,whichColumn);
3184  if (rhs->objective_)
3185    objective_  = rhs->objective_->subsetClone(numberColumns,whichColumn);
3186  else
3187    objective_ = NULL;
3188  rowObjective_=whichDouble(rhs->rowObjective_,numberRows,whichRow);
3189  // status has to be done in two stages
3190  status_ = new unsigned char[numberColumns_+numberRows_];
3191  unsigned char * rowStatus = whichUnsignedChar(rhs->status_+rhs->numberColumns_,
3192                                                numberRows_,whichRow);
3193  unsigned char * columnStatus = whichUnsignedChar(rhs->status_,
3194                                                numberColumns_,whichColumn);
[706]3195  CoinMemcpyN(rowStatus,numberRows_,status_+numberColumns_);
[225]3196  delete [] rowStatus;
[706]3197  CoinMemcpyN(columnStatus,numberColumns_,status_);
[225]3198  delete [] columnStatus;
3199  ray_ = NULL;
3200  if (problemStatus_==1&&!secondaryStatus_)
3201    ray_ = whichDouble (rhs->ray_,numberRows,whichRow);
3202  else if (problemStatus_==2)
3203    ray_ = whichDouble (rhs->ray_,numberColumns,whichColumn);
[372]3204  rowScale_ = NULL;
3205  columnScale_ = NULL;
[1197]3206  inverseRowScale_ = NULL;
3207  inverseColumnScale_ = NULL;
[372]3208  scalingFlag_ = rhs->scalingFlag_;
[618]3209  rowCopy_=NULL;
[1150]3210  scaledMatrix_=NULL;
[225]3211  matrix_=NULL;
3212  if (rhs->matrix_) {
3213    matrix_ = rhs->matrix_->subsetClone(numberRows,whichRow,
3214                                        numberColumns,whichColumn);
3215  }
[1141]3216  randomNumberGenerator_.setSeed(1234567);
[225]3217}
[653]3218#ifndef CLP_NO_STD
[225]3219// Copies in names
3220void 
3221ClpModel::copyNames(std::vector<std::string> & rowNames,
3222                 std::vector<std::string> & columnNames)
3223{
3224  unsigned int maxLength=0;
3225  int iRow;
3226  rowNames_ = std::vector<std::string> ();
3227  columnNames_ = std::vector<std::string> ();
3228  rowNames_.reserve(numberRows_);
3229  for (iRow=0;iRow<numberRows_;iRow++) {
[240]3230    rowNames_.push_back(rowNames[iRow]);
[399]3231    maxLength = CoinMax(maxLength,(unsigned int) strlen(rowNames_[iRow].c_str()));
[225]3232  }
3233  int iColumn;
3234  columnNames_.reserve(numberColumns_);
3235  for (iColumn=0;iColumn<numberColumns_;iColumn++) {
[240]3236    columnNames_.push_back(columnNames[iColumn]);
[399]3237    maxLength = CoinMax(maxLength,(unsigned int) strlen(columnNames_[iColumn].c_str()));
[225]3238  }
3239  lengthNames_=(int) maxLength;
3240}
[637]3241// Return name or Rnnnnnnn
3242std::string
3243ClpModel::getRowName(int iRow) const
3244{
3245#ifndef NDEBUG
3246  if (iRow<0||iRow>=numberRows_) {
3247    indexError(iRow,"getRowName");
3248  }
3249#endif
3250  int size = rowNames_.size();
3251  if (size>iRow) {
3252    return rowNames_[iRow];
3253  } else {
3254    char name[9];
3255    sprintf(name,"R%7.7d",iRow);
3256    std::string rowName(name);
3257    return rowName;
3258  }
3259}
3260// Set row name
3261void
3262ClpModel::setRowName(int iRow, std::string &name)
3263{
3264#ifndef NDEBUG
3265  if (iRow<0||iRow>=numberRows_) {
3266    indexError(iRow,"setRowName");
3267  }
3268#endif
3269  unsigned int maxLength=lengthNames_;
3270  int size = rowNames_.size();
3271  if (size<=iRow)
3272    rowNames_.resize(iRow+1);
3273  rowNames_[iRow]= name;
3274  maxLength = CoinMax(maxLength,(unsigned int) strlen(name.c_str()));
3275  // May be too big - but we would have to check both rows and columns to be exact
3276  lengthNames_=(int) maxLength;
3277}
3278// Return name or Cnnnnnnn
3279std::string
3280ClpModel::getColumnName(int iColumn) const
3281{
3282#ifndef NDEBUG
3283  if (iColumn<0||iColumn>=numberColumns_) {
3284    indexError(iColumn,"getColumnName");
3285  }
3286#endif
3287  int size = columnNames_.size();
3288  if (size>iColumn) {
3289    return columnNames_[iColumn];
3290  } else {
3291    char name[9];
3292    sprintf(name,"C%7.7d",iColumn);
3293    std::string columnName(name);
3294    return columnName;
3295  }
3296}
3297// Set column name
3298void
3299ClpModel::setColumnName(int iColumn, std::string &name)
3300{
3301#ifndef NDEBUG
3302  if (iColumn<0||iColumn>=numberColumns_) {
3303    indexError(iColumn,"setColumnName");
3304  }
3305#endif
3306  unsigned int maxLength=lengthNames_;
3307  int size = columnNames_.size();
3308  if (size<=iColumn)
3309    columnNames_.resize(iColumn+1);
3310  columnNames_[iColumn]= name;
3311  maxLength = CoinMax(maxLength,(unsigned int) strlen(name.c_str()));
3312  // May be too big - but we would have to check both columns and columns to be exact
3313  lengthNames_=(int) maxLength;
3314}
[470]3315// Copies in Row names - modifies names first .. last-1
3316void 
3317ClpModel::copyRowNames(const std::vector<std::string> & rowNames, int first, int last)
3318{
3319  unsigned int maxLength=lengthNames_;
3320  int size = rowNames_.size();
3321  if (size!=numberRows_)
3322    rowNames_.resize(numberRows_);
3323  int iRow;
3324  for (iRow=first; iRow<last;iRow++) {
3325    rowNames_[iRow]= rowNames[iRow-first];
[647]3326    maxLength = CoinMax(maxLength,(unsigned int) strlen(rowNames_[iRow-first].c_str()));
[470]3327  }
3328  // May be too big - but we would have to check both rows and columns to be exact
3329  lengthNames_=(int) maxLength;
3330}
3331// Copies in Column names - modifies names first .. last-1
3332void 
3333ClpModel::copyColumnNames(const std::vector<std::string> & columnNames, int first, int last)
3334{
3335  unsigned int maxLength=lengthNames_;
3336  int size = columnNames_.size();
3337  if (size!=numberColumns_)
3338    columnNames_.resize(numberColumns_);
3339  int iColumn;
3340  for (iColumn=first; iColumn<last;iColumn++) {
3341    columnNames_[iColumn]= columnNames[iColumn-first];
[647]3342    maxLength = CoinMax(maxLength,(unsigned int) strlen(columnNames_[iColumn-first].c_str()));
[470]3343  }
3344  // May be too big - but we would have to check both rows and columns to be exact
3345  lengthNames_=(int) maxLength;
3346}
[546]3347// Copies in Row names - modifies names first .. last-1
3348void 
3349ClpModel::copyRowNames(const char * const * rowNames, int first, int last)
3350{
3351  unsigned int maxLength=lengthNames_;
3352  int size = rowNames_.size();
3353  if (size!=numberRows_)
3354    rowNames_.resize(numberRows_);
3355  int iRow;
3356  for (iRow=first; iRow<last;iRow++) {
[1034]3357    if (rowNames[iRow-first]&&strlen(rowNames[iRow-first])) {
3358      rowNames_[iRow]= rowNames[iRow-first];
3359      maxLength = CoinMax(maxLength,(unsigned int) strlen(rowNames[iRow-first]));
3360    } else {
3361      maxLength = CoinMax(maxLength,(unsigned int) 8);
3362      char name[9];
3363      sprintf(name,"R%7.7d",iRow);
3364      rowNames_[iRow]=name;
3365    }
[546]3366  }
3367  // May be too big - but we would have to check both rows and columns to be exact
3368  lengthNames_=(int) maxLength;
3369}
3370// Copies in Column names - modifies names first .. last-1
3371void 
3372ClpModel::copyColumnNames(const char * const * columnNames, int first, int last)
3373{
3374  unsigned int maxLength=lengthNames_;
3375  int size = columnNames_.size();
3376  if (size!=numberColumns_)
3377    columnNames_.resize(numberColumns_);
3378  int iColumn;
3379  for (iColumn=first; iColumn<last;iColumn++) {
[1034]3380    if (columnNames[iColumn-first]&&strlen(columnNames[iColumn-first])) {
3381      columnNames_[iColumn]= columnNames[iColumn-first];
3382      maxLength = CoinMax(maxLength,(unsigned int) strlen(columnNames[iColumn-first]));
3383    } else {
3384      maxLength = CoinMax(maxLength,(unsigned int) 8);
3385      char name[9];
3386      sprintf(name,"C%7.7d",iColumn);
3387      columnNames_[iColumn]=name;
3388    }
[546]3389  }
3390  // May be too big - but we would have to check both rows and columns to be exact
3391  lengthNames_=(int) maxLength;
3392}
[653]3393#endif
[470]3394// Primal objective limit
3395void 
3396ClpModel::setPrimalObjectiveLimit(double value)
3397{
3398  dblParam_[ClpPrimalObjectiveLimit]=value;
3399}
[240]3400// Dual objective limit
3401void 
3402ClpModel::setDualObjectiveLimit(double value)
3403{
3404  dblParam_[ClpDualObjectiveLimit]=value;
3405}
3406// Objective offset
3407void 
3408ClpModel::setObjectiveOffset(double value)
3409{
3410  dblParam_[ClpObjOffset]=value;
3411}
[325]3412// Solve a problem with no elements - return status
3413int ClpModel::emptyProblem(int * infeasNumber, double * infeasSum,bool printMessage)
3414{
[523]3415  secondaryStatus_=6; // so user can see something odd
[325]3416  if (printMessage)
3417    handler_->message(CLP_EMPTY_PROBLEM,messages_)
3418      <<numberRows_
3419      <<numberColumns_
3420      <<0
3421      <<CoinMessageEol;
3422  int returnCode=0;
3423  if (numberRows_||numberColumns_) {
3424    if (!status_) {
3425      status_ = new unsigned char[numberRows_+numberColumns_];
[706]3426      CoinZeroN(status_,numberRows_+numberColumns_);
[325]3427    }
3428  }
3429  // status is set directly (as can be used by Interior methods)
3430  // check feasible
3431  int numberPrimalInfeasibilities=0;
3432  double sumPrimalInfeasibilities=0.0;
3433  int numberDualInfeasibilities=0;
3434  double sumDualInfeasibilities=0.0;
3435  if (numberRows_) {
3436    for (int i=0;i<numberRows_;i++) {
3437      dual_[i]=0.0;
3438      if (rowLower_[i]<=rowUpper_[i]) {
3439        if (rowLower_[i]>-1.0e30||rowUpper_[i]<1.0e30) {
3440          if (fabs(rowLower_[i])<fabs(rowUpper_[i]))
3441            rowActivity_[i]=rowLower_[i];
3442          else
3443            rowActivity_[i]=rowUpper_[i];
3444        } else {
3445          rowActivity_[i]=0.0;
3446        }
3447      } else {
3448        rowActivity_[i]=0.0;
3449        numberPrimalInfeasibilities++;
3450        sumPrimalInfeasibilities += rowLower_[i]-rowUpper_[i];
3451        returnCode=1;
3452      }
3453      status_[i+numberColumns_]=1;
3454    }
3455  }
3456  objectiveValue_=0.0;
3457  if (numberColumns_) {
3458    const double * cost = objective();
3459    for (int i=0;i<numberColumns_;i++) {
3460      reducedCost_[i]=cost[i];
3461      double objValue = cost[i]*optimizationDirection_;
3462      if (columnLower_[i]<=columnUpper_[i]) {
3463        if (columnLower_[i]>-1.0e30||columnUpper_[i]<1.0e30) {
3464          if (!objValue) {
3465            if (fabs(columnLower_[i])<fabs(columnUpper_[i])) {
3466              columnActivity_[i]=columnLower_[i];
3467              status_[i]=3;
3468            } else {
3469              columnActivity_[i]=columnUpper_[i];
3470              status_[i]=2;
3471            }
3472          } else if (objValue>0.0) {
3473            if (columnLower_[i]>-1.0e30) {
3474              columnActivity_[i]=columnLower_[i];
3475              status_[i]=3;
3476            } else {
3477              columnActivity_[i]=columnUpper_[i];
3478              status_[i]=2;
3479              numberDualInfeasibilities++;;
3480              sumDualInfeasibilities += fabs(objValue);
3481              returnCode |= 2;
3482            }
3483            objectiveValue_ += columnActivity_[i]*objValue;
3484          } else {
3485            if (columnUpper_[i]<1.0e30) {
3486              columnActivity_[i]=columnUpper_[i];
3487              status_[i]=2;
3488            } else {
3489              columnActivity_[i]=columnLower_[i];
3490              status_[i]=3;
3491              numberDualInfeasibilities++;;
3492              sumDualInfeasibilities += fabs(objValue);
3493              returnCode |= 2;
3494            }
3495            objectiveValue_ += columnActivity_[i]*objValue;
3496          }
3497        } else {
3498          columnActivity_[i]=0.0;
3499          if (objValue) {
3500            numberDualInfeasibilities++;;
3501            sumDualInfeasibilities += fabs(objValue);
3502            returnCode |= 2;
3503          }
3504          status_[i]=0;
3505        }
3506      } else {
3507        if (fabs(columnLower_[i])<fabs(columnUpper_[i])) {
3508          columnActivity_[i]=columnLower_[i];
3509          status_[i]=3;
3510        } else {
3511          columnActivity_[i]=columnUpper_[i];
3512          status_[i]=2;
3513        }
3514        numberPrimalInfeasibilities++;
3515        sumPrimalInfeasibilities += columnLower_[i]-columnUpper_[i];
3516        returnCode |= 1;
3517      }
3518    }
3519  }
[848]3520  objectiveValue_ /= (objectiveScale_*rhsScale_);
[325]3521  if (infeasNumber) {
3522    infeasNumber[0]=numberDualInfeasibilities;
3523    infeasSum[0]=sumDualInfeasibilities;
3524    infeasNumber[1]=numberPrimalInfeasibilities;
3525    infeasSum[1]=sumPrimalInfeasibilities;
3526  }
3527  if (returnCode==3) 
3528    returnCode=4;
3529  return returnCode;
3530}
[651]3531#ifndef SLIM_NOIO
[335]3532/* Write the problem in MPS format to the specified file.
3533   
3534Row and column names may be null.
3535formatType is
3536<ul>
3537<li> 0 - normal
3538<li> 1 - extra accuracy
3539<li> 2 - IEEE hex (later)
3540</ul>
3541
3542Returns non-zero on I/O error
3543*/
3544int 
3545ClpModel::writeMps(const char *filen