source: trunk/ClpModel.cpp @ 559

Last change on this file since 559 was 559, checked in by forrest, 15 years ago

check null model_

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