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

Last change on this file since 1231 was 1231, checked in by ladanyi, 11 years ago

switch from strdup to CoinStrdup? (same as changeset 1230 in stable/1.8)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 128.0 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    //#define SWAP_SIGN
2570#ifdef SWAP_SIGN
2571    // swap signs to be consistent with norm
2572    for (int i=0;i<numberRows_;i++)
2573      ray_[i] = -ray_[i];
2574#endif
2575#if 0
2576    // clean up
2577    double largest=1.0e-30;
2578    double smallest=COIN_DBL_MAX;
2579    int i;
2580    for (i=0;i<numberRows_;i++) {
2581      double value = fabs(array[i]);
2582      smallest = CoinMin(smallest,value);
2583      largest = CoinMax(largest,value);
2584    }
2585#endif
2586  }
2587  return array;
2588}
2589double * 
2590ClpModel::unboundedRay() const
2591{
2592  double * array = NULL;
2593  if (problemStatus_==2) 
2594    array = ClpCopyOfArray(ray_,numberColumns_);
2595  return array;
2596}
2597void 
2598ClpModel::setMaximumIterations(int value)
2599{
2600  if(value>=0)
2601    intParam_[ClpMaxNumIteration]=value;
2602}
2603void 
2604ClpModel::setMaximumSeconds(double value)
2605{
2606  if(value>=0)
2607    dblParam_[ClpMaxSeconds]=value+CoinCpuTime();
2608  else
2609    dblParam_[ClpMaxSeconds]=-1.0;
2610}
2611// Returns true if hit maximum iterations (or time)
2612bool 
2613ClpModel::hitMaximumIterations() const
2614{
2615  // replaced - compiler error? bool hitMax= (numberIterations_>=maximumIterations());
2616  bool hitMax = (numberIterations_ >= intParam_[ClpMaxNumIteration]);
2617  if (dblParam_[ClpMaxSeconds]>=0.0&&!hitMax) {
2618    hitMax = (CoinCpuTime()>=dblParam_[ClpMaxSeconds]);
2619  }
2620  return hitMax;
2621}
2622// On stopped - sets secondary status
2623void 
2624ClpModel::onStopped()
2625{
2626  if (problemStatus_==3) {
2627    secondaryStatus_=0;
2628    if (CoinCpuTime()>=dblParam_[ClpMaxSeconds]&&dblParam_[ClpMaxSeconds]>=0.0)
2629      secondaryStatus_=9;
2630  }
2631}
2632// Pass in Message handler (not deleted at end)
2633void 
2634ClpModel::passInMessageHandler(CoinMessageHandler * handler)
2635{
2636  if (defaultHandler_)
2637    delete handler_;
2638  defaultHandler_=false;
2639  handler_=handler;
2640}
2641// Pass in Message handler (not deleted at end) and return current
2642CoinMessageHandler *
2643ClpModel::pushMessageHandler(CoinMessageHandler * handler,
2644                             bool & oldDefault)
2645{
2646  CoinMessageHandler * returnValue = handler_;
2647  oldDefault = defaultHandler_;
2648  defaultHandler_=false;
2649  handler_=handler;
2650  return returnValue;
2651}
2652// back to previous message handler
2653void
2654ClpModel::popMessageHandler(CoinMessageHandler * oldHandler,bool oldDefault)
2655{
2656  if (defaultHandler_)
2657    delete handler_;
2658  defaultHandler_=oldDefault;
2659  handler_=oldHandler;
2660}
2661// Set language
2662void 
2663ClpModel::newLanguage(CoinMessages::Language language)
2664{
2665  messages_ = ClpMessage(language);
2666}
2667#ifndef SLIM_NOIO
2668// Read an mps file from the given filename
2669int 
2670ClpModel::readMps(const char *fileName,
2671                  bool keepNames,
2672                  bool ignoreErrors)
2673{
2674  if (!strcmp(fileName,"-")||!strcmp(fileName,"stdin")) {
2675    // stdin
2676  } else {
2677    std::string name=fileName;
2678    bool readable = fileCoinReadable(name);
2679    if (!readable) {
2680      handler_->message(CLP_UNABLE_OPEN,messages_)
2681        <<fileName<<CoinMessageEol;
2682      return -1;
2683    }
2684  }
2685  CoinMpsIO m;
2686  m.passInMessageHandler(handler_);
2687  *m.messagesPointer()=coinMessages();
2688  bool savePrefix =m.messageHandler()->prefix();
2689  m.messageHandler()->setPrefix(handler_->prefix());
2690  double time1 = CoinCpuTime(),time2;
2691  int status=0;
2692  try {
2693    status=m.readMps(fileName,"");
2694  }
2695  catch (CoinError e) {
2696    e.print();
2697    status=-1;
2698  }
2699  m.messageHandler()->setPrefix(savePrefix);
2700  if (!status||(ignoreErrors&&(status>0&&status<100000))) {
2701    loadProblem(*m.getMatrixByCol(),
2702                m.getColLower(),m.getColUpper(),
2703                m.getObjCoefficients(),
2704                m.getRowLower(),m.getRowUpper());
2705    if (m.integerColumns()) {
2706      integerType_ = new char[numberColumns_];
2707      CoinMemcpyN(m.integerColumns(),numberColumns_,integerType_);
2708    } else {
2709      integerType_ = NULL;
2710    }
2711#ifndef SLIM_CLP
2712    // get quadratic part
2713    if (m.reader()->whichSection (  ) == COIN_QUAD_SECTION ) {
2714      int * start=NULL;
2715      int * column = NULL;
2716      double * element = NULL;
2717      status=m.readQuadraticMps(NULL,start,column,element,2);
2718      if (!status||ignoreErrors) 
2719        loadQuadraticObjective(numberColumns_,start,column,element);
2720      delete [] start;
2721      delete [] column;
2722      delete [] element;
2723    }
2724#endif
2725#ifndef CLP_NO_STD   
2726    // set problem name
2727    setStrParam(ClpProbName,m.getProblemName());
2728    // do names
2729    if (keepNames) {
2730      unsigned int maxLength=0;
2731      int iRow;
2732      rowNames_ = std::vector<std::string> ();
2733      columnNames_ = std::vector<std::string> ();
2734      rowNames_.reserve(numberRows_);
2735      for (iRow=0;iRow<numberRows_;iRow++) {
2736        const char * name = m.rowName(iRow);
2737        maxLength = CoinMax(maxLength,(unsigned int) strlen(name));
2738          rowNames_.push_back(name);
2739      }
2740     
2741      int iColumn;
2742      columnNames_.reserve(numberColumns_);
2743      for (iColumn=0;iColumn<numberColumns_;iColumn++) {
2744        const char * name = m.columnName(iColumn);
2745        maxLength = CoinMax(maxLength,(unsigned int) strlen(name));
2746        columnNames_.push_back(name);
2747      }
2748      lengthNames_=(int) maxLength;
2749    } else {
2750      lengthNames_=0;
2751    }
2752#endif
2753    setDblParam(ClpObjOffset,m.objectiveOffset());
2754    time2 = CoinCpuTime();
2755    handler_->message(CLP_IMPORT_RESULT,messages_)
2756      <<fileName
2757      <<time2-time1<<CoinMessageEol;
2758  } else {
2759    // errors
2760    handler_->message(CLP_IMPORT_ERRORS,messages_)
2761      <<status<<fileName<<CoinMessageEol;
2762  }
2763
2764  return status;
2765}
2766// Read GMPL files from the given filenames
2767int 
2768ClpModel::readGMPL(const char *fileName,const char * dataName,
2769                   bool keepNames)
2770{
2771  FILE *fp=fopen(fileName,"r");
2772  if (fp) {
2773    // can open - lets go for it
2774    fclose(fp);
2775    if (dataName) {
2776      fp=fopen(dataName,"r");
2777      if (fp) {
2778        fclose(fp);
2779      } else {
2780        handler_->message(CLP_UNABLE_OPEN,messages_)
2781          <<dataName<<CoinMessageEol;
2782        return -1;
2783      }
2784    }
2785  } else {
2786    handler_->message(CLP_UNABLE_OPEN,messages_)
2787      <<fileName<<CoinMessageEol;
2788    return -1;
2789  }
2790  CoinMpsIO m;
2791  m.passInMessageHandler(handler_);
2792  *m.messagesPointer()=coinMessages();
2793  bool savePrefix =m.messageHandler()->prefix();
2794  m.messageHandler()->setPrefix(handler_->prefix());
2795  double time1 = CoinCpuTime(),time2;
2796  int status=m.readGMPL(fileName,dataName,keepNames);
2797  m.messageHandler()->setPrefix(savePrefix);
2798  if (!status) {
2799    loadProblem(*m.getMatrixByCol(),
2800                m.getColLower(),m.getColUpper(),
2801                m.getObjCoefficients(),
2802                m.getRowLower(),m.getRowUpper());
2803    if (m.integerColumns()) {
2804      integerType_ = new char[numberColumns_];
2805      CoinMemcpyN(m.integerColumns(),numberColumns_,integerType_);
2806    } else {
2807      integerType_ = NULL;
2808    }
2809#ifndef CLP_NO_STD
2810    // set problem name
2811    setStrParam(ClpProbName,m.getProblemName());
2812    // do names
2813    if (keepNames) {
2814      unsigned int maxLength=0;
2815      int iRow;
2816      rowNames_ = std::vector<std::string> ();
2817      columnNames_ = std::vector<std::string> ();
2818      rowNames_.reserve(numberRows_);
2819      for (iRow=0;iRow<numberRows_;iRow++) {
2820        const char * name = m.rowName(iRow);
2821        maxLength = CoinMax(maxLength,(unsigned int) strlen(name));
2822          rowNames_.push_back(name);
2823      }
2824     
2825      int iColumn;
2826      columnNames_.reserve(numberColumns_);
2827      for (iColumn=0;iColumn<numberColumns_;iColumn++) {
2828        const char * name = m.columnName(iColumn);
2829        maxLength = CoinMax(maxLength,(unsigned int) strlen(name));
2830        columnNames_.push_back(name);
2831      }
2832      lengthNames_=(int) maxLength;
2833    } else {
2834      lengthNames_=0;
2835    }
2836#endif
2837    setDblParam(ClpObjOffset,m.objectiveOffset());
2838    time2 = CoinCpuTime();
2839    handler_->message(CLP_IMPORT_RESULT,messages_)
2840      <<fileName
2841      <<time2-time1<<CoinMessageEol;
2842  } else {
2843    // errors
2844    handler_->message(CLP_IMPORT_ERRORS,messages_)
2845      <<status<<fileName<<CoinMessageEol;
2846  }
2847  return status;
2848}
2849#endif
2850bool ClpModel::isPrimalObjectiveLimitReached() const
2851{
2852  double limit = 0.0;
2853  getDblParam(ClpPrimalObjectiveLimit, limit);
2854  if (limit > 1e30) {
2855    // was not ever set
2856    return false;
2857  }
2858   
2859  const double obj = objectiveValue();
2860  const double maxmin = optimizationDirection();
2861
2862  if (problemStatus_ == 0) // optimal
2863    return maxmin > 0 ? (obj < limit) /*minim*/ : (-obj < limit) /*maxim*/;
2864  else if (problemStatus_==2)
2865    return true;
2866  else
2867    return false;
2868}
2869
2870bool ClpModel::isDualObjectiveLimitReached() const
2871{
2872
2873  double limit = 0.0;
2874  getDblParam(ClpDualObjectiveLimit, limit);
2875  if (limit > 1e30) {
2876    // was not ever set
2877    return false;
2878  }
2879   
2880  const double obj = objectiveValue();
2881  const double maxmin = optimizationDirection();
2882
2883  if (problemStatus_ == 0) // optimal
2884    return maxmin > 0 ? (obj > limit) /*minim*/ : (-obj > limit) /*maxim*/;
2885  else if (problemStatus_==1)
2886    return true;
2887  else
2888    return false;
2889
2890}
2891void 
2892ClpModel::copyInIntegerInformation(const char * information)
2893{
2894  delete [] integerType_;
2895  if (information) {
2896    integerType_ = new char[numberColumns_];
2897    CoinMemcpyN(information,numberColumns_,integerType_);
2898  } else {
2899    integerType_ = NULL;
2900  }
2901}
2902void
2903ClpModel::setContinuous(int index)
2904{
2905
2906  if (integerType_) {
2907#ifndef NDEBUG
2908    if (index<0||index>=numberColumns_) {
2909      indexError(index,"setContinuous");
2910    }
2911#endif
2912    integerType_[index]=0;
2913  }
2914}
2915//-----------------------------------------------------------------------------
2916void
2917ClpModel::setInteger(int index)
2918{
2919  if (!integerType_) {
2920    integerType_ = new char[numberColumns_];
2921    CoinZeroN ( integerType_, numberColumns_);
2922  }
2923#ifndef NDEBUG
2924  if (index<0||index>=numberColumns_) {
2925    indexError(index,"setInteger");
2926  }
2927#endif
2928  integerType_[index]=1;
2929}
2930/* Return true if the index-th variable is an integer variable */
2931bool 
2932ClpModel::isInteger(int index) const
2933{
2934  if (!integerType_) {
2935    return false;
2936  } else {
2937#ifndef NDEBUG
2938    if (index<0||index>=numberColumns_) {
2939      indexError(index,"isInteger");
2940    }
2941#endif
2942    return (integerType_[index]!=0);
2943  }
2944}
2945#ifndef CLP_NO_STD
2946// Drops names - makes lengthnames 0 and names empty
2947void 
2948ClpModel::dropNames()
2949{
2950  lengthNames_=0;
2951  rowNames_ = std::vector<std::string> ();
2952  columnNames_ = std::vector<std::string> ();
2953}
2954#endif
2955// Drop integer informations
2956void 
2957ClpModel::deleteIntegerInformation()
2958{
2959  delete [] integerType_;
2960  integerType_ = NULL;
2961}
2962/* Return copy of status array (char[numberRows+numberColumns]),
2963   use delete [] */
2964unsigned char * 
2965ClpModel::statusCopy() const
2966{
2967  return ClpCopyOfArray(status_,numberRows_+numberColumns_);
2968}
2969// Copy in status vector
2970void 
2971ClpModel::copyinStatus(const unsigned char * statusArray)
2972{
2973  delete [] status_;
2974  if (statusArray) {
2975    status_ = new unsigned char [numberRows_+numberColumns_];
2976    CoinMemcpyN(statusArray,(numberRows_+numberColumns_),status_);
2977  } else {
2978    status_=NULL;
2979  }
2980}
2981#ifndef SLIM_CLP
2982// Load up quadratic objective
2983void 
2984ClpModel::loadQuadraticObjective(const int numberColumns, const CoinBigIndex * start,
2985                              const int * column, const double * element)
2986{
2987  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
2988  CoinAssert (numberColumns==numberColumns_);
2989  assert ((dynamic_cast< ClpLinearObjective*>(objective_)));
2990  double offset;
2991  ClpObjective * obj = new ClpQuadraticObjective(objective_->gradient(NULL,NULL,offset,false),
2992                                                 numberColumns,
2993                                                 start,column,element);
2994  delete objective_;
2995  objective_ = obj;
2996
2997}
2998void 
2999ClpModel::loadQuadraticObjective (  const CoinPackedMatrix& matrix)
3000{
3001  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
3002  CoinAssert (matrix.getNumCols()==numberColumns_);
3003  assert ((dynamic_cast< ClpLinearObjective*>(objective_)));
3004  double offset;
3005  ClpQuadraticObjective * obj = 
3006    new ClpQuadraticObjective(objective_->gradient(NULL,NULL,offset,false),
3007                              numberColumns_,
3008                              NULL,NULL,NULL);
3009  delete objective_;
3010  objective_ = obj;
3011  obj->loadQuadraticObjective(matrix);
3012}
3013// Get rid of quadratic objective
3014void 
3015ClpModel::deleteQuadraticObjective()
3016{
3017  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
3018  ClpQuadraticObjective * obj = (dynamic_cast< ClpQuadraticObjective*>(objective_));
3019  if (obj)
3020    obj->deleteQuadraticObjective();
3021}
3022#endif
3023void 
3024ClpModel::setObjective(ClpObjective * objective)
3025{
3026  whatsChanged_ = 0; // Use ClpSimplex stuff to keep
3027  delete objective_;
3028  objective_=objective->clone();
3029}
3030// Returns resized array and updates size
3031double * whichDouble(double * array , int number, const int * which)
3032{
3033  double * newArray=NULL;
3034  if (array&&number) {
3035    int i ;
3036    newArray = new double[number];
3037    for (i=0;i<number;i++) 
3038      newArray[i]=array[which[i]];
3039  }
3040  return newArray;
3041}
3042char * whichChar(char * array , int number, const int * which)
3043{
3044  char * newArray=NULL;
3045  if (array&&number) {
3046    int i ;
3047    newArray = new char[number];
3048    for (i=0;i<number;i++) 
3049      newArray[i]=array[which[i]];
3050  }
3051  return newArray;
3052}
3053unsigned char * whichUnsignedChar(unsigned char * array , 
3054                                  int number, const int * which)
3055{
3056  unsigned char * newArray=NULL;
3057  if (array&&number) {
3058    int i ;
3059    newArray = new unsigned char[number];
3060    for (i=0;i<number;i++) 
3061      newArray[i]=array[which[i]];
3062  }
3063  return newArray;
3064}
3065// Replace Clp Matrix (current is not deleted)
3066void 
3067ClpModel::replaceMatrix( ClpMatrixBase * matrix,bool deleteCurrent)
3068{
3069  if (deleteCurrent)
3070    delete matrix_;
3071  matrix_=matrix;
3072  whatsChanged_ = 0; // Too big a change
3073}
3074// Subproblem constructor
3075ClpModel::ClpModel ( const ClpModel * rhs,
3076                     int numberRows, const int * whichRow,
3077                     int numberColumns, const int * whichColumn,
3078                     bool dropNames, bool dropIntegers)
3079  :  specialOptions_(rhs->specialOptions_),
3080  maximumColumns_(-1),
3081  maximumRows_(-1),
3082  maximumInternalColumns_(-1),
3083  maximumInternalRows_(-1),
3084  savedRowScale_(NULL),
3085  savedColumnScale_(NULL)
3086{
3087  defaultHandler_ = rhs->defaultHandler_;
3088  if (defaultHandler_) 
3089    handler_ = new CoinMessageHandler(*rhs->handler_);
3090   else 
3091    handler_ = rhs->handler_;
3092  eventHandler_ = rhs->eventHandler_->clone();
3093  randomNumberGenerator_ = rhs->randomNumberGenerator_;
3094  messages_ = rhs->messages_;
3095  coinMessages_ = rhs->coinMessages_;
3096  maximumColumns_ = -1;
3097  maximumRows_ = -1;
3098  maximumInternalColumns_ = -1;
3099  maximumInternalRows_ = -1;
3100  savedRowScale_ = NULL;
3101  savedColumnScale_ = NULL;
3102  intParam_[ClpMaxNumIteration] = rhs->intParam_[ClpMaxNumIteration];
3103  intParam_[ClpMaxNumIterationHotStart] = 
3104    rhs->intParam_[ClpMaxNumIterationHotStart];
3105  intParam_[ClpNameDiscipline] = rhs->intParam_[ClpNameDiscipline] ;
3106
3107  dblParam_[ClpDualObjectiveLimit] = rhs->dblParam_[ClpDualObjectiveLimit];
3108  dblParam_[ClpPrimalObjectiveLimit] = rhs->dblParam_[ClpPrimalObjectiveLimit];
3109  dblParam_[ClpDualTolerance] = rhs->dblParam_[ClpDualTolerance];
3110  dblParam_[ClpPrimalTolerance] = rhs->dblParam_[ClpPrimalTolerance];
3111  dblParam_[ClpObjOffset] = rhs->dblParam_[ClpObjOffset];
3112  dblParam_[ClpMaxSeconds] = rhs->dblParam_[ClpMaxSeconds];
3113  dblParam_[ClpPresolveTolerance] = rhs->dblParam_[ClpPresolveTolerance];
3114#ifndef CLP_NO_STD
3115  strParam_[ClpProbName] = rhs->strParam_[ClpProbName];
3116#endif
3117  specialOptions_ = rhs->specialOptions_;
3118  optimizationDirection_ = rhs->optimizationDirection_;
3119  objectiveValue_=rhs->objectiveValue_;
3120  smallElement_ = rhs->smallElement_;
3121  objectiveScale_ = rhs->objectiveScale_;
3122  rhsScale_ = rhs->rhsScale_;
3123  numberIterations_ = rhs->numberIterations_;
3124  solveType_ = rhs->solveType_;
3125  whatsChanged_ = 0; // Too big a change
3126  problemStatus_ = rhs->problemStatus_;
3127  secondaryStatus_ = rhs->secondaryStatus_;
3128  // check valid lists
3129  int numberBad=0;
3130  int i;
3131  for (i=0;i<numberRows;i++)
3132    if (whichRow[i]<0||whichRow[i]>=rhs->numberRows_)
3133      numberBad++;
3134  CoinAssertHint(!numberBad,"Bad row list for subproblem constructor");
3135  numberBad=0;
3136  for (i=0;i<numberColumns;i++)
3137    if (whichColumn[i]<0||whichColumn[i]>=rhs->numberColumns_)
3138      numberBad++;
3139  CoinAssertHint(!numberBad,"Bad Column list for subproblem constructor");
3140  numberRows_ = numberRows;
3141  numberColumns_ = numberColumns;
3142  userPointer_ = rhs->userPointer_;
3143  numberThreads_=0;
3144#ifndef CLP_NO_STD
3145  if (!dropNames) {
3146    unsigned int maxLength=0;
3147    int iRow;
3148    rowNames_ = std::vector<std::string> ();
3149    columnNames_ = std::vector<std::string> ();
3150    rowNames_.reserve(numberRows_);
3151    for (iRow=0;iRow<numberRows_;iRow++) {
3152      rowNames_.push_back(rhs->rowNames_[whichRow[iRow]]);
3153      maxLength = CoinMax(maxLength,(unsigned int) strlen(rowNames_[iRow].c_str()));
3154    }
3155    int iColumn;
3156    columnNames_.reserve(numberColumns_);
3157    for (iColumn=0;iColumn<numberColumns_;iColumn++) {
3158      columnNames_.push_back(rhs->columnNames_[whichColumn[iColumn]]);
3159      maxLength = CoinMax(maxLength,(unsigned int) strlen(columnNames_[iColumn].c_str()));
3160    }
3161    lengthNames_=(int) maxLength;
3162  } else {
3163    lengthNames_ = 0;
3164    rowNames_ = std::vector<std::string> ();
3165    columnNames_ = std::vector<std::string> ();
3166  }
3167#endif
3168  if (rhs->integerType_&&!dropIntegers) {
3169    integerType_ = whichChar(rhs->integerType_,numberColumns,whichColumn);
3170  } else {
3171    integerType_ = NULL;
3172  }
3173  if (rhs->rowActivity_) {
3174    rowActivity_=whichDouble(rhs->rowActivity_,numberRows,whichRow);
3175    dual_=whichDouble(rhs->dual_,numberRows,whichRow);
3176    columnActivity_=whichDouble(rhs->columnActivity_,numberColumns,
3177                                whichColumn);
3178    reducedCost_=whichDouble(rhs->reducedCost_,numberColumns,
3179                                whichColumn);
3180  } else {
3181    rowActivity_=NULL;
3182    columnActivity_=NULL;
3183    dual_=NULL;
3184    reducedCost_=NULL;
3185  }
3186  rowLower_=whichDouble(rhs->rowLower_,numberRows,whichRow);
3187  rowUpper_=whichDouble(rhs->rowUpper_,numberRows,whichRow);
3188  columnLower_=whichDouble(rhs->columnLower_,numberColumns,whichColumn);
3189  columnUpper_=whichDouble(rhs->columnUpper_,numberColumns,whichColumn);
3190  if (rhs->objective_)
3191    objective_  = rhs->objective_->subsetClone(numberColumns,whichColumn);
3192  else
3193    objective_ = NULL;
3194  rowObjective_=whichDouble(rhs->rowObjective_,numberRows,whichRow);
3195  // status has to be done in two stages
3196  status_ = new unsigned char[numberColumns_+numberRows_];
3197  unsigned char * rowStatus = whichUnsignedChar(rhs->status_+rhs->numberColumns_,
3198                                                numberRows_,whichRow);
3199  unsigned char * columnStatus = whichUnsignedChar(rhs->status_,
3200                                                numberColumns_,whichColumn);
3201  CoinMemcpyN(rowStatus,numberRows_,status_+numberColumns_);
3202  delete [] rowStatus;
3203  CoinMemcpyN(columnStatus,numberColumns_,status_);
3204  delete [] columnStatus;
3205  ray_ = NULL;
3206  if (problemStatus_==1&&!secondaryStatus_)
3207    ray_ = whichDouble (rhs->ray_,numberRows,whichRow);
3208  else if (problemStatus_==2)
3209    ray_ = whichDouble (rhs->ray_,numberColumns,whichColumn);
3210  rowScale_ = NULL;
3211  columnScale_ = NULL;
3212  inverseRowScale_ = NULL;
3213  inverseColumnScale_ = NULL;
3214  scalingFlag_ = rhs->scalingFlag_;
3215  rowCopy_=NULL;
3216  scaledMatrix_=NULL;
3217  matrix_=NULL;
3218  if (rhs->matrix_) {
3219    matrix_ = rhs->matrix_->subsetClone(numberRows,whichRow,
3220                                        numberColumns,whichColumn);
3221  }
3222  randomNumberGenerator_.setSeed(1234567);
3223}
3224#ifndef CLP_NO_STD
3225// Copies in names
3226void 
3227ClpModel::copyNames(std::vector<std::string> & rowNames,
3228                 std::vector<std::string> & columnNames)
3229{
3230  unsigned int maxLength=0;
3231  int iRow;
3232  rowNames_ = std::vector<std::string> ();
3233  columnNames_ = std::vector<std::string> ();
3234  rowNames_.reserve(numberRows_);
3235  for (iRow=0;iRow<numberRows_;iRow++) {
3236    rowNames_.push_back(rowNames[iRow]);
3237    maxLength = CoinMax(maxLength,(unsigned int) strlen(rowNames_[iRow].c_str()));
3238  }
3239  int iColumn;
3240  columnNames_.reserve(numberColumns_);
3241  for (iColumn=0;iColumn<numberColumns_;iColumn++) {
3242    columnNames_.push_back(columnNames[iColumn]);
3243    maxLength = CoinMax(maxLength,(unsigned int) strlen(columnNames_[iColumn].c_str()));
3244  }
3245  lengthNames_=(int) maxLength;
3246}
3247// Return name or Rnnnnnnn
3248std::string
3249ClpModel::getRowName(int iRow) const
3250{
3251#ifndef NDEBUG
3252  if (iRow<0||iRow>=numberRows_) {
3253    indexError(iRow,"getRowName");
3254  }
3255#endif
3256  int size = rowNames_.size();
3257  if (size>iRow) {
3258    return rowNames_[iRow];
3259  } else {
3260    char name[9];
3261    sprintf(name,"R%7.7d",iRow);
3262    std::string rowName(name);
3263    return rowName;
3264  }
3265}
3266// Set row name
3267void
3268ClpModel::setRowName(int iRow, std::string &name)
3269{
3270#ifndef NDEBUG
3271  if (iRow<0||iRow>=numberRows_) {
3272    indexError(iRow,"setRowName");
3273  }
3274#endif
3275  unsigned int maxLength=lengthNames_;
3276  int size = rowNames_.size();
3277  if (size<=iRow)
3278    rowNames_.resize(iRow+1);
3279  rowNames_[iRow]= name;
3280  maxLength = CoinMax(maxLength,(unsigned int) strlen(name.c_str()));
3281  // May be too big - but we would have to check both rows and columns to be exact
3282  lengthNames_=(int) maxLength;
3283}
3284// Return name or Cnnnnnnn
3285std::string
3286ClpModel::getColumnName(int iColumn) const
3287{
3288#ifndef NDEBUG
3289  if (iColumn<0||iColumn>=numberColumns_) {
3290    indexError(iColumn,"getColumnName");
3291  }
3292#endif
3293  int size = columnNames_.size();
3294  if (size>iColumn) {
3295    return columnNames_[iColumn];
3296  } else {
3297    char name[9];
3298    sprintf(name,"C%7.7d",iColumn);
3299    std::string columnName(name);
3300    return columnName;
3301  }
3302}
3303// Set column name
3304void
3305ClpModel::setColumnName(int iColumn, std::string &name)
3306{
3307#ifndef NDEBUG
3308  if (iColumn<0||iColumn>=numberColumns_) {
3309    indexError(iColumn,"setColumnName");
3310  }
3311#endif
3312  unsigned int maxLength=lengthNames_;
3313  int size = columnNames_.size();
3314  if (size<=iColumn)
3315    columnNames_.resize(iColumn+1);
3316  columnNames_[iColumn]= name;
3317  maxLength = CoinMax(maxLength,(unsigned int) strlen(name.c_str()));
3318  // May be too big - but we would have to check both columns and columns to be exact
3319  lengthNames_=(int) maxLength;
3320}
3321// Copies in Row names - modifies names first .. last-1
3322void 
3323ClpModel::copyRowNames(const std::vector<std::string> & rowNames, int first, int last)
3324{
3325  unsigned int maxLength=lengthNames_;
3326  int size = rowNames_.size();
3327  if (size!=numberRows_)
3328    rowNames_.resize(numberRows_);
3329  int iRow;
3330  for (iRow=first; iRow<last;iRow++) {
3331    rowNames_[iRow]= rowNames[iRow-first];
3332    maxLength = CoinMax(maxLength,(unsigned int) strlen(rowNames_[iRow-first].c_str()));
3333  }
3334  // May be too big - but we would have to check both rows and columns to be exact
3335  lengthNames_=(int) maxLength;
3336}
3337// Copies in Column names - modifies names first .. last-1
3338void 
3339ClpModel::copyColumnNames(const std::vector<std::string> & columnNames, int first, int last)
3340{
3341  unsigned int maxLength=lengthNames_;
3342  int size = columnNames_.size();
3343  if (size!=numberColumns_)
3344    columnNames_.resize(numberColumns_);
3345  int iColumn;
3346  for (iColumn=first; iColumn<last;iColumn++) {
3347    columnNames_[iColumn]= columnNames[iColumn-first];
3348    maxLength = CoinMax(maxLength,(unsigned int) strlen(columnNames_[iColumn-first].c_str()));
3349  }
3350  // May be too big - but we would have to check both rows and columns to be exact
3351  lengthNames_=(int) maxLength;
3352}
3353// Copies in Row names - modifies names first .. last-1
3354void 
3355ClpModel::copyRowNames(const char * const * rowNames, int first, int last)
3356{
3357  unsigned int maxLength=lengthNames_;
3358  int size = rowNames_.size();
3359  if (size!=numberRows_)
3360    rowNames_.resize(numberRows_);
3361  int iRow;
3362  for (iRow=first; iRow<last;iRow++) {
3363    if (rowNames[iRow-first]&&strlen(rowNames[iRow-first])) {
3364      rowNames_[iRow]= rowNames[iRow-first];
3365      maxLength = CoinMax(maxLength,(unsigned int) strlen(rowNames[iRow-first]));
3366    } else {
3367      maxLength = CoinMax(maxLength,(unsigned int) 8);
3368      char name[9];
3369      sprintf(name,"R%7.7d",iRow);
3370      rowNames_[iRow]=name;
3371    }
3372  }
3373  // May be too big - but we would have to check both rows and columns to be exact
3374  lengthNames_=(int) maxLength;
3375}
3376// Copies in Column names - modifies names first .. last-1
3377void 
3378ClpModel::copyColumnNames(const char * const * columnNames, int first, int last)
3379{
3380  unsigned int maxLength=lengthNames_;
3381  int size = columnNames_.size();
3382  if (size!=numberColumns_)
3383    columnNames_.resize(numberColumns_);
3384  int iColumn;
3385  for (iColumn=first; iColumn<last;iColumn++) {
3386    if (columnNames[iColumn-first]&&strlen(columnNames[iColumn-first])) {
3387      columnNames_[iColumn]= columnNames[iColumn-first];
3388      maxLength = CoinMax(maxLength,(unsigned int) strlen(columnNames[iColumn-first]));
3389    } else {
3390      maxLength = CoinMax(maxLength,(unsigned int) 8);
3391      char name[9];
3392      sprintf(name,"C%7.7d",iColumn);
3393      columnNames_[iColumn]=name;
3394    }
3395  }
3396  // May be too big - but we would have to check both rows and columns to be exact
3397  lengthNames_=(int) maxLength;
3398}
3399#endif
3400// Primal objective limit
3401void 
3402ClpModel::setPrimalObjectiveLimit(double value)
3403{
3404  dblParam_[ClpPrimalObjectiveLimit]=value;
3405}
3406// Dual objective limit
3407void 
3408ClpModel::setDualObjectiveLimit(double value)
3409{
3410  dblParam_[ClpDualObjectiveLimit]=value;
3411}
3412// Objective offset
3413void 
3414ClpModel::setObjectiveOffset(double value)
3415{
3416  dblParam_[ClpObjOffset]=value;
3417}
3418// Solve a problem with no elements - return status
3419int ClpModel::emptyProblem(int * infeasNumber, double * infeasSum,bool printMessage)
3420{
3421  secondaryStatus_=6; // so user can see something odd
3422  if (printMessage)
3423    handler_->message(CLP_EMPTY_PROBLEM,messages_)
3424      <<numberRows_
3425      <<numberColumns_
3426      <<0
3427      <<CoinMessageEol;
3428  int returnCode=0;
3429  if (numberRows_||numberColumns_) {
3430    if (!status_) {
3431      status_ = new unsigned char[numberRows_+numberColumns_];
3432      CoinZeroN(status_,numberRows_+numberColumns_);
3433    }
3434  }
3435  // status is set directly (as can be used by Interior methods)
3436  // check feasible
3437  int numberPrimalInfeasibilities=0;
3438  double sumPrimalInfeasibilities=0.0;
3439  int numberDualInfeasibilities=0;
3440  double sumDualInfeasibilities=0.0;
3441  if (numberRows_) {
3442    for (int i=0;i<numberRows_;i++) {
3443      dual_[i]=0.0;
3444      if (rowLower_[i]<=rowUpper_[i]) {
3445        if (rowLower_[i]>-1.0e30||rowUpper_[i]<1.0e30) {
3446          if (rowLower_[i]<=0.0&&rowUpper_[i]>=0.0) {
3447            if (fabs(rowLower_[i])<fabs(rowUpper_[i]))
3448              rowActivity_[i]=rowLower_[i];
3449            else
3450              rowActivity_[i]=rowUpper_[i];
3451          } else {
3452            rowActivity_[i]=0.0;
3453            numberPrimalInfeasibilities++;
3454            sumPrimalInfeasibilities += CoinMin(rowLower_[i],-rowUpper_[i]);
3455            returnCode=1;
3456          }
3457        } else {
3458          rowActivity_[i]=0.0;
3459        }
3460      } else {
3461        rowActivity_[i]=0.0;
3462        numberPrimalInfeasibilities++;
3463        sumPrimalInfeasibilities += rowLower_[i]-rowUpper_[i];
3464        returnCode=1;
3465      }
3466      status_[i+numberColumns_]=1;
3467    }
3468  }
3469  objectiveValue_=0.0;
3470  if (numberColumns_) {
3471    const double * cost = objective();
3472    for (int i=0;i<numberColumns_;i++) {
3473      reducedCost_[i]=cost[i];
3474      double objValue = cost[i]*optimizationDirection_;
3475      if (columnLower_[i]<=columnUpper_[i]) {
3476        if (columnLower_[i]>-1.0e30||columnUpper_[i]<1.0e30) {
3477          if (!objValue) {
3478            if (fabs(columnLower_[i])<fabs(columnUpper_[i])) {
3479              columnActivity_[i]=columnLower_[i];
3480              status_[i]=3;
3481            } else {
3482              columnActivity_[i]=columnUpper_[i];
3483              status_[i]=2;
3484            }
3485          } else if (objValue>0.0) {
3486            if (columnLower_[i]>-1.0e30) {
3487              columnActivity_[i]=columnLower_[i];
3488              status_[i]=3;
3489            } else {
3490              columnActivity_[i]=columnUpper_[i];
3491              status_[i]=2;
3492              numberDualInfeasibilities++;;
3493              sumDualInfeasibilities += fabs(objValue);
3494              returnCode |= 2;
3495            }
3496            objectiveValue_ += columnActivity_[i]*objValue;
3497          } else {
3498            if (columnUpper_[i]<1.0e30) {
3499              columnActivity_[i]=columnUpper_[i];
3500              status_[i]=2;
3501            } else {
3502              columnActivity_[i]=columnLower_[i];
3503              status_[i]=3;
3504              numberDualInfeasibilities++;;
3505              sumDualInfeasibilities += fabs(objValue);
3506              returnCode |= 2;
3507            }
3508            objectiveValue_ += columnActivity_[i]*objValue;
3509          }
3510        } else {
3511          columnActivity_[i]=0.0;
3512          if (objValue) {
3513            numberDualInfeasibilities++;;
3514            sumDualInfeasibilities += fabs(objValue);
3515            returnCode |= 2;
3516          }
3517          status_[i]=0;
3518        }
3519      } else {
3520        if (fabs(columnLower_[i])<fabs(columnUpper_[i])) {
3521          columnActivity_[i]=columnLower_[i];
3522          status_[i]=3;
3523        } else {
3524          columnActivity_[i]=columnUpper_[i];
3525          status_[i]=2;
3526        }
3527        numberPrimalInfeasibilities++;
3528        sumPrimalInfeasibilities += columnLower_[i]-columnUpper_[i];
3529        returnCode |= 1;
3530      }
3531    }
3532  }
3533  objectiveValue_ /= (objectiveScale_*rhsScale_);
3534  if (infeasNumber) {
3535    infeasNumber[0]=numberDualInfeasibilities;
3536    infeasSum[0]=sumDualInfeasibilities;
3537    infeasNumber[1]=numberPrimalInfeasibilities;
3538    infeasSum[1]=sumPrimalInfeasibilities;
3539  }
3540  if (returnCode==3) 
3541    returnCode=4;
3542  return returnCode;
3543}
3544#ifndef SLIM_NOIO
3545/* Write the problem in MPS format to the specified file.
3546   
3547Row and column names may be null.
3548formatType is
3549<ul>
3550<li> 0 - normal
3551<li> 1 - extra accuracy
3552<li> 2 - IEEE hex (later)
3553</ul>
3554
3555Returns non-zero on I/O error
3556*/
3557int 
3558ClpModel::writeMps(const char *filename, 
3559                   int formatType,int numberAcross,
3560                   double objSense) const 
3561{
3562  matrix_->setDimensions(numberRows_,numberColumns_);
3563 
3564  // Get multiplier for objective function - default 1.0
3565  double * objective = new double[numberColumns_];
3566  CoinMemcpyN(getObjCoefficients(),numberColumns_,objective);
3567  if (objSense*getObjSense()<0.0) {
3568    for (int i = 0; i < numberColumns_; ++i) 
3569      objective [i] = - objective[i];
3570  }
3571  // get names
3572  const char * const * const rowNames = rowNamesAsChar();
3573  const char * const * const columnNames = columnNamesAsChar();
3574  CoinMpsIO writer;
3575  writer.passInMessageHandler(handler_);
3576  *writer.messagesPointer()=coinMessages();
3577  writer.setMpsData(*(matrix_->getPackedMatrix()), COIN_DBL_MAX,
3578                    getColLower(), getColUpper(),
3579                    objective,
3580                    (const char*) 0 /*integrality*/,
3581                    getRowLower(), getRowUpper(),
3582                    columnNames, rowNames);
3583  // Pass in array saying if each variable integer
3584  writer.copyInIntegerInformation(integerInformation());
3585  writer.setObjectiveOffset(objectiveOffset());
3586  delete [] objective;
3587  CoinPackedMatrix * quadratic=NULL;
3588#ifndef SLIM_CLP
3589  // allow for quadratic objective
3590#ifndef NO_RTTI
3591  ClpQuadraticObjective * quadraticObj = (dynamic_cast< ClpQuadraticObjective*>(objective_));
3592#else
3593  ClpQuadraticObjective * quadraticObj = NULL;
3594  if (objective_->type()==2)
3595    quadraticObj = (static_cast< ClpQuadraticObjective*>(objective_));
3596#endif
3597  if (quadraticObj) 
3598    quadratic = quadraticObj->quadraticObjective();
3599#endif
3600  int returnCode = writer.writeMps(filename, 0 /* do not gzip it*/, formatType, numberAcross,
3601                         quadratic);
3602  if (rowNames) {
3603    deleteNamesAsChar(rowNames, numberRows_+1);
3604    deleteNamesAsChar(columnNames, numberColumns_);
3605  }
3606  return returnCode;
3607}
3608#ifndef CLP_NO_STD
3609// Create row names as char **
3610const char * const * 
3611ClpModel::rowNamesAsChar() const
3612{
3613  char ** rowNames = NULL;
3614  if (lengthNames()) {
3615    rowNames = new char * [numberRows_+1];
3616    int numberNames = rowNames_.size();
3617    numberNames = CoinMin(numberRows_,numberNames);
3618    int iRow;
3619    for (iRow=0;iRow<numberNames;iRow++) {
3620      rowNames[iRow] = 
3621        CoinStrdup(rowName(iRow).c_str());
3622#ifdef STRIPBLANKS
3623      char * xx = rowNames[iRow];
3624      int i;
3625      int length = strlen(xx);
3626      int n=0;
3627      for (i=0;i<length;i++) {
3628        if (xx[i]!=' ')
3629          xx[n++]=xx[i];
3630      }
3631      xx[n]='\0';
3632#endif
3633    }
3634    char name[9];
3635    for ( ;iRow<numberRows_;iRow++) {
3636      sprintf(name,"R%7.7d",iRow);
3637      rowNames[iRow]=CoinStrdup(name);
3638    }
3639    rowNames[numberRows_] = CoinStrdup("OBJROW");
3640  }
3641  return reinterpret_cast<const char * const *>(rowNames);
3642}
3643// Create column names as char **
3644const char * const * 
3645ClpModel::columnNamesAsChar() const
3646{
3647  char ** columnNames = NULL;
3648  if (lengthNames()) {
3649    columnNames = new char * [numberColumns_];
3650    int numberNames = columnNames_.size();
3651    numberNames = CoinMin(numberColumns_,numberNames);
3652    int iColumn;
3653    for (iColumn=0;iColumn<numberNames;iColumn++) {
3654      columnNames[iColumn] = 
3655        CoinStrdup(columnName(iColumn).c_str());
3656#ifdef STRIPBLANKS
3657      char * xx = columnNames[iColumn];
3658      int i;
3659      int length = strlen(xx);
3660      int n=0;
3661      for (i=0;i<length;i++) {
3662        if (xx[i]!=' ')
3663          xx[n++]=xx[i];
3664      }
3665      xx[n]='\0';
3666#endif
3667    }
3668    char name[9];
3669    for ( ;iColumn<numberColumns_;iColumn++) {
3670      sprintf(name,"C%7.7d",iColumn);
3671      columnNames[iColumn]=CoinStrdup(name);
3672    }
3673  }
3674  return /*reinterpret_cast<const char * const *>*/(columnNames);
3675}
3676// Delete char * version of names
3677void 
3678ClpModel::deleteNamesAsChar(const char * const * names,int number) const
3679{
3680  for (int i=0;i<number;i++) {
3681    free(const_cast<char *>(names[i]));
3682  }
3683  delete [] const_cast<char **>(names);
3684}
3685#endif
3686#endif
3687// Pass in Event handler (cloned and deleted at end)
3688void 
3689ClpModel::passInEventHandler(const ClpEventHandler * eventHandler)
3690{
3691  delete eventHandler_;
3692  eventHandler_ = eventHandler->clone();
3693}
3694// Sets or unsets scaling, 0 -off, 1 on, 2 dynamic(later)
3695void 
3696ClpModel::scaling(int mode)
3697{
3698  // If mode changes then we treat as new matrix (need new row copy)
3699  if (mode!=scalingFlag_)
3700    whatsChanged_ &= ~(2+4+8);
3701  if (mode>0&&mode<5) {
3702    scalingFlag_=mode;
3703  } else if (!mode) {
3704    scalingFlag_=0;
3705    setRowScale(NULL);
3706    setColumnScale(NULL);
3707  }
3708}
3709void 
3710ClpModel::times(double scalar,
3711                  const double * x, double * y) const
3712{
3713  if (!scaledMatrix_||!rowScale_) {
3714    if (rowScale_)
3715      matrix_->times(scalar,x,y,rowScale_,columnScale_);
3716    else
3717      matrix_->times(scalar,x,y);
3718  } else {
3719    scaledMatrix_->times(scalar,x,y);
3720  }
3721}
3722void 
3723ClpModel::transposeTimes(double scalar,
3724                           const double * x, double * y) const 
3725{
3726  if (!scaledMatrix_||!rowScale_) {
3727    if (rowScale_)
3728      matrix_->transposeTimes(scalar,x,y,rowScale_,columnScale_);
3729    else
3730      matrix_->transposeTimes(scalar,x,y);
3731  } else {
3732    scaledMatrix_->transposeTimes(scalar,x,y);
3733  }
3734}
3735// Does much of scaling
3736void 
3737ClpModel::gutsOfScaling()
3738{
3739  int i;
3740  if (rowObjective_) {
3741    for (i=0;i<numberRows_;i++) 
3742      rowObjective_[i] /= rowScale_[i];
3743  }
3744  for (i=0;i<numberRows_;i++) {
3745    double multiplier = rowScale_[i];
3746    double inverseMultiplier = 1.0/multiplier;
3747    rowActivity_[i] *= multiplier;
3748    dual_[i] *= inverseMultiplier;
3749    if (rowLower_[i]>-1.0e30)
3750      rowLower_[i] *= multiplier;
3751    else
3752      rowLower_[i] = -COIN_DBL_MAX;
3753    if (rowUpper_[i]<1.0e30)
3754      rowUpper_[i] *= multiplier;
3755    else
3756      rowUpper_[i] = COIN_DBL_MAX;
3757  }
3758  for (i=0;i<numberColumns_;i++) {
3759    double multiplier = 1.0/columnScale_[i];
3760    columnActivity_[i] *= multiplier;
3761    reducedCost_[i] *= columnScale_[i];
3762    if (columnLower_[i]>-1.0e30)
3763      columnLower_[i] *= multiplier;
3764    else
3765      columnLower_[i] = -COIN_DBL_MAX;
3766    if (columnUpper_[i]<1.0e30)
3767      columnUpper_[i] *= multiplier;
3768    else
3769      columnUpper_[i] = COIN_DBL_MAX;
3770   
3771  }
3772  //now replace matrix
3773  //and objective
3774  matrix_->reallyScale(rowScale_,columnScale_);
3775  objective_->reallyScale(columnScale_);
3776}
3777/* If we constructed a "really" scaled model then this reverses the operation.
3778      Quantities may not be exactly as they were before due to rounding errors */
3779void 
3780ClpModel::unscale()
3781{
3782  if (rowScale_) {
3783    int i;
3784    // reverse scaling
3785    for (i=0;i<numberRows_;i++) 
3786      rowScale_[i] = 1.0/rowScale_[i];
3787    for (i=0;i<numberColumns_;i++) 
3788      columnScale_[i] = 1.0/columnScale_[i];
3789    gutsOfScaling();
3790  }
3791 
3792  scalingFlag_=0;
3793  setRowScale(NULL);
3794  setColumnScale(NULL);
3795}
3796void 
3797ClpModel::setSpecialOptions(unsigned int value)
3798{ 
3799  specialOptions_=value;
3800}
3801/* This creates a coinModel object
3802 */
3803CoinModel * 
3804ClpModel::createCoinModel() const
3805{
3806  CoinModel * coinModel = new CoinModel();
3807  CoinPackedMatrix matrixByRow;
3808  matrixByRow.reverseOrderedCopyOf(*matrix());
3809  coinModel->setObjectiveOffset(objectiveOffset());
3810  coinModel->setProblemName(problemName().c_str());
3811
3812  // Build by row from scratch
3813  const double * element = matrixByRow.getElements();
3814  const int * column = matrixByRow.getIndices();
3815  const CoinBigIndex * rowStart = matrixByRow.getVectorStarts();
3816  const int * rowLength = matrixByRow.getVectorLengths();
3817  int i;
3818  for (i=0;i<numberRows_;i++) {
3819    coinModel->addRow(rowLength[i],column+rowStart[i],
3820                      element+rowStart[i],rowLower_[i],rowUpper_[i]);
3821  }
3822  // Now do column part
3823  const double * objective = this->objective();
3824  for (i=0;i<numberColumns_;i++) {
3825    coinModel->setColumnBounds(i,columnLower_[i],columnUpper_[i]);
3826    coinModel->setColumnObjective(i,objective[i]);
3827  }
3828  for ( i=0;i<numberColumns_;i++) {
3829    if (isInteger(i))
3830      coinModel->setColumnIsInteger(i,true);
3831  }
3832  // do names
3833  for (i=0;i<numberRows_;i++) {
3834    char temp[30];
3835    strcpy(temp,rowName(i).c_str());
3836    int length = strlen(temp);
3837    for (int j=0;j<length;j++) {
3838      if (temp[j]=='-')
3839        temp[j]='_';
3840    }
3841    coinModel->setRowName(i,temp);
3842  }
3843  for (i=0;i<numberColumns_;i++) {
3844    char temp[30];
3845    strcpy(temp,columnName(i).c_str());
3846    int length = strlen(temp);
3847    for (int j=0;j<length;j++) {
3848      if (temp[j]=='-')
3849        temp[j]='_';
3850    }
3851    coinModel->setColumnName(i,temp);
3852  }
3853  ClpQuadraticObjective * obj = (dynamic_cast< ClpQuadraticObjective*>(objective_));
3854  if (obj) {
3855    const CoinPackedMatrix * quadObj = obj->quadraticObjective();
3856    // add in quadratic
3857    const double * element = quadObj->getElements();
3858    const int * row = quadObj->getIndices();
3859    const CoinBigIndex * columnStart = quadObj->getVectorStarts();
3860    const int * columnLength = quadObj->getVectorLengths();
3861    for (i=0;i<numberColumns_;i++) {
3862      int nels = columnLength[i];
3863      if (nels) {
3864        CoinBigIndex start = columnStart[i];
3865        double constant = coinModel->getColumnObjective(i);
3866        char temp[100000];
3867        char temp2[30];
3868        sprintf(temp,"%g",constant);
3869        for (CoinBigIndex k=start;k<start+nels;k++) {
3870          int kColumn = row[k];
3871          double value = element[k];
3872#if 1
3873          // ampl gives twice with assumed 0.5
3874          if (kColumn<i)
3875            continue;
3876          else if (kColumn==i)
3877            value *= 0.5;
3878#endif
3879          if (value==1.0) 
3880            sprintf(temp2,"+%s",coinModel->getColumnName(kColumn));
3881          else if (value==-1.0)
3882            sprintf(temp2,"-%s",coinModel->getColumnName(kColumn));
3883          else if (value>0.0)
3884            sprintf(temp2,"+%g*%s",value,coinModel->getColumnName(kColumn));
3885          else 
3886            sprintf(temp2,"%g*%s",value,coinModel->getColumnName(kColumn));
3887          strcat(temp,temp2);
3888          assert (strlen(temp)<100000);
3889        }
3890        coinModel->setObjective(i,temp);
3891        if (logLevel()>2)
3892          printf("el for objective column %s is %s\n",coinModel->getColumnName(i),temp);
3893      }
3894    }
3895  }
3896  return coinModel;
3897}
3898// Start or reset using maximumRows_ and Columns_
3899void 
3900ClpModel::startPermanentArrays()
3901{
3902  printf("startperm a %d rows, %d maximum rows\n",
3903         numberRows_,maximumRows_);
3904  if ((specialOptions_&65536)!=0) {
3905    if (numberRows_>maximumRows_||numberColumns_>maximumColumns_) {
3906      if (numberRows_>maximumRows_)
3907        if (maximumRows_>0)
3908          maximumRows_ = numberRows_+10+numberRows_/100;
3909        else
3910          maximumRows_ = numberRows_;
3911      if (numberColumns_>maximumColumns_) 
3912        if (maximumColumns_>0)
3913          maximumColumns_ = numberColumns_+10+numberColumns_/100;
3914        else
3915          maximumColumns_ = numberColumns_;
3916      // need to make sure numberRows_ OK and size of matrices
3917      resize(maximumRows_,maximumColumns_);
3918      printf("startperm b %d rows, %d maximum rows\n",
3919             numberRows_,maximumRows_);
3920    } else {
3921      return;
3922    }
3923  } else {
3924    specialOptions_ |= 65536;
3925    maximumRows_ = numberRows_;
3926    maximumColumns_ = numberColumns_;
3927    baseMatrix_ = *matrix();
3928    baseMatrix_.cleanMatrix();
3929    baseRowCopy_.setExtraGap(0.0);
3930    baseRowCopy_.setExtraMajor(0.0);
3931    baseRowCopy_.reverseOrderedCopyOf(baseMatrix_);
3932    printf("startperm c %d rows, %d maximum rows\n",
3933             numberRows_,maximumRows_);
3934  }
3935}
3936// Stop using maximumRows_ and Columns_
3937void 
3938ClpModel::stopPermanentArrays()
3939{
3940  specialOptions_ &= ~65536;
3941  maximumRows_=-1;
3942  maximumColumns_=-1;
3943  if (rowScale_!=savedRowScale_) {
3944    delete [] savedRowScale_;
3945    delete [] savedColumnScale_;
3946  }
3947  savedRowScale_ = NULL;
3948  savedColumnScale_ = NULL;
3949}
3950/* Find a network subset.
3951   rotate array should be numberRows.  On output
3952   -1 not in network
3953   0 in network as is
3954   1 in network with signs swapped
3955  Returns number of network rows (positive if exact network, negative if needs extra row)
3956  From Gulpinar, Gutin, Maros and Mitra
3957*/
3958int 
3959ClpModel::findNetwork(char * rotate,double fractionNeeded)
3960{
3961  int * mapping = new int [numberRows_];
3962  // Get column copy
3963  CoinPackedMatrix * columnCopy = matrix();
3964  // Get a row copy in standard format
3965  CoinPackedMatrix * copy = new CoinPackedMatrix();
3966  copy->reverseOrderedCopyOf(*columnCopy);
3967  // make sure ordered and no gaps
3968  copy->cleanMatrix();
3969  // get matrix data pointers
3970  const int * columnIn = copy->getIndices();
3971  const CoinBigIndex * rowStartIn = copy->getVectorStarts();
3972  const int * rowLength = copy->getVectorLengths(); 
3973  const double * elementByRowIn = copy->getElements();
3974  int iRow,iColumn;
3975  int numberEligible=0;
3976  int numberIn=0;
3977  int numberElements=0;
3978  for (iRow=0;iRow<numberRows_;iRow++) {
3979    bool possible=true;
3980    mapping[iRow]=-1;
3981    rotate[iRow]=-1;
3982    for (CoinBigIndex j=rowStartIn[iRow];j<rowStartIn[iRow]+rowLength[iRow];j++) {
3983      //int iColumn = column[j];
3984      double value = elementByRowIn[j];
3985      if (fabs(value)!=1.0) {
3986        possible=false;
3987        break;
3988      }
3989    }
3990    if (rowLength[iRow]&&possible) {
3991      mapping[iRow]=numberEligible;
3992      numberEligible++;
3993      numberElements+=rowLength[iRow];
3994    }
3995  }
3996  if (numberEligible<fractionNeeded*numberRows_) {
3997    delete [] mapping;
3998    return 0;
3999  }
4000  // create arrays
4001  int * eligible = new int [numberRows_];
4002  int * column = new int [numberElements];
4003  CoinBigIndex * rowStart = new CoinBigIndex [numberEligible+1];
4004  char * elementByRow = new char [numberElements];
4005  numberEligible=0;
4006  numberElements=0;
4007  rowStart[0]=0;
4008  for (iRow=0;iRow<numberRows_;iRow++) {
4009    if (mapping[iRow]<0)
4010      continue;
4011    assert (numberEligible==mapping[iRow]);
4012    rotate[numberEligible]=0;
4013    for (CoinBigIndex j=rowStartIn[iRow];j<rowStartIn[iRow]+rowLength[iRow];j++) {
4014      column[numberElements] = columnIn[j];
4015      double value = elementByRowIn[j];
4016      if (value==1.0) 
4017        elementByRow[numberElements++]=1;
4018      else
4019        elementByRow[numberElements++]=-1;
4020    }
4021    numberEligible++;
4022    rowStart[numberEligible]=numberElements;
4023  }
4024  // get rid of copy to save space
4025  delete copy;
4026  const int * rowIn = columnCopy->getIndices();
4027  const CoinBigIndex * columnStartIn = columnCopy->getVectorStarts();
4028  const int * columnLengthIn = columnCopy->getVectorLengths(); 
4029  const double * elementByColumnIn = columnCopy->getElements();
4030  int * columnLength = new int [numberColumns_];
4031  // May just be that is a network - worth checking
4032  bool isNetworkAlready=true;
4033  bool trueNetwork=true;
4034  for (iColumn=0;iColumn<numberColumns_;iColumn++) {
4035    double product =1.0;
4036    int n=0;
4037    for (CoinBigIndex j=columnStartIn[iColumn];j<columnStartIn[iColumn]+columnLengthIn[iColumn];j++) {
4038      iRow = mapping[rowIn[j]];
4039      if (iRow>=0) {
4040        n++;
4041        product *= elementByColumnIn[j];
4042      }
4043    }
4044    if (n>=2) {
4045      if (product!=-1.0||n>2) 
4046        isNetworkAlready=false;
4047    } else if (n==1) {
4048      trueNetwork=false;
4049    }
4050    columnLength[iColumn]=n;
4051  }
4052  if (!isNetworkAlready) {
4053    // For sorting
4054    double * count = new double [numberRows_];
4055    int * which = new int [numberRows_];
4056    int numberLast=-1;
4057      // Count for columns
4058    char * columnCount = new char[numberColumns_];
4059    memset(columnCount,0,numberColumns_);
4060    char * currentColumnCount = new char[numberColumns_];
4061    // Now do main loop
4062    while (numberIn>numberLast) {
4063      numberLast=numberIn;
4064      int numberLeft = 0;
4065      for (iRow=0;iRow<numberEligible;iRow++) {
4066        if (rotate[iRow]==0) {
4067          which[numberLeft]=iRow;
4068          int merit=0;
4069          bool OK=true;
4070          bool reflectionOK=true;
4071          for (CoinBigIndex j=rowStart[iRow];j<rowStart[iRow+1];j++) {
4072            iColumn = column[j];
4073            int iCount=columnCount[iColumn];
4074            int absCount=CoinAbs(iCount);
4075            if (absCount<2) {
4076              merit = CoinMax(columnLength[iColumn]-absCount-1,merit);
4077              if (elementByRow[j]==iCount)
4078                OK=false;
4079              else if (elementByRow[j]==-iCount)
4080                reflectionOK=false;
4081            } else {
4082              merit =-2;
4083              break;
4084            }
4085          }
4086          if (merit>-2&&(OK||reflectionOK)) {
4087            assert (!OK||!reflectionOK||!numberIn);
4088            //if (!numberLast) merit=1;
4089            count[numberLeft++]=(rowStart[iRow+1]-rowStart[iRow]-1)*((double)merit);
4090            if (OK)
4091              rotate[iRow]=0;
4092            else
4093              rotate[iRow]=1;
4094          } else {
4095            // no good
4096            rotate[iRow]=-1;
4097          }
4098        }
4099      }
4100      CoinSort_2(count,count+numberLeft,which);
4101      // Get G
4102      memset(currentColumnCount,0,numberColumns_);
4103      for (iRow=0;iRow<numberLeft;iRow++) {
4104        int jRow = which[iRow];
4105        bool possible=true;
4106        for (int i=0;i<numberIn;i++) {
4107          for (CoinBigIndex j=rowStart[jRow];j<rowStart[jRow+1];j++) {
4108            if (currentColumnCount[column[j]]) {
4109              possible=false;
4110              break;
4111            }
4112          }
4113        }
4114        if (possible) {
4115          rotate[jRow]+=2;
4116          eligible[numberIn++]=jRow;
4117          char multiplier = (rotate[jRow]==2) ? 1 : -1;
4118          for (CoinBigIndex j=rowStart[jRow];j<rowStart[jRow+1];j++) {
4119            iColumn = column[j];
4120            currentColumnCount[iColumn]++;
4121            int iCount=columnCount[iColumn];
4122            int absCount=CoinAbs(iCount);
4123            if (!absCount) {
4124              columnCount[iColumn]=elementByRow[j]*multiplier;
4125            } else {
4126              columnCount[iColumn]=2;
4127            }
4128          }
4129        }
4130      }
4131    }
4132#ifndef NDEBUG
4133    for (iRow=0;iRow<numberIn;iRow++) {
4134      int kRow = eligible[iRow];
4135      assert (rotate[kRow]>=2);
4136    }
4137#endif
4138    trueNetwork=true;
4139    for (iColumn=0;iColumn<numberColumns_;iColumn++) {
4140      if (CoinAbs(columnCount[iColumn])==1) {
4141        trueNetwork=false;
4142        break;
4143      }
4144    }
4145    delete [] currentColumnCount;
4146    delete [] columnCount;
4147    delete [] which;
4148    delete [] count;
4149  } else {
4150    numberIn=numberEligible;
4151    for (iRow=0;iRow<numberRows_;iRow++) {
4152      int kRow = mapping[iRow];
4153      if (kRow>=0) {
4154        rotate[kRow]=2;
4155      }
4156    }
4157  }
4158  if (!trueNetwork)
4159    numberIn= - numberIn;
4160  delete [] column;
4161  delete [] rowStart;
4162  delete [] elementByRow;
4163  delete [] columnLength;
4164  // redo rotate
4165  char * rotate2 = CoinCopyOfArray(rotate,numberEligible);
4166  for (iRow=0;iRow<numberRows_;iRow++) {
4167    int kRow = mapping[iRow];
4168    if (kRow>=0) {
4169      int iState=rotate2[kRow];
4170      if (iState>1)
4171        iState -=2;
4172      else
4173        iState = -1;
4174      rotate[iRow]=iState;
4175    } else {
4176      rotate[iRow]=-1;
4177    }
4178  }
4179  delete [] rotate2;
4180  delete [] eligible;
4181  delete [] mapping;
4182  return numberIn;
4183}
4184//#############################################################################
4185// Constructors / Destructor / Assignment
4186//#############################################################################
4187
4188//-------------------------------------------------------------------
4189// Default Constructor
4190//-------------------------------------------------------------------
4191ClpDataSave::ClpDataSave () 
4192{
4193  dualBound_ = 0.0;
4194  infeasibilityCost_ = 0.0;
4195  sparseThreshold_ = 0;
4196  pivotTolerance_=0.0;
4197  acceptablePivot_ = 0.0;
4198  objectiveScale_ = 1.0;
4199  perturbation_ = 0;
4200  forceFactorization_=-1;
4201  scalingFlag_=0;
4202  specialOptions_=0;
4203}
4204
4205//-------------------------------------------------------------------
4206// Copy constructor
4207//-------------------------------------------------------------------
4208ClpDataSave::ClpDataSave (const ClpDataSave & rhs) 
4209{ 
4210  dualBound_ = rhs.dualBound_;
4211  infeasibilityCost_ = rhs.infeasibilityCost_;
4212  pivotTolerance_ = rhs.pivotTolerance_;
4213  acceptablePivot_ = rhs.acceptablePivot_;
4214  objectiveScale_ = rhs.objectiveScale_;
4215  sparseThreshold_ = rhs.sparseThreshold_;
4216  perturbation_ = rhs.perturbation_;
4217  forceFactorization_=rhs.forceFactorization_;
4218  scalingFlag_=rhs.scalingFlag_;
4219  specialOptions_=rhs.specialOptions_;
4220}
4221
4222//-------------------------------------------------------------------
4223// Destructor
4224//-------------------------------------------------------------------
4225ClpDataSave::~ClpDataSave ()
4226{
4227}
4228
4229//----------------------------------------------------------------
4230// Assignment operator
4231//-------------------------------------------------------------------
4232ClpDataSave &
4233ClpDataSave::operator=(const ClpDataSave& rhs)
4234{
4235  if (this != &rhs) {
4236    dualBound_ = rhs.dualBound_;
4237    infeasibilityCost_ = rhs.infeasibilityCost_;
4238    pivotTolerance_ = rhs.pivotTolerance_;
4239    acceptablePivot_ = rhs.acceptablePivot_;
4240    objectiveScale_ = rhs.objectiveScale_;
4241    sparseThreshold_ = rhs.sparseThreshold_;
4242    perturbation_ = rhs.perturbation_;
4243    forceFactorization_=rhs.forceFactorization_;
4244    scalingFlag_=rhs.scalingFlag_;
4245    specialOptions_=rhs.specialOptions_;
4246  }
4247  return *this;
4248}
4249// Create C++ lines to get to current state
4250void 
4251ClpModel::generateCpp( FILE * fp)
4252{
4253  // Stuff that can't be done easily
4254  if (!lengthNames_) {
4255    // no names
4256    fprintf(fp,"  clpModel->dropNames();\n");
4257  }
4258  ClpModel defaultModel;
4259  ClpModel * other = &defaultModel;
4260  int iValue1, iValue2;
4261  double dValue1, dValue2;
4262  iValue1 = this->maximumIterations();
4263  iValue2 = other->maximumIterations();
4264  fprintf(fp,"%d  int save_maximumIterations = clpModel->maximumIterations();\n",iValue1==iValue2 ? 2 : 1);
4265  fprintf(fp,"%d  clpModel->setMaximumIterations(%d);\n",iValue1==iValue2 ? 4 : 3,iValue1);
4266  fprintf(fp,"%d  clpModel->setMaximumIterations(save_maximumIterations);\n",iValue1==iValue2 ? 7 : 6);
4267  dValue1 = this->primalTolerance();
4268  dValue2 = other->primalTolerance();
4269  fprintf(fp,"%d  double save_primalTolerance = clpModel->primalTolerance();\n",dValue1==dValue2 ? 2 : 1);
4270  fprintf(fp,"%d  clpModel->setPrimalTolerance(%g);\n",dValue1==dValue2 ? 4 : 3,dValue1);
4271  fprintf(fp,"%d  clpModel->setPrimalTolerance(save_primalTolerance);\n",dValue1==dValue2 ? 7 : 6);
4272  dValue1 = this->dualTolerance();
4273  dValue2 = other->dualTolerance();
4274  fprintf(fp,"%d  double save_dualTolerance = clpModel->dualTolerance();\n",dValue1==dValue2 ? 2 : 1);
4275  fprintf(fp,"%d  clpModel->setDualTolerance(%g);\n",dValue1==dValue2 ? 4 : 3,dValue1);
4276  fprintf(fp,"%d  clpModel->setDualTolerance(save_dualTolerance);\n",dValue1==dValue2 ? 7 : 6);
4277  iValue1 = this->numberIterations();
4278  iValue2 = other->numberIterations();
4279  fprintf(fp,"%d  int save_numberIterations = clpModel->numberIterations();\n",iValue1==iValue2 ? 2 : 1);
4280  fprintf(fp,"%d  clpModel->setNumberIterations(%d);\n",iValue1==iValue2 ? 4 : 3,iValue1);
4281  fprintf(fp,"%d  clpModel->setNumberIterations(save_numberIterations);\n",iValue1==iValue2 ? 7 : 6);
4282  dValue1 = this->maximumSeconds();
4283  dValue2 = other->maximumSeconds();
4284  fprintf(fp,"%d  double save_maximumSeconds = clpModel->maximumSeconds();\n",dValue1==dValue2 ? 2 : 1);
4285  fprintf(fp,"%d  clpModel->setMaximumSeconds(%g);\n",dValue1==dValue2 ? 4 : 3,dValue1);
4286  fprintf(fp,"%d  clpModel->setMaximumSeconds(save_maximumSeconds);\n",dValue1==dValue2 ? 7 : 6);
4287  dValue1 = this->optimizationDirection();
4288  dValue2 = other->optimizationDirection();
4289  fprintf(fp,"%d  double save_optimizationDirection = clpModel->optimizationDirection();\n",dValue1==dValue2 ? 2 : 1);
4290  fprintf(fp,"%d  clpModel->setOptimizationDirection(%g);\n",dValue1==dValue2 ? 4 : 3,dValue1);
4291  fprintf(fp,"%d  clpModel->setOptimizationDirection(save_optimizationDirection);\n",dValue1==dValue2 ? 7 : 6);
4292  dValue1 = this->objectiveScale();
4293  dValue2 = other->objectiveScale();
4294  fprintf(fp,"%d  double save_objectiveScale = clpModel->objectiveScale();\n",dValue1==dValue2 ? 2 : 1);
4295  fprintf(fp,"%d  clpModel->setObjectiveScale(%g);\n",dValue1==dValue2 ? 4 : 3,dValue1);
4296  fprintf(fp,"%d  clpModel->setObjectiveScale(save_objectiveScale);\n",dValue1==dValue2 ? 7 : 6);
4297  dValue1 = this->rhsScale();
4298  dValue2 = other->rhsScale();
4299  fprintf(fp,"%d  double save_rhsScale = clpModel->rhsScale();\n",dValue1==dValue2 ? 2 : 1);
4300  fprintf(fp,"%d  clpModel->setRhsScale(%g);\n",dValue1==dValue2 ? 4 : 3,dValue1);
4301  fprintf(fp,"%d  clpModel->setRhsScale(save_rhsScale);\n",dValue1==dValue2 ? 7 : 6);
4302  iValue1 = this->scalingFlag();
4303  iValue2 = other->scalingFlag();
4304  fprintf(fp,"%d  int save_scalingFlag = clpModel->scalingFlag();\n",iValue1==iValue2 ? 2 : 1);
4305  fprintf(fp,"%d  clpModel->scaling(%d);\n",iValue1==iValue2 ? 4 : 3,iValue1);
4306  fprintf(fp,"%d  clpModel->scaling(save_scalingFlag);\n",iValue1==iValue2 ? 7 : 6);
4307  dValue1 = this->getSmallElementValue();
4308  dValue2 = other->getSmallElementValue();
4309  fprintf(fp,"%d  double save_getSmallElementValue = clpModel->getSmallElementValue();\n",dValue1==dValue2 ? 2 : 1);
4310  fprintf(fp,"%d  clpModel->setSmallElementValue(%g);\n",dValue1==dValue2 ? 4 : 3,dValue1);
4311  fprintf(fp,"%d  clpModel->setSmallElementValue(save_getSmallElementValue);\n",dValue1==dValue2 ? 7 : 6);
4312  iValue1 = this->logLevel();
4313  iValue2 = other->logLevel();
4314  fprintf(fp,"%d  int save_logLevel = clpModel->logLevel();\n",iValue1==iValue2 ? 2 : 1);
4315  fprintf(fp,"%d  clpModel->setLogLevel(%d);\n",iValue1==iValue2 ? 4 : 3,iValue1);
4316  fprintf(fp,"%d  clpModel->setLogLevel(save_logLevel);\n",iValue1==iValue2 ? 7 : 6);
4317}
Note: See TracBrowser for help on using the repository browser.