source: branches/devel/Clp/src/ClpModel.cpp @ 989

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

this may be a mistake

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