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

Last change on this file since 1150 was 1150, checked in by forrest, 12 years ago

try and make a bit faster

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