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

Last change on this file since 1484 was 1484, checked in by forrest, 10 years ago

memory leak

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