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

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

for threaded random numbers

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