source: stable/1.7/Clp/src/ClpModel.cpp @ 1186

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

include cstdlib before cmath to get things to compile on AIX with xlC (same as changeset 1185 in trunk)

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