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

Last change on this file since 1344 was 1344, checked in by forrest, 11 years ago

changes to simplex and lots of stuff and start Mumps cholesky

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