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

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

fixes for various ideas

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