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

Last change on this file since 1154 was 1154, checked in by forrest, 13 years ago

changes for cbc

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