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
Line 
1// copyright (C) 2002, International Business Machines
2// Corporation and others.  All Rights Reserved.
3
4#include <cstdlib>
5#include <cmath>
6#include <cassert>
7#include <cfloat>
8#include <string>
9#include <cstdio>
10#include <iostream>
11
12
13#include "CoinPragma.hpp"
14
15#include "CoinHelperFunctions.hpp"
16#include "CoinTime.hpp"
17#include "ClpModel.hpp"
18#include "ClpEventHandler.hpp"
19#include "ClpPackedMatrix.hpp"
20#ifndef SLIM_CLP
21#include "ClpPlusMinusOneMatrix.hpp"
22#endif
23#ifndef CLP_NO_VECTOR
24#include "CoinPackedVector.hpp"
25#endif
26#include "CoinIndexedVector.hpp"
27#if SLIM_CLP==2
28#define SLIM_NOIO
29#endif
30#ifndef SLIM_NOIO
31#include "CoinMpsIO.hpp"
32#include "CoinFileIO.hpp"
33#include "CoinModel.hpp"
34#endif
35#include "ClpMessage.hpp"
36#include "CoinMessage.hpp"
37#include "ClpLinearObjective.hpp"
38#ifndef SLIM_CLP
39#include "ClpQuadraticObjective.hpp"
40#include "CoinBuild.hpp"
41#endif
42
43//#############################################################################
44ClpModel::ClpModel (bool emptyMessages) :
45
46  optimizationDirection_(1),
47  objectiveValue_(0.0),
48  smallElement_(1.0e-20),
49  objectiveScale_(1.0),
50  rhsScale_(1.0),
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),
65  scaledMatrix_(NULL),
66  ray_(NULL),
67  rowScale_(NULL),
68  columnScale_(NULL),
69  inverseRowScale_(NULL),
70  inverseColumnScale_(NULL),
71  scalingFlag_(3),
72  status_(NULL),
73  integerType_(NULL),
74  userPointer_(NULL),
75  numberIterations_(0),
76  solveType_(0),
77  whatsChanged_(0),
78  problemStatus_(-1),
79  secondaryStatus_(0),
80  lengthNames_(0),
81  numberThreads_(0),
82  specialOptions_(0),
83#ifndef CLP_NO_STD
84  defaultHandler_(true),
85  rowNames_(),
86  columnNames_(),
87#else
88  defaultHandler_(true),
89#endif
90  maximumColumns_(-1),
91  maximumRows_(-1),
92  maximumInternalColumns_(-1),
93  maximumInternalRows_(-1),
94  savedRowScale_(NULL),
95  savedColumnScale_(NULL)
96{
97  intParam_[ClpMaxNumIteration] = 2147483647;
98  intParam_[ClpMaxNumIterationHotStart] = 9999999;
99  intParam_[ClpNameDiscipline] = 0;
100
101  dblParam_[ClpDualObjectiveLimit] = COIN_DBL_MAX;
102  dblParam_[ClpPrimalObjectiveLimit] = COIN_DBL_MAX;
103  dblParam_[ClpDualTolerance] = 1e-7;
104  dblParam_[ClpPrimalTolerance] = 1e-7;
105  dblParam_[ClpObjOffset] = 0.0;
106  dblParam_[ClpMaxSeconds] = -1.0;
107  dblParam_[ClpPresolveTolerance] = 1.0e-8;
108
109#ifndef CLP_NO_STD
110  strParam_[ClpProbName] = "ClpDefaultName";
111#endif
112  handler_ = new CoinMessageHandler();
113  handler_->setLogLevel(1);
114  eventHandler_ = new ClpEventHandler();
115  if (!emptyMessages) {
116    messages_ = ClpMessage();
117    coinMessages_ = CoinMessage();
118  }
119  randomNumberGenerator_.setSeed(1234567);
120}
121
122//-----------------------------------------------------------------------------
123
124ClpModel::~ClpModel ()
125{
126  if (defaultHandler_) {
127    delete handler_;
128    handler_ = NULL;
129  }
130  gutsOfDelete(0);
131}
132// Does most of deletion (0 = all, 1 = most)
133void 
134ClpModel::gutsOfDelete(int type)
135{
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;
179  delete matrix_;
180  matrix_=NULL;
181  delete rowCopy_;
182  rowCopy_=NULL;
183  delete scaledMatrix_;
184  scaledMatrix_=NULL,
185  delete [] ray_;
186  ray_ = NULL;
187  specialOptions_ = 0;
188}
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}
211//#############################################################################
212void ClpModel::setPrimalTolerance( double value) 
213{
214  if (value>0.0&&value<1.0e10) 
215    dblParam_[ClpPrimalTolerance]=value;
216}
217void ClpModel::setDualTolerance( double value) 
218{
219  if (value>0.0&&value<1.0e10)
220    dblParam_[ClpDualTolerance]=value;
221}
222void ClpModel::setOptimizationDirection( double value) 
223{
224  optimizationDirection_=value;
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{
233  // save event handler in case already set
234  ClpEventHandler * handler = eventHandler_->clone();
235  // Save specialOptions
236  int saveOptions = specialOptions_;
237  gutsOfDelete(0);
238  specialOptions_ = saveOptions;
239  eventHandler_ = handler;
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
247  CoinZeroN(dual_,numberRows_);
248  CoinZeroN(reducedCost_,numberColumns_);
249  int iRow,iColumn;
250
251  rowLower_=ClpCopyOfArray(rowlb,numberRows_,-COIN_DBL_MAX);
252  rowUpper_=ClpCopyOfArray(rowub,numberRows_,COIN_DBL_MAX);
253  double * objective=ClpCopyOfArray(obj,numberColumns_,0.0);
254  objective_ = new ClpLinearObjective(objective,numberColumns_);
255  delete [] objective;
256  rowObjective_=ClpCopyOfArray(rowObjective,numberRows_);
257  columnLower_=ClpCopyOfArray(collb,numberColumns_,0.0);
258  columnUpper_=ClpCopyOfArray(colub,numberColumns_,COIN_DBL_MAX);
259  // set default solution and clean bounds
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    }
268    if (rowLower_[iRow]<-1.0e27)
269      rowLower_[iRow]=-COIN_DBL_MAX;
270    if (rowUpper_[iRow]>1.0e27)
271      rowUpper_[iRow]=COIN_DBL_MAX;
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    }
281    if (columnLower_[iColumn]<-1.0e27)
282      columnLower_[iColumn]=-COIN_DBL_MAX;
283    if (columnUpper_[iColumn]>1.0e27)
284      columnUpper_[iColumn]=COIN_DBL_MAX;
285  }
286}
287// This just loads up a row objective
288void ClpModel::setRowObjective(const double * rowObjective)
289{
290  delete [] rowObjective_;
291  rowObjective_=ClpCopyOfArray(rowObjective,numberRows_);
292  whatsChanged_=0;
293}
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
307    CoinPackedMatrix matrix2;
308    matrix2.reverseOrderedCopyOf(*matrix.getPackedMatrix());
309    matrix.releasePackedMatrix();
310    matrix_=new ClpPackedMatrix(matrix2);
311  }   
312  matrix_->setDimensions(numberRows_,numberColumns_);
313}
314void
315ClpModel::loadProblem (  const CoinPackedMatrix& matrix,
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 {
326    CoinPackedMatrix matrix2;
327    matrix2.reverseOrderedCopyOf(matrix);
328    matrix_=new ClpPackedMatrix(matrix2);
329  }   
330  matrix_->setDimensions(numberRows_,numberColumns_);
331}
332void
333ClpModel::loadProblem ( 
334                              const int numcols, const int numrows,
335                              const CoinBigIndex* start, const int* index,
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);
344  int numberElements = start ? start[numcols] : 0;
345  CoinPackedMatrix matrix(true,numrows,numrows ? numcols : 0,numberElements,
346                              value,index,start,NULL);
347  matrix_ = new ClpPackedMatrix(matrix);
348  matrix_->setDimensions(numberRows_,numberColumns_);
349}
350void
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}
371#ifndef SLIM_NOIO
372// This loads a model from a coinModel object - returns number of errors
373int 
374ClpModel::loadProblem (  CoinModel & modelObject,bool tryPlusMinusOne)
375{
376  if (modelObject.numberColumns()==0&&modelObject.numberRows()==0)
377    return 0;
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);
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  }
410#ifndef SLIM_CLP
411  if (!tryPlusMinusOne) {
412#endif
413    CoinPackedMatrix matrix;
414    modelObject.createPackedMatrix(matrix,associated);
415    matrix_ = new ClpPackedMatrix(matrix);
416#ifndef SLIM_CLP
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  }
429#endif
430#ifndef CLP_NO_STD
431  // Do names if wanted
432  int numberItems;
433  numberItems = modelObject.rowNames()->numberItems();
434  if (numberItems) {
435    const char *const * rowNames=modelObject.rowNames()->names();
436    copyRowNames(rowNames,0,numberItems);
437  }
438  numberItems = modelObject.columnNames()->numberItems();
439  if (numberItems) {
440    const char *const * columnNames=modelObject.columnNames()->names();
441    copyColumnNames(columnNames,0,numberItems);
442  }
443#endif
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;
458    delete [] associated;
459    if (numberErrors)
460      handler_->message(CLP_BAD_STRING_VALUES,messages_)
461        <<numberErrors
462        <<CoinMessageEol;
463  }
464  matrix_->setDimensions(numberRows_,numberColumns_);
465  return numberErrors;
466}
467#endif
468void
469ClpModel::getRowBound(int iRow, double& lower, double& upper) const
470{
471  lower=-COIN_DBL_MAX;
472  upper=COIN_DBL_MAX;
473  if (rowUpper_)
474    upper=rowUpper_[iRow];
475  if (rowLower_)
476    lower=rowLower_[iRow];
477}
478//------------------------------------------------------------------
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
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;
499  whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep)
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;
508  whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep)
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;
518  whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep)
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;
529  CoinAssert (upper>=lower);
530  rowLower_[elementIndex] = lower;
531  rowUpper_[elementIndex] = upper;
532  whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep)
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_;
543  whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep)
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;
557    CoinAssert (upper[iRow]>=lower[iRow]);
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;
575  whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep)
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;
592  whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep)
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;
612  CoinAssert (upper>=lower);
613  whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep)
614}
615void ClpModel::setColumnSetBounds(const int* indexFirst,
616                                            const int* indexLast,
617                                            const double* boundList)
618{
619  double * lower = columnLower_;
620  double * upper = columnUpper_;
621  whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep)
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++;
634    CoinAssert (upper[iColumn]>=lower[iColumn]);
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//-----------------------------------------------------------------------------
642//#############################################################################
643// Copy constructor.
644ClpModel::ClpModel(const ClpModel &rhs, int scalingMode) :
645  optimizationDirection_(rhs.optimizationDirection_),
646  numberRows_(rhs.numberRows_),
647  numberColumns_(rhs.numberColumns_),
648  specialOptions_(rhs.specialOptions_),
649  maximumColumns_(-1),
650  maximumRows_(-1),
651  maximumInternalColumns_(-1),
652  maximumInternalRows_(-1),
653  savedRowScale_(NULL),
654  savedColumnScale_(NULL)
655{
656  gutsOfCopy(rhs);
657  if (scalingMode>=0&&matrix_&&
658      matrix_->allElementsInRange(this,smallElement_,1.0e20)) {
659    // really do scaling
660    scalingFlag_=scalingMode;
661    setRowScale(NULL);
662    setColumnScale(NULL);
663    delete rowCopy_; // in case odd
664    rowCopy_=NULL;
665    delete scaledMatrix_;
666    scaledMatrix_=NULL;
667    if (scalingMode&&!matrix_->scale(this)) {
668      // scaling worked - now apply
669      gutsOfScaling();
670      // pretend not scaled
671      scalingFlag_ = -scalingFlag_;
672    } else {
673      // not scaled
674      scalingFlag_=0;
675    }
676  }
677  randomNumberGenerator_.setSeed(1234567);
678}
679// Assignment operator. This copies the data
680ClpModel & 
681ClpModel::operator=(const ClpModel & rhs)
682{
683  if (this != &rhs) {
684    if (defaultHandler_) {
685      //delete handler_;
686      //handler_ = NULL;
687    }
688    gutsOfDelete(1);
689    optimizationDirection_ = rhs.optimizationDirection_;
690    numberRows_ = rhs.numberRows_;
691    numberColumns_ = rhs.numberColumns_;
692    gutsOfCopy(rhs,-1);
693  }
694  return *this;
695}
696/* Does most of copying
697   If trueCopy 0 then just points to arrays
698   If -1 leaves as much as possible */
699void 
700ClpModel::gutsOfCopy(const ClpModel & rhs, int trueCopy)
701{
702  defaultHandler_ = rhs.defaultHandler_;
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  }
716  intParam_[ClpMaxNumIteration] = rhs.intParam_[ClpMaxNumIteration];
717  intParam_[ClpMaxNumIterationHotStart] = 
718    rhs.intParam_[ClpMaxNumIterationHotStart];
719  intParam_[ClpNameDiscipline] = rhs.intParam_[ClpNameDiscipline] ;
720
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];
726  dblParam_[ClpMaxSeconds] = rhs.dblParam_[ClpMaxSeconds];
727  dblParam_[ClpPresolveTolerance] = rhs.dblParam_[ClpPresolveTolerance];
728#ifndef CLP_NO_STD
729
730  strParam_[ClpProbName] = rhs.strParam_[ClpProbName];
731#endif
732
733  optimizationDirection_ = rhs.optimizationDirection_;
734  objectiveValue_=rhs.objectiveValue_;
735  smallElement_ = rhs.smallElement_;
736  objectiveScale_ = rhs.objectiveScale_;
737  rhsScale_ = rhs.rhsScale_;
738  numberIterations_ = rhs.numberIterations_;
739  solveType_ = rhs.solveType_;
740  whatsChanged_ = rhs.whatsChanged_;
741  problemStatus_ = rhs.problemStatus_;
742  secondaryStatus_ = rhs.secondaryStatus_;
743  numberRows_ = rhs.numberRows_;
744  numberColumns_ = rhs.numberColumns_;
745  userPointer_ = rhs.userPointer_;
746  scalingFlag_ = rhs.scalingFlag_;
747  specialOptions_ = rhs.specialOptions_;
748  if (trueCopy) {
749#ifndef CLP_NO_STD
750    lengthNames_ = rhs.lengthNames_;
751    if (lengthNames_) {
752      rowNames_ = rhs.rowNames_;
753      columnNames_ = rhs.columnNames_;
754    }
755#endif
756    numberThreads_ = rhs.numberThreads_;
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      }
804      if (rhs.scaledMatrix_) {
805        scaledMatrix_ = new ClpPackedMatrix(*rhs.scaledMatrix_);
806      } else {
807        scaledMatrix_=NULL;
808      }
809      matrix_=NULL;
810      if (rhs.matrix_) {
811        matrix_ = rhs.matrix_->clone();
812      }
813    } else {
814      // This already has arrays - just copy
815      savedRowScale_ = NULL;
816      savedColumnScale_ = NULL;
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      }
864      delete scaledMatrix_;
865      if (rhs.scaledMatrix_) {
866        scaledMatrix_ = new ClpPackedMatrix(*rhs.scaledMatrix_);
867      } else {
868        scaledMatrix_=NULL;
869      }
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_);
878        ClpDisjointCopyN(rhs.savedRowScale_,4*maximumInternalRows_,savedRowScale_);
879        ClpDisjointCopyN(rhs.savedColumnScale_,4*maximumInternalColumns_,savedColumnScale_);
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
891    }
892  } else {
893    savedRowScale_ = rhs.savedRowScale_;
894    assert (!savedRowScale_);
895    savedColumnScale_ = rhs.savedColumnScale_;
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_;
907    rowCopy_ = NULL;
908    scaledMatrix_ = NULL;
909    ray_ = rhs.ray_;
910    //rowScale_ = rhs.rowScale_;
911    //columnScale_ = rhs.columnScale_;
912    lengthNames_ = 0;
913    numberThreads_ = rhs.numberThreads_;
914#ifndef CLP_NO_STD
915    rowNames_ = std::vector<std::string> ();
916    columnNames_ = std::vector<std::string> ();
917#endif
918    integerType_ = NULL;
919    status_ = rhs.status_;
920  }
921  inverseRowScale_ = NULL;
922  inverseColumnScale_ = NULL;
923}
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
938  delete modelPtr_->matrix_;
939  if (continuousModel_->matrix_) {
940    modelPtr_->matrix_ = continuousModel_->matrix_->clone();
941  } else {
942    modelPtr_->matrix_=NULL;
943  }
944#endif
945}
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  }
956  gutsOfDelete(1);
957  optimizationDirection_ = rhs.optimizationDirection_;
958  numberRows_ = rhs.numberRows_;
959  numberColumns_ = rhs.numberColumns_;
960  delete [] rhs.ray_;
961  rhs.ray_=NULL;
962  // make sure scaled matrix not copied
963  ClpPackedMatrix * save = rhs.scaledMatrix_;
964  rhs.scaledMatrix_ = NULL;
965  delete scaledMatrix_;
966  scaledMatrix_=NULL;
967  gutsOfCopy(rhs,0);
968  rhs.scaledMatrix_ = save;
969  specialOptions_ = rhs.specialOptions_ & ~65536;
970  savedRowScale_=NULL;
971  savedColumnScale_=NULL;
972  inverseRowScale_ = NULL;
973  inverseColumnScale_ = NULL;
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_;
982  otherModel.secondaryStatus_ = secondaryStatus_;
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;
995  delete scaledMatrix_;
996  scaledMatrix_ = NULL;
997  delete [] otherModel.ray_;
998  otherModel.ray_ = ray_;
999  ray_ = NULL;
1000  if (rowScale_&&otherModel.rowScale_!=rowScale_) {
1001    delete [] rowScale_;
1002    delete [] columnScale_;
1003  }
1004  rowScale_ = NULL;
1005  columnScale_ = NULL;
1006  //rowScale_=NULL;
1007  //columnScale_=NULL;
1008  // do status
1009  if (otherModel.status_!=status_) {
1010    delete [] otherModel.status_;
1011    otherModel.status_ = status_;
1012  }
1013  status_ = NULL;
1014  if (defaultHandler_) {
1015    delete handler_;
1016    handler_ = NULL;
1017  }
1018  inverseRowScale_ = NULL;
1019  inverseColumnScale_ = NULL;
1020}
1021//#############################################################################
1022// Parameter related methods
1023//#############################################################################
1024
1025bool
1026ClpModel::setIntParam(ClpIntParam key, int value)
1027{
1028  switch (key) {
1029  case ClpMaxNumIteration:
1030    if (value < 0)
1031      return false;
1032    break;
1033  case ClpMaxNumIterationHotStart:
1034    if (value < 0)
1035      return false;
1036    break;
1037  case ClpNameDiscipline:
1038    if (value < 0)
1039      return false;
1040    break;
1041  default:
1042    return false;
1043  }
1044  intParam_[key] = value;
1045  return true;
1046}
1047
1048//-----------------------------------------------------------------------------
1049
1050bool
1051ClpModel::setDblParam(ClpDblParam key, double value)
1052{
1053
1054  switch (key) {
1055  case ClpDualObjectiveLimit:
1056    break;
1057
1058  case ClpPrimalObjectiveLimit:
1059    break;
1060
1061  case ClpDualTolerance: 
1062    if (value<=0.0||value>1.0e10)
1063      return false;
1064    break;
1065   
1066  case ClpPrimalTolerance: 
1067    if (value<=0.0||value>1.0e10)
1068      return false;
1069    break;
1070   
1071  case ClpObjOffset: 
1072    break;
1073
1074  case ClpMaxSeconds: 
1075    if(value>=0)
1076      value += CoinCpuTime();
1077    else
1078      value = -1.0;
1079    break;
1080
1081  case ClpPresolveTolerance: 
1082    if (value<=0.0||value>1.0e10)
1083      return false;
1084    break;
1085   
1086  default:
1087    return false;
1088  }
1089  dblParam_[key] = value;
1090  return true;
1091}
1092
1093//-----------------------------------------------------------------------------
1094#ifndef CLP_NO_STD
1095
1096bool
1097ClpModel::setStrParam(ClpStrParam key, const std::string & value)
1098{
1099
1100  switch (key) {
1101  case ClpProbName:
1102    break;
1103
1104  default:
1105    return false;
1106  }
1107  strParam_[key] = value;
1108  return true;
1109}
1110#endif
1111// Useful routines
1112// Returns resized array and deletes incoming
1113double * resizeDouble(double * array , int size, int newSize, double fill,
1114                      bool createArray)
1115{
1116  if ((array||createArray)&&size<newSize) {
1117    int i;
1118    double * newArray = new double[newSize];
1119    if (array)
1120      CoinMemcpyN(array,CoinMin(newSize,size),newArray);
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;
1136    CoinZeroN(deleted,size);
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}
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;
1166    CoinZeroN(deleted,size);
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}
1189// Create empty ClpPackedMatrix
1190void 
1191ClpModel::createEmptyMatrix()
1192{
1193  delete matrix_;
1194  whatsChanged_ = 0;
1195  CoinPackedMatrix matrix2;
1196  matrix_=new ClpPackedMatrix(matrix2);
1197}
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}
1215// Resizes
1216void 
1217ClpModel::resize (int newNumberRows, int newNumberColumns)
1218{
1219  if (newNumberRows==numberRows_&&
1220      newNumberColumns==numberColumns_)
1221    return; // nothing to do
1222  whatsChanged_ = 0;
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_)
1270    objective_->resize(newNumberColumns);
1271  else if (!objective_)
1272    objective_ = new ClpLinearObjective(NULL,newNumberColumns);
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  }
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;
1290    secondaryStatus_ = 0;
1291    delete [] ray_;
1292    ray_ = NULL;
1293  }
1294  setRowScale(NULL);
1295  setColumnScale(NULL);
1296  if (status_) {
1297    if (newNumberColumns+newNumberRows) {
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      }
1315    } else {
1316      // empty model - some systems don't like new [0]
1317      delete [] status_;
1318      status_ = NULL;
1319    }
1320  }
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
1344  numberRows_ = newNumberRows;
1345  if (newNumberColumns<numberColumns_&&matrix_->getNumCols()) {
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  }
1353  if (integerType_&&numberColumns2>maximumColumns_) {
1354    char * temp = new char [newNumberColumns];
1355    CoinZeroN(temp,newNumberColumns);
1356    CoinMemcpyN(integerType_,
1357           CoinMin(newNumberColumns,numberColumns_),temp);
1358    delete [] integerType_;
1359    integerType_ = temp;
1360  }
1361  numberColumns_ = newNumberColumns;
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  }
1372}
1373// Deletes rows
1374void 
1375ClpModel::deleteRows(int number, const int * which)
1376{
1377  if (!number)
1378    return; // nothing to do
1379  whatsChanged_ &= ~(1+2+4+8+16+32); // all except columns changed
1380  int newSize=0;
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      }
1412    }
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;
1441  }
1442#ifndef CLP_NO_STD
1443  // Now works if which out of order
1444  if (lengthNames_) {
1445    char * mark = new char [numberRows_];
1446    CoinZeroN(mark,numberRows_);
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]) 
1453        rowNames_[k++] = rowNames_[i];
1454    }
1455    rowNames_.erase(rowNames_.begin()+k, rowNames_.end());
1456    delete [] mark;
1457  }
1458#endif
1459  numberRows_=newSize;
1460  // set state back to unknown
1461  problemStatus_ = -1;
1462  secondaryStatus_ = 0;
1463  delete [] ray_;
1464  ray_ = NULL;
1465  if (savedRowScale_!=rowScale_) {
1466    delete [] rowScale_;
1467    delete [] columnScale_;
1468  }
1469  rowScale_ = NULL;
1470  columnScale_ = NULL;
1471}
1472// Deletes columns
1473void 
1474ClpModel::deleteColumns(int number, const int * which)
1475{
1476  if (!number)
1477    return; // nothing to do
1478  assert (maximumColumns_<0);
1479  whatsChanged_ &= ~(1+2+4+8+64+128+256); // all except rows changed
1480  int newSize=0;
1481  columnActivity_ = deleteDouble(columnActivity_,numberColumns_,
1482                              number, which, newSize);
1483  reducedCost_ = deleteDouble(reducedCost_,numberColumns_,
1484                              number, which, newSize);
1485  objective_->deleteSome(number, which);
1486  columnLower_ = deleteDouble(columnLower_,numberColumns_,
1487                              number, which, newSize);
1488  columnUpper_ = deleteDouble(columnUpper_,numberColumns_,
1489                              number, which, newSize);
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  }
1504  //matrix_->removeGaps();
1505  // status
1506  if (status_) {
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];
1512      CoinMemcpyN(tempC,newSize,temp);
1513      CoinMemcpyN(status_+numberColumns_,       numberRows_,temp+newSize);
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    }
1522  }
1523  integerType_ = deleteChar(integerType_,numberColumns_,
1524                            number, which, newSize,true);
1525#ifndef CLP_NO_STD
1526  // Now works if which out of order
1527  if (lengthNames_) {
1528    char * mark = new char [numberColumns_];
1529    CoinZeroN(mark,numberColumns_);
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]) 
1536        columnNames_[k++] = columnNames_[i];
1537    }
1538    columnNames_.erase(columnNames_.begin()+k, columnNames_.end());
1539    delete [] mark;
1540  }
1541#endif
1542  numberColumns_=newSize;
1543  // set state back to unknown
1544  problemStatus_ = -1;
1545  secondaryStatus_ = 0;
1546  delete [] ray_;
1547  ray_ = NULL;
1548  setRowScale(NULL);
1549  setColumnScale(NULL);
1550}
1551// Add one row
1552void 
1553ClpModel::addRow(int numberInRow, const int * columns,
1554                 const double * elements, double rowLower, double rowUpper)
1555{
1556  CoinBigIndex starts[2];
1557  starts[0]=0;
1558  starts[1]=numberInRow;
1559  addRows(1, &rowLower, &rowUpper,starts,columns,elements);
1560}
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) {
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;
1574    int iRow;
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      }
1586    }
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;
1603    delete scaledMatrix_;
1604    scaledMatrix_=NULL;
1605    if (!matrix_)
1606      createEmptyMatrix();
1607    setRowScale(NULL);
1608    setColumnScale(NULL);
1609#ifndef CLP_NO_STD
1610    if (lengthNames_) {
1611      rowNames_.resize(numberRows_);
1612    }
1613#endif
1614    if (rowStarts) 
1615      matrix_->appendMatrix(number,0,rowStarts,columns,elements);
1616  }
1617}
1618// Add rows
1619void 
1620ClpModel::addRows(int number, const double * rowLower, 
1621                  const double * rowUpper,
1622                  const int * rowStarts, 
1623                  const int * rowLengths, const int * columns,
1624                  const double * elements)
1625{
1626  if (number) {
1627    CoinBigIndex numberElements=0;
1628    int iRow;
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;
1636    for (iRow=0;iRow<number;iRow++) {
1637      int iStart = rowStarts[iRow];
1638      int length = rowLengths[iRow];
1639      CoinMemcpyN(columns+iStart,length,newIndex+numberElements);
1640      CoinMemcpyN(elements+iStart,length,newElements+numberElements);
1641      numberElements += length;
1642      newStarts[iRow+1]=numberElements;
1643    }
1644    addRows(number, rowLower, rowUpper,
1645            newStarts,newIndex,newElements);
1646    delete [] newStarts;
1647    delete [] newIndex;
1648    delete [] newElements;
1649  }
1650}
1651#ifndef CLP_NO_VECTOR
1652void 
1653ClpModel::addRows(int number, const double * rowLower, 
1654                  const double * rowUpper,
1655                  const CoinPackedVectorBase * const * rows)
1656{
1657  if (!number)
1658    return;
1659  whatsChanged_ &= ~(1+2+8+16+32); // all except columns changed
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;
1693  delete scaledMatrix_;
1694  scaledMatrix_=NULL;
1695  if (!matrix_)
1696    createEmptyMatrix();
1697  if (rows)
1698    matrix_->appendRows(number,rows);
1699  setRowScale(NULL);
1700  setColumnScale(NULL);
1701  if (lengthNames_) {
1702    rowNames_.resize(numberRows_);
1703  }
1704}
1705#endif
1706#ifndef SLIM_CLP
1707// Add rows from a build object
1708int
1709ClpModel::addRows(const CoinBuild & buildObject,bool tryPlusMinusOne,bool checkDuplicates)
1710{
1711  CoinAssertHint (buildObject.type()==0,"Looks as if both addRows and addCols being used"); // check correct
1712  int number = buildObject.numberRows();
1713  int numberErrors=0;
1714  if (number) {
1715    CoinBigIndex size=0;
1716    int iRow;
1717    double * lower = new double [number];
1718    double * upper = new double [number];
1719    if ((!matrix_||!matrix_->getNumElements())&&tryPlusMinusOne) {
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;
1744    }
1745    if (!tryPlusMinusOne) {
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_];
1774        CoinZeroN(which,numberColumns_);
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];
1782      CoinZeroN(startPositive,numberColumns_);
1783      CoinZeroN(startNegative,numberColumns_);
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}
1884#endif
1885#ifndef SLIM_NOIO
1886// Add rows from a model object
1887int 
1888ClpModel::addRows( CoinModel & modelObject,bool tryPlusMinusOne,bool checkDuplicates)
1889{
1890  if (modelObject.numberElements()==0)
1891    return 0;
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);
1948      addRows(numberRows2, rowLower, rowUpper,NULL,NULL,NULL);
1949#ifndef SLIM_CLP
1950      if (!tryPlusMinusOne) {
1951#endif
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        }
1971#ifndef SLIM_CLP
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      }
1990#endif
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}
2015#endif
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{
2025  CoinBigIndex starts[2];
2026  starts[0]=0;
2027  starts[1]=numberInColumn;
2028  addColumns(1, &columnLower, &columnUpper,&objective,starts,rows,elements);
2029}
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) {
2040    whatsChanged_ &= ~(1+2+4+64+128+256); // all except rows changed
2041    int numberColumnsNow = numberColumns_;
2042    resize(numberRows_,numberColumnsNow+number);
2043    double * lower = columnLower_+numberColumnsNow;
2044    double * upper = columnUpper_+numberColumnsNow;
2045    double * obj = objective()+numberColumnsNow;
2046    int iColumn;
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      }
2058    }
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;
2084    delete scaledMatrix_;
2085    scaledMatrix_=NULL;
2086    if (!matrix_)
2087      createEmptyMatrix();
2088    setRowScale(NULL);
2089    setColumnScale(NULL);
2090#ifndef CLP_NO_STD
2091    if (lengthNames_) {
2092      columnNames_.resize(numberColumns_);
2093    }
2094#endif
2095    //if (elements)
2096    matrix_->appendMatrix(number,1,columnStarts,rows,elements);
2097  }
2098}
2099// Add columns
2100void 
2101ClpModel::addColumns(int number, const double * columnLower, 
2102                     const double * columnUpper,
2103                     const double * objIn,
2104                     const int * columnStarts, 
2105                     const int * columnLengths, const int * rows,
2106                     const double * elements)
2107{
2108  if (number) {
2109    CoinBigIndex numberElements=0;
2110    int iColumn;
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;
2118    for (iColumn=0;iColumn<number;iColumn++) {
2119      int iStart = columnStarts[iColumn];
2120      int length = columnLengths[iColumn];
2121      CoinMemcpyN(rows+iStart,length,newIndex+numberElements);
2122      CoinMemcpyN(elements+iStart,length,newElements+numberElements);
2123      numberElements += length;
2124      newStarts[iColumn+1]=numberElements;
2125    }
2126    addColumns(number, columnLower, columnUpper,objIn,
2127            newStarts,newIndex,newElements);
2128    delete [] newStarts;
2129    delete [] newIndex;
2130    delete [] newElements;
2131  }
2132}
2133#ifndef CLP_NO_VECTOR
2134void 
2135ClpModel::addColumns(int number, const double * columnLower, 
2136                     const double * columnUpper,
2137                     const double * objIn,
2138                     const CoinPackedVectorBase * const * columns)
2139{
2140  if (!number)
2141    return;
2142  whatsChanged_ &= ~(1+2+4+64+128+256); // all except rows changed
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;
2186  delete scaledMatrix_;
2187  scaledMatrix_=NULL;
2188  if (!matrix_)
2189    createEmptyMatrix();
2190  if (columns)
2191    matrix_->appendCols(number,columns);
2192  setRowScale(NULL);
2193  setColumnScale(NULL);
2194  if (lengthNames_) {
2195    columnNames_.resize(numberColumns_);
2196  }
2197}
2198#endif
2199#ifndef SLIM_CLP
2200// Add columns from a build object
2201int 
2202ClpModel::addColumns(const CoinBuild & buildObject,bool tryPlusMinusOne,bool checkDuplicates)
2203{
2204  CoinAssertHint (buildObject.type()==1,"Looks as if both addRows and addCols being used"); // check correct
2205  int number = buildObject.numberColumns();
2206  int numberErrors=0;
2207  if (number) {
2208    CoinBigIndex size=0;
2209    int maximumLength=0;
2210    double * lower = new double [number];
2211    double * upper = new double [number];
2212    int iColumn;
2213    double * objective = new double [number];
2214    if ((!matrix_||!matrix_->getNumElements())&&tryPlusMinusOne) {
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;
2240    }
2241    if (!tryPlusMinusOne) {
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_];
2272        CoinZeroN(which,numberRows_);
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;
2314        CoinMemcpyN(neg,nNeg,indices+size);
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}
2334#endif
2335#ifndef SLIM_NOIO
2336// Add columns from a model object
2337int 
2338ClpModel::addColumns( CoinModel & modelObject,bool tryPlusMinusOne,bool checkDuplicates)
2339{
2340  if (modelObject.numberElements()==0)
2341    return 0;
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);
2391      addColumns(numberColumns2, columnLower, columnUpper,objective, NULL,NULL,NULL);
2392#ifndef SLIM_CLP
2393      if (!tryPlusMinusOne) {
2394#endif
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        }
2411#ifndef SLIM_CLP
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      }
2425#endif
2426#ifndef CLP_NO_STD
2427      // Do names if wanted
2428      if (modelObject.columnNames()->numberItems()) {
2429        const char *const * columnNames=modelObject.columnNames()->names();
2430        copyColumnNames(columnNames,numberColumns,numberColumns_);
2431      }
2432#endif
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}
2463#endif
2464// chgRowLower
2465void 
2466ClpModel::chgRowLower(const double * rowLower) 
2467{
2468  int numberRows = numberRows_;
2469  int iRow;
2470  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
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{
2488  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
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{
2508  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
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{
2528  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
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{
2548  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
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}
2562// Infeasibility/unbounded ray (NULL returned if none/wrong)
2563double * 
2564ClpModel::infeasibilityRay() const
2565{
2566  double * array = NULL;
2567  if (problemStatus_==1&&!secondaryStatus_) {
2568    array = ClpCopyOfArray(ray_,numberRows_);
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  }
2581  return array;
2582}
2583double * 
2584ClpModel::unboundedRay() const
2585{
2586  double * array = NULL;
2587  if (problemStatus_==2) 
2588    array = ClpCopyOfArray(ray_,numberColumns_);
2589  return array;
2590}
2591void 
2592ClpModel::setMaximumIterations(int value)
2593{
2594  if(value>=0)
2595    intParam_[ClpMaxNumIteration]=value;
2596}
2597void 
2598ClpModel::setMaximumSeconds(double value)
2599{
2600  if(value>=0)
2601    dblParam_[ClpMaxSeconds]=value+CoinCpuTime();
2602  else
2603    dblParam_[ClpMaxSeconds]=-1.0;
2604}
2605// Returns true if hit maximum iterations (or time)
2606bool 
2607ClpModel::hitMaximumIterations() const
2608{
2609  // replaced - compiler error? bool hitMax= (numberIterations_>=maximumIterations());
2610  bool hitMax = (numberIterations_ >= intParam_[ClpMaxNumIteration]);
2611  if (dblParam_[ClpMaxSeconds]>=0.0&&!hitMax) {
2612    hitMax = (CoinCpuTime()>=dblParam_[ClpMaxSeconds]);
2613  }
2614  return hitMax;
2615}
2616// On stopped - sets secondary status
2617void 
2618ClpModel::onStopped()
2619{
2620  if (problemStatus_==3) {
2621    secondaryStatus_=0;
2622    if (CoinCpuTime()>=dblParam_[ClpMaxSeconds]&&dblParam_[ClpMaxSeconds]>=0.0)
2623      secondaryStatus_=9;
2624  }
2625}
2626// Pass in Message handler (not deleted at end)
2627void 
2628ClpModel::passInMessageHandler(CoinMessageHandler * handler)
2629{
2630  if (defaultHandler_)
2631    delete handler_;
2632  defaultHandler_=false;
2633  handler_=handler;
2634}
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}
2655// Set language
2656void 
2657ClpModel::newLanguage(CoinMessages::Language language)
2658{
2659  messages_ = ClpMessage(language);
2660}
2661#ifndef SLIM_NOIO
2662// Read an mps file from the given filename
2663int 
2664ClpModel::readMps(const char *fileName,
2665                  bool keepNames,
2666                  bool ignoreErrors)
2667{
2668  if (!strcmp(fileName,"-")||!strcmp(fileName,"stdin")) {
2669    // stdin
2670  } else {
2671    std::string name=fileName;
2672    bool readable = fileCoinReadable(name);
2673    if (!readable) {
2674      handler_->message(CLP_UNABLE_OPEN,messages_)
2675        <<fileName<<CoinMessageEol;
2676      return -1;
2677    }
2678  }
2679  CoinMpsIO m;
2680  m.passInMessageHandler(handler_);
2681  *m.messagesPointer()=coinMessages();
2682  bool savePrefix =m.messageHandler()->prefix();
2683  m.messageHandler()->setPrefix(handler_->prefix());
2684  double time1 = CoinCpuTime(),time2;
2685  int status=0;
2686  try {
2687    status=m.readMps(fileName,"");
2688  }
2689  catch (CoinError e) {
2690    e.print();
2691    status=-1;
2692  }
2693  m.messageHandler()->setPrefix(savePrefix);
2694  if (!status||(ignoreErrors&&(status>0&&status<100000))) {
2695    loadProblem(*m.getMatrixByCol(),
2696                m.getColLower(),m.getColUpper(),
2697                m.getObjCoefficients(),
2698                m.getRowLower(),m.getRowUpper());
2699    if (m.integerColumns()) {
2700      integerType_ = new char[numberColumns_];
2701      CoinMemcpyN(m.integerColumns(),numberColumns_,integerType_);
2702    } else {
2703      integerType_ = NULL;
2704    }
2705#ifndef SLIM_CLP
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    }
2718#endif
2719#ifndef CLP_NO_STD   
2720    // set problem name
2721    setStrParam(ClpProbName,m.getProblemName());
2722    // do names
2723    if (keepNames) {
2724      unsigned int maxLength=0;
2725      int iRow;
2726      rowNames_ = std::vector<std::string> ();
2727      columnNames_ = std::vector<std::string> ();
2728      rowNames_.reserve(numberRows_);
2729      for (iRow=0;iRow<numberRows_;iRow++) {
2730        const char * name = m.rowName(iRow);
2731        maxLength = CoinMax(maxLength,(unsigned int) strlen(name));
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);
2739        maxLength = CoinMax(maxLength,(unsigned int) strlen(name));
2740        columnNames_.push_back(name);
2741      }
2742      lengthNames_=(int) maxLength;
2743    } else {
2744      lengthNames_=0;
2745    }
2746#endif
2747    setDblParam(ClpObjOffset,m.objectiveOffset());
2748    time2 = CoinCpuTime();
2749    handler_->message(CLP_IMPORT_RESULT,messages_)
2750      <<fileName
2751      <<time2-time1<<CoinMessageEol;
2752  } else {
2753    // errors
2754    handler_->message(CLP_IMPORT_ERRORS,messages_)
2755      <<status<<fileName<<CoinMessageEol;
2756  }
2757
2758  return status;
2759}
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_);
2786  *m.messagesPointer()=coinMessages();
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_];
2799      CoinMemcpyN(m.integerColumns(),numberColumns_,integerType_);
2800    } else {
2801      integerType_ = NULL;
2802    }
2803#ifndef CLP_NO_STD
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    }
2830#endif
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}
2843#endif
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();
2854  const double maxmin = optimizationDirection();
2855
2856  if (problemStatus_ == 0) // optimal
2857    return maxmin > 0 ? (obj < limit) /*minim*/ : (-obj < limit) /*maxim*/;
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();
2875  const double maxmin = optimizationDirection();
2876
2877  if (problemStatus_ == 0) // optimal
2878    return maxmin > 0 ? (obj > limit) /*minim*/ : (-obj > limit) /*maxim*/;
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_];
2891    CoinMemcpyN(information,numberColumns_,integerType_);
2892  } else {
2893    integerType_ = NULL;
2894  }
2895}
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_];
2915    CoinZeroN ( integerType_, numberColumns_);
2916  }
2917#ifndef NDEBUG
2918  if (index<0||index>=numberColumns_) {
2919    indexError(index,"setInteger");
2920  }
2921#endif
2922  integerType_[index]=1;
2923}
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}
2939#ifndef CLP_NO_STD
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}
2948#endif
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_];
2970    CoinMemcpyN(statusArray,(numberRows_+numberColumns_),status_);
2971  } else {
2972    status_=NULL;
2973  }
2974}
2975#ifndef SLIM_CLP
2976// Load up quadratic objective
2977void 
2978ClpModel::loadQuadraticObjective(const int numberColumns, const CoinBigIndex * start,
2979                              const int * column, const double * element)
2980{
2981  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
2982  CoinAssert (numberColumns==numberColumns_);
2983  assert ((dynamic_cast< ClpLinearObjective*>(objective_)));
2984  double offset;
2985  ClpObjective * obj = new ClpQuadraticObjective(objective_->gradient(NULL,NULL,offset,false),
2986                                                 numberColumns,
2987                                                 start,column,element);
2988  delete objective_;
2989  objective_ = obj;
2990
2991}
2992void 
2993ClpModel::loadQuadraticObjective (  const CoinPackedMatrix& matrix)
2994{
2995  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
2996  CoinAssert (matrix.getNumCols()==numberColumns_);
2997  assert ((dynamic_cast< ClpLinearObjective*>(objective_)));
2998  double offset;
2999  ClpQuadraticObjective * obj = 
3000    new ClpQuadraticObjective(objective_->gradient(NULL,NULL,offset,false),
3001                              numberColumns_,
3002                              NULL,NULL,NULL);
3003  delete objective_;
3004  objective_ = obj;
3005  obj->loadQuadraticObjective(matrix);
3006}
3007// Get rid of quadratic objective
3008void 
3009ClpModel::deleteQuadraticObjective()
3010{
3011  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
3012  ClpQuadraticObjective * obj = (dynamic_cast< ClpQuadraticObjective*>(objective_));
3013  if (obj)
3014    obj->deleteQuadraticObjective();
3015}
3016#endif
3017void 
3018ClpModel::setObjective(ClpObjective * objective)
3019{
3020  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
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 
3061ClpModel::replaceMatrix( ClpMatrixBase * matrix,bool deleteCurrent)
3062{
3063  if (deleteCurrent)
3064    delete matrix_;
3065  matrix_=matrix;
3066  whatsChanged_ = 0; // Too big a change
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)
3073  :  specialOptions_(rhs->specialOptions_),
3074  maximumColumns_(-1),
3075  maximumRows_(-1),
3076  maximumInternalColumns_(-1),
3077  maximumInternalRows_(-1),
3078  savedRowScale_(NULL),
3079  savedColumnScale_(NULL)
3080{
3081  defaultHandler_ = rhs->defaultHandler_;
3082  if (defaultHandler_) 
3083    handler_ = new CoinMessageHandler(*rhs->handler_);
3084   else 
3085    handler_ = rhs->handler_;
3086  eventHandler_ = rhs->eventHandler_->clone();
3087  randomNumberGenerator_ = rhs->randomNumberGenerator_;
3088  messages_ = rhs->messages_;
3089  coinMessages_ = rhs->coinMessages_;
3090  maximumColumns_ = -1;
3091  maximumRows_ = -1;
3092  maximumInternalColumns_ = -1;
3093  maximumInternalRows_ = -1;
3094  savedRowScale_ = NULL;
3095  savedColumnScale_ = NULL;
3096  intParam_[ClpMaxNumIteration] = rhs->intParam_[ClpMaxNumIteration];
3097  intParam_[ClpMaxNumIterationHotStart] = 
3098    rhs->intParam_[ClpMaxNumIterationHotStart];
3099  intParam_[ClpNameDiscipline] = rhs->intParam_[ClpNameDiscipline] ;
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];
3107  dblParam_[ClpPresolveTolerance] = rhs->dblParam_[ClpPresolveTolerance];
3108#ifndef CLP_NO_STD
3109  strParam_[ClpProbName] = rhs->strParam_[ClpProbName];
3110#endif
3111  specialOptions_ = rhs->specialOptions_;
3112  optimizationDirection_ = rhs->optimizationDirection_;
3113  objectiveValue_=rhs->objectiveValue_;
3114  smallElement_ = rhs->smallElement_;
3115  objectiveScale_ = rhs->objectiveScale_;
3116  rhsScale_ = rhs->rhsScale_;
3117  numberIterations_ = rhs->numberIterations_;
3118  solveType_ = rhs->solveType_;
3119  whatsChanged_ = 0; // Too big a change
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++;
3128  CoinAssertHint(!numberBad,"Bad row list for subproblem constructor");
3129  numberBad=0;
3130  for (i=0;i<numberColumns;i++)
3131    if (whichColumn[i]<0||whichColumn[i]>=rhs->numberColumns_)
3132      numberBad++;
3133  CoinAssertHint(!numberBad,"Bad Column list for subproblem constructor");
3134  numberRows_ = numberRows;
3135  numberColumns_ = numberColumns;
3136  userPointer_ = rhs->userPointer_;
3137  numberThreads_=0;
3138#ifndef CLP_NO_STD
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++) {
3146      rowNames_.push_back(rhs->rowNames_[whichRow[iRow]]);
3147      maxLength = CoinMax(maxLength,(unsigned int) strlen(rowNames_[iRow].c_str()));
3148    }
3149    int iColumn;
3150    columnNames_.reserve(numberColumns_);
3151    for (iColumn=0;iColumn<numberColumns_;iColumn++) {
3152      columnNames_.push_back(rhs->columnNames_[whichColumn[iColumn]]);
3153      maxLength = CoinMax(maxLength,(unsigned int) strlen(columnNames_[iColumn].c_str()));
3154    }
3155    lengthNames_=(int) maxLength;
3156  } else {
3157    lengthNames_ = 0;
3158    rowNames_ = std::vector<std::string> ();
3159    columnNames_ = std::vector<std::string> ();
3160  }
3161#endif
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);
3195  CoinMemcpyN(rowStatus,numberRows_,status_+numberColumns_);
3196  delete [] rowStatus;
3197  CoinMemcpyN(columnStatus,numberColumns_,status_);
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);
3204  rowScale_ = NULL;
3205  columnScale_ = NULL;
3206  inverseRowScale_ = NULL;
3207  inverseColumnScale_ = NULL;
3208  scalingFlag_ = rhs->scalingFlag_;
3209  rowCopy_=NULL;
3210  scaledMatrix_=NULL;
3211  matrix_=NULL;
3212  if (rhs->matrix_) {
3213    matrix_ = rhs->matrix_->subsetClone(numberRows,whichRow,
3214                                        numberColumns,whichColumn);
3215  }
3216  randomNumberGenerator_.setSeed(1234567);
3217}
3218#ifndef CLP_NO_STD
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++) {
3230    rowNames_.push_back(rowNames[iRow]);
3231    maxLength = CoinMax(maxLength,(unsigned int) strlen(rowNames_[iRow].c_str()));
3232  }
3233  int iColumn;
3234  columnNames_.reserve(numberColumns_);
3235  for (iColumn=0;iColumn<numberColumns_;iColumn++) {
3236    columnNames_.push_back(columnNames[iColumn]);
3237    maxLength = CoinMax(maxLength,(unsigned int) strlen(columnNames_[iColumn].c_str()));
3238  }
3239  lengthNames_=(int) maxLength;
3240}
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}
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];
3326    maxLength = CoinMax(maxLength,(unsigned int) strlen(rowNames_[iRow-first].c_str()));
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];
3342    maxLength = CoinMax(maxLength,(unsigned int) strlen(columnNames_[iColumn-first].c_str()));
3343  }
3344  // May be too big - but we would have to check both rows and columns to be exact
3345  lengthNames_=(int) maxLength;
3346}
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++) {
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    }
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++) {
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    }
3389  }
3390  // May be too big - but we would have to check both rows and columns to be exact
3391  lengthNames_=(int) maxLength;
3392}
3393#endif
3394// Primal objective limit
3395void 
3396ClpModel::setPrimalObjectiveLimit(double value)
3397{
3398  dblParam_[ClpPrimalObjectiveLimit]=value;
3399}
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}
3412// Solve a problem with no elements - return status
3413int ClpModel::emptyProblem(int * infeasNumber, double * infeasSum,bool printMessage)
3414{
3415  secondaryStatus_=6; // so user can see something odd
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_];
3426      CoinZeroN(status_,numberRows_+numberColumns_);
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  }
3520  objectiveValue_ /= (objectiveScale_*rhsScale_);
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}
3531#ifndef SLIM_NOIO
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 *filename, 
3546                   int formatType,int numberAcross,
3547                   double objSense) const 
3548{
3549  matrix_->setDimensions(numberRows_,numberColumns_);
3550 
3551  // Get multiplier for objective function - default 1.0
3552  double * objective = new double[numberColumns_];
3553  CoinMemcpyN(getObjCoefficients(),numberColumns_,objective);
3554  if (objSense*getObjSense()<0.0) {
3555    for (int i = 0; i < numberColumns_; ++i) 
3556      objective [i] = - objective[i];
3557  }
3558  // get names
3559  const char * const * const rowNames = rowNamesAsChar();
3560  const char * const * const columnNames = columnNamesAsChar();
3561  CoinMpsIO writer;
3562  writer.passInMessageHandler(handler_);
3563  *writer.messagesPointer()=coinMessages();
3564  writer.setMpsData(*(matrix_->getPackedMatrix()), COIN_DBL_MAX,
3565                    getColLower(), getColUpper(),
3566                    objective,
3567                    (const char*) 0 /*integrality*/,
3568                    getRowLower(), getRowUpper(),
3569                    columnNames, rowNames);
3570  // Pass in array saying if each variable integer
3571  writer.copyInIntegerInformation(integerInformation());
3572  writer.setObjectiveOffset(objectiveOffset());
3573  delete [] objective;
3574  CoinPackedMatrix * quadratic=NULL;
3575#ifndef SLIM_CLP
3576  // allow for quadratic objective
3577#ifndef NO_RTTI
3578  ClpQuadraticObjective * quadraticObj = (dynamic_cast< ClpQuadraticObjective*>(objective_));
3579#else
3580  ClpQuadraticObjective * quadraticObj = NULL;
3581  if (objective_->type()==2)
3582    quadraticObj = (static_cast< ClpQuadraticObjective*>(objective_));
3583#endif
3584  if (quadraticObj) 
3585    quadratic = quadraticObj->quadraticObjective();
3586#endif
3587  int returnCode = writer.writeMps(filename, 0 /* do not gzip it*/, formatType, numberAcross,
3588                         quadratic);
3589  if (rowNames) {
3590    deleteNamesAsChar(rowNames, numberRows_+1);
3591    deleteNamesAsChar(columnNames, numberColumns_);
3592  }
3593  return returnCode;
3594}
3595#ifndef CLP_NO_STD
3596// Create row names as char **
3597const char * const * 
3598ClpModel::rowNamesAsChar() const
3599{
3600  char ** rowNames = NULL;
3601  if (lengthNames()) {
3602    rowNames = new char * [numberRows_+1];
3603    int numberNames = rowNames_.size();
3604    numberNames = CoinMin(numberRows_,numberNames);
3605    int iRow;
3606    for (iRow=0;iRow<numberNames;iRow++) {
3607      rowNames[iRow] = 
3608        strdup(rowName(iRow).c_str());
3609#ifdef STRIPBLANKS
3610      char * xx = rowNames[iRow];
3611      int i;
3612      int length = strlen(xx);
3613      int n=0;
3614      for (i=0;i<length;i++) {
3615        if (xx[i]!=' ')
3616          xx[n++]=xx[i];
3617      }
3618      xx[n]='\0';
3619#endif
3620    }
3621    char name[9];
3622    for ( ;iRow<numberRows_;iRow++) {
3623      sprintf(name,"R%7.7d",iRow);
3624      rowNames[iRow]=strdup(name);
3625    }
3626    rowNames[numberRows_] = strdup("OBJROW");
3627  }
3628  return reinterpret_cast<const char * const *>(rowNames);
3629}
3630// Create column names as char **
3631const char * const * 
3632ClpModel::columnNamesAsChar() const
3633{
3634  char ** columnNames = NULL;
3635  if (lengthNames()) {
3636    columnNames = new char * [numberColumns_];
3637    int numberNames = columnNames_.size();
3638    numberNames = CoinMin(numberColumns_,numberNames);
3639    int iColumn;
3640    for (iColumn=0;iColumn<numberNames;iColumn++) {
3641      columnNames[iColumn] = 
3642        strdup(columnName(iColumn).c_str());
3643#ifdef STRIPBLANKS
3644      char * xx = columnNames[iColumn];
3645      int i;
3646      int length = strlen(xx);
3647      int n=0;
3648      for (i=0;i<length;i++) {
3649        if (xx[i]!=' ')
3650          xx[n++]=xx[i];
3651      }
3652      xx[n]='\0';
3653#endif
3654    }
3655    char name[9];
3656    for ( ;iColumn<numberColumns_;iColumn++) {
3657      sprintf(name,"C%7.7d",iColumn);
3658      columnNames[iColumn]=strdup(name);
3659    }
3660  }
3661  return /*reinterpret_cast<const char * const *>*/(columnNames);
3662}
3663// Delete char * version of names
3664void 
3665ClpModel::deleteNamesAsChar(const char * const * names,int number) const
3666{
3667  for (int i=0;i<number;i++) {
3668    free(const_cast<char *>(names[i]));
3669  }
3670  delete [] const_cast<char **>(names);
3671}
3672#endif
3673#endif
3674// Pass in Event handler (cloned and deleted at end)
3675void 
3676ClpModel::passInEventHandler(const ClpEventHandler * eventHandler)
3677{
3678  delete eventHandler_;
3679  eventHandler_ = eventHandler->clone();
3680}
3681// Sets or unsets scaling, 0 -off, 1 on, 2 dynamic(later)
3682void 
3683ClpModel::scaling(int mode)
3684{
3685  // If mode changes then we treat as new matrix (need new row copy)
3686  if (mode!=scalingFlag_)
3687    whatsChanged_ &= ~(2+4+8);
3688  if (mode>0&&mode<5) {
3689    scalingFlag_=mode;
3690  } else if (!mode) {
3691    scalingFlag_=0;
3692    setRowScale(NULL);
3693    setColumnScale(NULL);
3694  }
3695}
3696void 
3697ClpModel::times(double scalar,
3698                  const double * x, double * y) const
3699{
3700  if (!scaledMatrix_||!rowScale_) {
3701    if (rowScale_)
3702      matrix_->times(scalar,x,y,rowScale_,columnScale_);
3703    else
3704      matrix_->times(scalar,x,y);
3705  } else {
3706    scaledMatrix_->times(scalar,x,y);
3707  }
3708}
3709void 
3710ClpModel::transposeTimes(double scalar,
3711                           const double * x, double * y) const 
3712{
3713  if (!scaledMatrix_||!rowScale_) {
3714    if (rowScale_)
3715      matrix_->transposeTimes(scalar,x,y,rowScale_,columnScale_);
3716    else
3717      matrix_->transposeTimes(scalar,x,y);
3718  } else {
3719    scaledMatrix_->transposeTimes(scalar,x,y);
3720  }
3721}
3722// Does much of scaling
3723void 
3724ClpModel::gutsOfScaling()
3725{
3726  int i;
3727  if (rowObjective_) {
3728    for (i=0;i<numberRows_;i++) 
3729      rowObjective_[i] /= rowScale_[i];
3730  }
3731  for (i=0;i<numberRows_;i++) {
3732    double multiplier = rowScale_[i];
3733    double inverseMultiplier = 1.0/multiplier;
3734    rowActivity_[i] *= multiplier;
3735    dual_[i] *= inverseMultiplier;
3736    if (rowLower_[i]>-1.0e30)
3737      rowLower_[i] *= multiplier;
3738    else
3739      rowLower_[i] = -COIN_DBL_MAX;
3740    if (rowUpper_[i]<1.0e30)
3741      rowUpper_[i] *= multiplier;
3742    else
3743      rowUpper_[i] = COIN_DBL_MAX;
3744  }
3745  for (i=0;i<numberColumns_;i++) {
3746    double multiplier = 1.0/columnScale_[i];
3747    columnActivity_[i] *= multiplier;
3748    reducedCost_[i] *= columnScale_[i];
3749    if (columnLower_[i]>-1.0e30)
3750      columnLower_[i] *= multiplier;
3751    else
3752      columnLower_[i] = -COIN_DBL_MAX;
3753    if (columnUpper_[i]<1.0e30)
3754      columnUpper_[i] *= multiplier;
3755    else
3756      columnUpper_[i] = COIN_DBL_MAX;
3757   
3758  }
3759  //now replace matrix
3760  //and objective
3761  matrix_->reallyScale(rowScale_,columnScale_);
3762  objective_->reallyScale(columnScale_);
3763}
3764/* If we constructed a "really" scaled model then this reverses the operation.
3765      Quantities may not be exactly as they were before due to rounding errors */
3766void 
3767ClpModel::unscale()
3768{
3769  if (rowScale_) {
3770    int i;
3771    // reverse scaling
3772    for (i=0;i<numberRows_;i++) 
3773      rowScale_[i] = 1.0/rowScale_[i];
3774    for (i=0;i<numberColumns_;i++) 
3775      columnScale_[i] = 1.0/columnScale_[i];
3776    gutsOfScaling();
3777  }
3778 
3779  scalingFlag_=0;
3780  setRowScale(NULL);
3781  setColumnScale(NULL);
3782}
3783void 
3784ClpModel::setSpecialOptions(unsigned int value)
3785{ 
3786  specialOptions_=value;
3787}
3788/* This creates a coinModel object
3789 */
3790CoinModel * 
3791ClpModel::createCoinModel() const
3792{
3793  CoinModel * coinModel = new CoinModel();
3794  CoinPackedMatrix matrixByRow;
3795  matrixByRow.reverseOrderedCopyOf(*matrix());
3796  coinModel->setObjectiveOffset(objectiveOffset());
3797  coinModel->setProblemName(problemName().c_str());
3798
3799  // Build by row from scratch
3800  const double * element = matrixByRow.getElements();
3801  const int * column = matrixByRow.getIndices();
3802  const CoinBigIndex * rowStart = matrixByRow.getVectorStarts();
3803  const int * rowLength = matrixByRow.getVectorLengths();
3804  int i;
3805  for (i=0;i<numberRows_;i++) {
3806    coinModel->addRow(rowLength[i],column+rowStart[i],
3807                      element+rowStart[i],rowLower_[i],rowUpper_[i]);
3808  }
3809  // Now do column part
3810  const double * objective = this->objective();
3811  for (i=0;i<numberColumns_;i++) {
3812    coinModel->setColumnBounds(i,columnLower_[i],columnUpper_[i]);
3813    coinModel->setColumnObjective(i,objective[i]);
3814  }
3815  for ( i=0;i<numberColumns_;i++) {
3816    if (isInteger(i))
3817      coinModel->setColumnIsInteger(i,true);
3818  }
3819  // do names
3820  for (i=0;i<numberRows_;i++) {
3821    char temp[30];
3822    strcpy(temp,rowName(i).c_str());
3823    int length = strlen(temp);
3824    for (int j=0;j<length;j++) {
3825      if (temp[j]=='-')
3826        temp[j]='_';
3827    }
3828    coinModel->setRowName(i,temp);
3829  }
3830  for (i=0;i<numberColumns_;i++) {
3831    char temp[30];
3832    strcpy(temp,columnName(i).c_str());
3833    int length = strlen(temp);
3834    for (int j=0;j<length;j++) {
3835      if (temp[j]=='-')
3836        temp[j]='_';
3837    }
3838    coinModel->setColumnName(i,temp);
3839  }
3840  ClpQuadraticObjective * obj = (dynamic_cast< ClpQuadraticObjective*>(objective_));
3841  if (obj) {
3842    const CoinPackedMatrix * quadObj = obj->quadraticObjective();
3843    // add in quadratic
3844    const double * element = quadObj->getElements();
3845    const int * row = quadObj->getIndices();
3846    const CoinBigIndex * columnStart = quadObj->getVectorStarts();
3847    const int * columnLength = quadObj->getVectorLengths();
3848    for (i=0;i<numberColumns_;i++) {
3849      int nels = columnLength[i];
3850      if (nels) {
3851        CoinBigIndex start = columnStart[i];
3852        double constant = coinModel->getColumnObjective(i);
3853        char temp[100000];
3854        char temp2[30];
3855        sprintf(temp,"%g",constant);
3856        for (CoinBigIndex k=start;k<start+nels;k++) {
3857          int kColumn = row[k];
3858          double value = element[k];
3859#if 1
3860          // ampl gives twice with assumed 0.5
3861          if (kColumn<i)
3862            continue;
3863          else if (kColumn==i)
3864            value *= 0.5;
3865#endif
3866          if (value==1.0) 
3867            sprintf(temp2,"+%s",coinModel->getColumnName(kColumn));
3868          else if (value==-1.0)
3869            sprintf(temp2,"-%s",coinModel->getColumnName(kColumn));
3870          else if (value>0.0)
3871            sprintf(temp2,"+%g*%s",value,coinModel->getColumnName(kColumn));
3872          else 
3873            sprintf(temp2,"%g*%s",value,coinModel->getColumnName(kColumn));
3874          strcat(temp,temp2);
3875          assert (strlen(temp)<100000);
3876        }
3877        coinModel->setObjective(i,temp);
3878        if (logLevel()>2)
3879          printf("el for objective column %s is %s\n",coinModel->getColumnName(i),temp);
3880      }
3881    }
3882  }
3883  return coinModel;
3884}
3885// Start or reset using maximumRows_ and Columns_
3886void 
3887ClpModel::startPermanentArrays()
3888{
3889  printf("startperm a %d rows, %d maximum rows\n",
3890         numberRows_,maximumRows_);
3891  if ((specialOptions_&65536)!=0) {
3892    if (numberRows_>maximumRows_||numberColumns_>maximumColumns_) {
3893      if (numberRows_>maximumRows_)
3894        if (maximumRows_>0)
3895          maximumRows_ = numberRows_+10+numberRows_/100;
3896        else
3897          maximumRows_ = numberRows_;
3898      if (numberColumns_>maximumColumns_) 
3899        if (maximumColumns_>0)
3900          maximumColumns_ = numberColumns_+10+numberColumns_/100;
3901        else
3902          maximumColumns_ = numberColumns_;
3903      // need to make sure numberRows_ OK and size of matrices
3904      resize(maximumRows_,maximumColumns_);
3905      printf("startperm b %d rows, %d maximum rows\n",
3906             numberRows_,maximumRows_);
3907    } else {
3908      return;
3909    }
3910  } else {
3911    specialOptions_ |= 65536;
3912    maximumRows_ = numberRows_;
3913    maximumColumns_ = numberColumns_;
3914    baseMatrix_ = *matrix();
3915    baseMatrix_.cleanMatrix();
3916    baseRowCopy_.setExtraGap(0.0);
3917    baseRowCopy_.setExtraMajor(0.0);
3918    baseRowCopy_.reverseOrderedCopyOf(baseMatrix_);
3919    printf("startperm c %d rows, %d maximum rows\n",
3920             numberRows_,maximumRows_);
3921  }
3922}
3923// Stop using maximumRows_ and Columns_
3924void 
3925ClpModel::stopPermanentArrays()
3926{
3927  specialOptions_ &= ~65536;
3928  maximumRows_=-1;
3929  maximumColumns_=-1;
3930  if (rowScale_!=savedRowScale_) {
3931    delete [] savedRowScale_;
3932    delete [] savedColumnScale_;
3933  }
3934  savedRowScale_ = NULL;
3935  savedColumnScale_ = NULL;
3936}
3937/* Find a network subset.
3938   rotate array should be numberRows.  On output
3939   -1 not in network
3940   0 in network as is
3941   1 in network with signs swapped
3942  Returns number of network rows (positive if exact network, negative if needs extra row)
3943  From Gulpinar, Gutin, Maros and Mitra
3944*/
3945int 
3946ClpModel::findNetwork(char * rotate,double fractionNeeded)
3947{
3948  int * mapping = new int [numberRows_];
3949  // Get column copy
3950  CoinPackedMatrix * columnCopy = matrix();
3951  // Get a row copy in standard format
3952  CoinPackedMatrix * copy = new CoinPackedMatrix();
3953  copy->reverseOrderedCopyOf(*columnCopy);
3954  // make sure ordered and no gaps
3955  copy->cleanMatrix();
3956  // get matrix data pointers
3957  const int * columnIn = copy->getIndices();
3958  const CoinBigIndex * rowStartIn = copy->getVectorStarts();
3959  const int * rowLength = copy->getVectorLengths(); 
3960  const double * elementByRowIn = copy->getElements();
3961  int iRow,iColumn;
3962  int numberEligible=0;
3963  int numberIn=0;
3964  int numberElements=0;
3965  for (iRow=0;iRow<numberRows_;iRow++) {
3966    bool possible=true;
3967    mapping[iRow]=-1;
3968    rotate[iRow]=-1;
3969    for (CoinBigIndex j=rowStartIn[iRow];j<rowStartIn[iRow]+rowLength[iRow];j++) {
3970      //int iColumn = column[j];
3971      double value = elementByRowIn[j];
3972      if (fabs(value)!=1.0) {
3973        possible=false;
3974        break;
3975      }
3976    }
3977    if (rowLength[iRow]&&possible) {
3978      mapping[iRow]=numberEligible;
3979      numberEligible++;
3980      numberElements+=rowLength[iRow];
3981    }
3982  }
3983  if (numberEligible<fractionNeeded*numberRows_) {
3984    delete [] mapping;
3985    return 0;
3986  }
3987  // create arrays
3988  int * eligible = new int [numberRows_];
3989  int * column = new int [numberElements];
3990  CoinBigIndex * rowStart = new CoinBigIndex [numberEligible+1];
3991  char * elementByRow = new char [numberElements];
3992  numberEligible=0;
3993  numberElements=0;
3994  rowStart[0]=0;
3995  for (iRow=0;iRow<numberRows_;iRow++) {
3996    if (mapping[iRow]<0)
3997      continue;
3998    assert (numberEligible==mapping[iRow]);
3999    rotate[numberEligible]=0;
4000    for (CoinBigIndex j=rowStartIn[iRow];j<rowStartIn[iRow]+rowLength[iRow];j++) {
4001      column[numberElements] = columnIn[j];
4002      double value = elementByRowIn[j];
4003      if (value==1.0) 
4004        elementByRow[numberElements++]=1;
4005      else
4006        elementByRow[numberElements++]=-1;
4007    }
4008    numberEligible++;
4009    rowStart[numberEligible]=numberElements;
4010  }
4011  // get rid of copy to save space
4012  delete copy;
4013  const int * rowIn = columnCopy->getIndices();
4014  const CoinBigIndex * columnStartIn = columnCopy->getVectorStarts();
4015  const int * columnLengthIn = columnCopy->getVectorLengths(); 
4016  const double * elementByColumnIn = columnCopy->getElements();
4017  int * columnLength = new int [numberColumns_];
4018  // May just be that is a network - worth checking
4019  bool isNetworkAlready=true;
4020  bool trueNetwork=true;
4021  for (iColumn=0;iColumn<numberColumns_;iColumn++) {
4022    double product =1.0;
4023    int n=0;
4024    for (CoinBigIndex j=columnStartIn[iColumn];j<columnStartIn[iColumn]+columnLengthIn[iColumn];j++) {
4025      iRow = mapping[rowIn[j]];
4026      if (iRow>=0) {
4027        n++;
4028        product *= elementByColumnIn[j];
4029      }
4030    }
4031    if (n>=2) {
4032      if (product!=-1.0||n>2) 
4033        isNetworkAlready=false;
4034    } else if (n==1) {
4035      trueNetwork=false;
4036    }
4037    columnLength[iColumn]=n;
4038  }
4039  if (!isNetworkAlready) {
4040    // For sorting
4041    double * count = new double [numberRows_];
4042    int * which = new int [numberRows_];
4043    int numberLast=-1;
4044      // Count for columns
4045    char * columnCount = new char[numberColumns_];
4046    memset(columnCount,0,numberColumns_);
4047    char * currentColumnCount = new char[numberColumns_];
4048    // Now do main loop
4049    while (numberIn>numberLast) {
4050      numberLast=numberIn;
4051      int numberLeft = 0;
4052      for (iRow=0;iRow<numberEligible;iRow++) {
4053        if (rotate[iRow]==0) {
4054          which[numberLeft]=iRow;
4055          int merit=0;
4056          bool OK=true;
4057          bool reflectionOK=true;
4058          for (CoinBigIndex j=rowStart[iRow];j<rowStart[iRow+1];j++) {
4059            iColumn = column[j];
4060            int iCount=columnCount[iColumn];
4061            int absCount=CoinAbs(iCount);
4062            if (absCount<2) {
4063              merit = CoinMax(columnLength[iColumn]-absCount-1,merit);
4064              if (elementByRow[j]==iCount)
4065                OK=false;
4066              else if (elementByRow[j]==-iCount)
4067                reflectionOK=false;
4068            } else {
4069              merit =-2;
4070              break;
4071            }
4072          }
4073          if (merit>-2&&(OK||reflectionOK)) {
4074            assert (!OK||!reflectionOK||!numberIn);
4075            //if (!numberLast) merit=1;
4076            count[numberLeft++]=(rowStart[iRow+1]-rowStart[iRow]-1)*((double)merit);
4077            if (OK)
4078              rotate[iRow]=0;
4079            else
4080              rotate[iRow]=1;
4081          } else {
4082            // no good
4083            rotate[iRow]=-1;
4084          }
4085        }
4086      }
4087      CoinSort_2(count,count+numberLeft,which);
4088      // Get G
4089      memset(currentColumnCount,0,numberColumns_);
4090      for (iRow=0;iRow<numberLeft;iRow++) {
4091        int jRow = which[iRow];
4092        bool possible=true;
4093        for (int i=0;i<numberIn;i++) {
4094          for (CoinBigIndex j=rowStart[jRow];j<rowStart[jRow+1];j++) {
4095            if (currentColumnCount[column[j]]) {
4096              possible=false;
4097              break;
4098            }
4099          }
4100        }
4101        if (possible) {
4102          rotate[jRow]+=2;
4103          eligible[numberIn++]=jRow;
4104          char multiplier = (rotate[jRow]==2) ? 1 : -1;
4105          for (CoinBigIndex j=rowStart[jRow];j<rowStart[jRow+1];j++) {
4106            iColumn = column[j];
4107            currentColumnCount[iColumn]++;
4108            int iCount=columnCount[iColumn];
4109            int absCount=CoinAbs(iCount);
4110            if (!absCount) {
4111              columnCount[iColumn]=elementByRow[j]*multiplier;
4112            } else {
4113              columnCount[iColumn]=2;
4114            }
4115          }
4116        }
4117      }
4118    }
4119#ifndef NDEBUG
4120    for (iRow=0;iRow<numberIn;iRow++) {
4121      int kRow = eligible[iRow];
4122      assert (rotate[kRow]>=2);
4123    }
4124#endif
4125    trueNetwork=true;
4126    for (iColumn=0;iColumn<numberColumns_;iColumn++) {
4127      if (CoinAbs(columnCount[iColumn])==1) {
4128        trueNetwork=false;
4129        break;
4130      }
4131    }
4132    delete [] currentColumnCount;
4133    delete [] columnCount;
4134    delete [] which;
4135    delete [] count;
4136  } else {
4137    numberIn=numberEligible;
4138    for (iRow=0;iRow<numberRows_;iRow++) {
4139      int kRow = mapping[iRow];
4140      if (kRow>=0) {
4141        rotate[kRow]=2;
4142      }
4143    }
4144  }
4145  if (!trueNetwork)
4146    numberIn= - numberIn;
4147  delete [] column;
4148  delete [] rowStart;
4149  delete [] elementByRow;
4150  delete [] columnLength;
4151  // redo rotate
4152  char * rotate2 = CoinCopyOfArray(rotate,numberEligible);
4153  for (iRow=0;iRow<numberRows_;iRow++) {
4154    int kRow = mapping[iRow];
4155    if (kRow>=0) {
4156      int iState=rotate2[kRow];
4157      if (iState>1)
4158        iState -=2;
4159      else
4160        iState = -1;
4161      rotate[iRow]=iState;
4162    } else {
4163      rotate[iRow]=-1;
4164    }
4165  }
4166  delete [] rotate2;
4167  delete [] eligible;
4168  delete [] mapping;
4169  return numberIn;
4170}
4171//#############################################################################
4172// Constructors / Destructor / Assignment
4173//#############################################################################
4174
4175//-------------------------------------------------------------------
4176// Default Constructor
4177//-------------------------------------------------------------------
4178ClpDataSave::ClpDataSave () 
4179{
4180  dualBound_ = 0.0;
4181  infeasibilityCost_ = 0.0;
4182  sparseThreshold_ = 0;
4183  pivotTolerance_=0.0;
4184  acceptablePivot_ = 0.0;
4185  objectiveScale_ = 1.0;
4186  perturbation_ = 0;
4187  forceFactorization_=-1;
4188  scalingFlag_=0;
4189}
4190
4191//-------------------------------------------------------------------
4192// Copy constructor
4193//-------------------------------------------------------------------
4194ClpDataSave::ClpDataSave (const ClpDataSave & rhs) 
4195{ 
4196  dualBound_ = rhs.dualBound_;
4197  infeasibilityCost_ = rhs.infeasibilityCost_;
4198  pivotTolerance_ = rhs.pivotTolerance_;
4199  acceptablePivot_ = rhs.acceptablePivot_;
4200  objectiveScale_ = rhs.objectiveScale_;
4201  sparseThreshold_ = rhs.sparseThreshold_;
4202  perturbation_ = rhs.perturbation_;
4203  forceFactorization_=rhs.forceFactorization_;
4204  scalingFlag_=rhs.scalingFlag_;
4205}
4206
4207//-------------------------------------------------------------------
4208// Destructor
4209//-------------------------------------------------------------------
4210ClpDataSave::~ClpDataSave ()
4211{
4212}
4213
4214//----------------------------------------------------------------
4215// Assignment operator
4216//-------------------------------------------------------------------
4217ClpDataSave &
4218ClpDataSave::operator=(const ClpDataSave& rhs)
4219{
4220  if (this != &rhs) {
4221    dualBound_ = rhs.dualBound_;
4222    infeasibilityCost_ = rhs.infeasibilityCost_;
4223    pivotTolerance_ = rhs.pivotTolerance_;
4224    acceptablePivot_ = rhs.acceptablePivot_;
4225    objectiveScale_ = rhs.objectiveScale_;
4226    sparseThreshold_ = rhs.sparseThreshold_;
4227    perturbation_ = rhs.perturbation_;
4228    forceFactorization_=rhs.forceFactorization_;
4229    scalingFlag_=rhs.scalingFlag_;
4230  }
4231  return *this;
4232}
4233// Create C++ lines to get to current state
4234void 
4235ClpModel::generateCpp( FILE * fp)
4236{
4237  // Stuff that can't be done easily
4238  if (!lengthNames_) {
4239    // no names
4240    fprintf(fp,"  clpModel->dropNames();\n");
4241  }
4242  ClpModel defaultModel;
4243  ClpModel * other = &defaultModel;
4244  int iValue1, iValue2;
4245  double dValue1, dValue2;
4246  iValue1 = this->maximumIterations();
4247  iValue2 = other->maximumIterations();
4248  fprintf(fp,"%d  int save_maximumIterations = clpModel->maximumIterations();\n",iValue1==iValue2 ? 2 : 1);
4249  fprintf(fp,"%d  clpModel->setMaximumIterations(%d);\n",iValue1==iValue2 ? 4 : 3,iValue1);
4250  fprintf(fp,"%d  clpModel->setMaximumIterations(save_maximumIterations);\n",iValue1==iValue2 ? 7 : 6);
4251  dValue1 = this->primalTolerance();
4252  dValue2 = other->primalTolerance();
4253  fprintf(fp,"%d  double save_primalTolerance = clpModel->primalTolerance();\n",dValue1==dValue2 ? 2 : 1);
4254  fprintf(fp,"%d  clpModel->setPrimalTolerance(%g);\n",dValue1==dValue2 ? 4 : 3,dValue1);
4255  fprintf(fp,"%d  clpModel->setPrimalTolerance(save_primalTolerance);\n",dValue1==dValue2 ? 7 : 6);
4256  dValue1 = this->dualTolerance();
4257  dValue2 = other->dualTolerance();
4258  fprintf(fp,"%d  double save_dualTolerance = clpModel->dualTolerance();\n",dValue1==dValue2 ? 2 : 1);
4259  fprintf(fp,"%d  clpModel->setDualTolerance(%g);\n",dValue1==dValue2 ? 4 : 3,dValue1);
4260  fprintf(fp,"%d  clpModel->setDualTolerance(save_dualTolerance);\n",dValue1==dValue2 ? 7 : 6);
4261  iValue1 = this->numberIterations();
4262  iValue2 = other->numberIterations();
4263  fprintf(fp,"%d  int save_numberIterations = clpModel->numberIterations();\n",iValue1==iValue2 ? 2 : 1);
4264  fprintf(fp,"%d  clpModel->setNumberIterations(%d);\n",iValue1==iValue2 ? 4 : 3,iValue1);
4265  fprintf(fp,"%d  clpModel->setNumberIterations(save_numberIterations);\n",iValue1==iValue2 ? 7 : 6);
4266  dValue1 = this->maximumSeconds();
4267  dValue2 = other->maximumSeconds();
4268  fprintf(fp,"%d  double save_maximumSeconds = clpModel->maximumSeconds();\n",dValue1==dValue2 ? 2 : 1);
4269  fprintf(fp,"%d  clpModel->setMaximumSeconds(%g);\n",dValue1==dValue2 ? 4 : 3,dValue1);
4270  fprintf(fp,"%d  clpModel->setMaximumSeconds(save_maximumSeconds);\n",dValue1==dValue2 ? 7 : 6);
4271  dValue1 = this->optimizationDirection();
4272  dValue2 = other->optimizationDirection();
4273  fprintf(fp,"%d  double save_optimizationDirection = clpModel->optimizationDirection();\n",dValue1==dValue2 ? 2 : 1);
4274  fprintf(fp,"%d  clpModel->setOptimizationDirection(%g);\n",dValue1==dValue2 ? 4 : 3,dValue1);
4275  fprintf(fp,"%d  clpModel->setOptimizationDirection(save_optimizationDirection);\n",dValue1==dValue2 ? 7 : 6);
4276  dValue1 = this->objectiveScale();
4277  dValue2 = other->objectiveScale();
4278  fprintf(fp,"%d  double save_objectiveScale = clpModel->objectiveScale();\n",dValue1==dValue2 ? 2 : 1);
4279  fprintf(fp,"%d  clpModel->setObjectiveScale(%g);\n",dValue1==dValue2 ? 4 : 3,dValue1);
4280  fprintf(fp,"%d  clpModel->setObjectiveScale(save_objectiveScale);\n",dValue1==dValue2 ? 7 : 6);
4281  dValue1 = this->rhsScale();
4282  dValue2 = other->rhsScale();
4283  fprintf(fp,"%d  double save_rhsScale = clpModel->rhsScale();\n",dValue1==dValue2 ? 2 : 1);
4284  fprintf(fp,"%d  clpModel->setRhsScale(%g);\n",dValue1==dValue2 ? 4 : 3,dValue1);
4285  fprintf(fp,"%d  clpModel->setRhsScale(save_rhsScale);\n",dValue1==dValue2 ? 7 : 6);
4286  iValue1 = this->scalingFlag();
4287  iValue2 = other->scalingFlag();
4288  fprintf(fp,"%d  int save_scalingFlag = clpModel->scalingFlag();\n",iValue1==iValue2 ? 2 : 1);
4289  fprintf(fp,"%d  clpModel->scaling(%d);\n",iValue1==iValue2 ? 4 : 3,iValue1);
4290  fprintf(fp,"%d  clpModel->scaling(save_scalingFlag);\n",iValue1==iValue2 ? 7 : 6);
4291  dValue1 = this->getSmallElementValue();
4292  dValue2 = other->getSmallElementValue();
4293  fprintf(fp,"%d  double save_getSmallElementValue = clpModel->getSmallElementValue();\n",dValue1==dValue2 ? 2 : 1);
4294  fprintf(fp,"%d  clpModel->setSmallElementValue(%g);\n",dValue1==dValue2 ? 4 : 3,dValue1);
4295  fprintf(fp,"%d  clpModel->setSmallElementValue(save_getSmallElementValue);\n",dValue1==dValue2 ? 7 : 6);
4296  iValue1 = this->logLevel();
4297  iValue2 = other->logLevel();
4298  fprintf(fp,"%d  int save_logLevel = clpModel->logLevel();\n",iValue1==iValue2 ? 2 : 1);
4299  fprintf(fp,"%d  clpModel->setLogLevel(%d);\n",iValue1==iValue2 ? 4 : 3,iValue1);
4300  fprintf(fp,"%d  clpModel->setLogLevel(save_logLevel);\n",iValue1==iValue2 ? 7 : 6);
4301}
Note: See TracBrowser for help on using the repository browser.