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

Last change on this file since 1185 was 1185, checked in by ladanyi, 13 years ago

include cstdlib before cmath to get things to compile on AIX with xlC

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