source: branches/pre/ClpModel.cpp @ 180

Last change on this file since 180 was 180, checked in by forrest, 18 years ago

new stuff

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 41.1 KB
Line 
1// Copyright (C) 2002, International Business Machines
2// Corporation and others.  All Rights Reserved.
3
4#include <cmath>
5#include <cassert>
6#include <cfloat>
7#include <string>
8#include <cstdio>
9#include <iostream>
10
11
12#include "CoinPragma.hpp"
13
14#include "CoinHelperFunctions.hpp"
15#include "ClpModel.hpp"
16#include "ClpPackedMatrix.hpp"
17#include "CoinPackedVector.hpp"
18#include "CoinIndexedVector.hpp"
19#include "CoinMpsIO.hpp"
20#include "ClpMessage.hpp"
21#include "ClpLinearObjective.hpp"
22
23//#############################################################################
24
25ClpModel::ClpModel () :
26
27  optimizationDirection_(1),
28  objectiveValue_(0.0),
29  smallElement_(1.0e-20),
30  numberRows_(0),
31  numberColumns_(0),
32  rowActivity_(NULL),
33  columnActivity_(NULL),
34  dual_(NULL),
35  reducedCost_(NULL),
36  rowLower_(NULL),
37  rowUpper_(NULL),
38  objective_(NULL),
39  rowObjective_(NULL),
40  columnLower_(NULL),
41  columnUpper_(NULL),
42  matrix_(NULL),
43  rowCopy_(NULL),
44  quadraticObjective_(NULL),
45  ray_(NULL),
46  status_(NULL),
47  integerType_(NULL),
48  numberIterations_(0),
49  solveType_(0),
50  problemStatus_(-1),
51  lengthNames_(0),
52  defaultHandler_(true),
53  rowNames_(),
54  columnNames_()
55{
56  intParam_[ClpMaxNumIteration] = 99999999;
57  intParam_[ClpMaxNumIterationHotStart] = 9999999;
58
59  dblParam_[ClpDualObjectiveLimit] = COIN_DBL_MAX;
60  dblParam_[ClpPrimalObjectiveLimit] = COIN_DBL_MAX;
61  dblParam_[ClpDualTolerance] = 1e-7;
62  dblParam_[ClpPrimalTolerance] = 1e-7;
63  dblParam_[ClpObjOffset] = 0.0;
64  dblParam_[ClpMaxSeconds] = -1.0;
65
66  strParam_[ClpProbName] = "ClpDefaultName";
67  handler_ = new CoinMessageHandler();
68  handler_->setLogLevel(2);
69  messages_ = ClpMessage();
70}
71
72//-----------------------------------------------------------------------------
73
74ClpModel::~ClpModel ()
75{
76  if (defaultHandler_) {
77    delete handler_;
78    handler_ = NULL;
79  }
80  gutsOfDelete();
81}
82void ClpModel::gutsOfDelete()
83{
84  delete [] rowActivity_;
85  rowActivity_=NULL;
86  delete [] columnActivity_;
87  columnActivity_=NULL;
88  delete [] dual_;
89  dual_=NULL;
90  delete [] reducedCost_;
91  reducedCost_=NULL;
92  delete [] rowLower_;
93  delete [] rowUpper_;
94  delete [] rowObjective_;
95  rowLower_=NULL;
96  rowUpper_=NULL;
97  rowObjective_=NULL;
98  delete [] columnLower_;
99  delete [] columnUpper_;
100  delete objective_;
101  columnLower_=NULL;
102  columnUpper_=NULL;
103  objective_=NULL;
104  delete matrix_;
105  matrix_=NULL;
106  delete rowCopy_;
107  rowCopy_=NULL;
108  delete quadraticObjective_;
109  quadraticObjective_ = NULL;
110  delete [] ray_;
111  ray_ = NULL;
112  delete [] integerType_;
113  integerType_ = NULL;
114  delete [] status_;
115  status_=NULL;
116}
117//#############################################################################
118void ClpModel::setPrimalTolerance( double value) 
119{
120  if (value>0.0&&value<1.0e10)
121    dblParam_[ClpPrimalTolerance]=value;
122}
123void ClpModel::setDualTolerance( double value) 
124{
125  if (value>0.0&&value<1.0e10)
126    dblParam_[ClpDualTolerance]=value;
127}
128void ClpModel::setOptimizationDirection( int value) 
129{
130  if (value>=-1&&value<=1)
131    optimizationDirection_=value;
132}
133void
134ClpModel::gutsOfLoadModel (int numberRows, int numberColumns, 
135                     const double* collb, const double* colub,   
136                     const double* obj,
137                     const double* rowlb, const double* rowub,
138                                const double * rowObjective)
139{
140  gutsOfDelete();
141  numberRows_=numberRows;
142  numberColumns_=numberColumns;
143  rowActivity_=new double[numberRows_];
144  columnActivity_=new double[numberColumns_];
145  dual_=new double[numberRows_];
146  reducedCost_=new double[numberColumns_];
147
148  ClpFillN(dual_,numberRows_,0.0);
149  ClpFillN(reducedCost_,numberColumns_,0.0);
150  int iRow,iColumn;
151
152  rowLower_=ClpCopyOfArray(rowlb,numberRows_,-COIN_DBL_MAX);
153  rowUpper_=ClpCopyOfArray(rowub,numberRows_,COIN_DBL_MAX);
154  double * objective=ClpCopyOfArray(obj,numberColumns_,0.0);
155  objective_ = new ClpLinearObjective(objective,numberColumns_);
156  delete [] objective;
157  rowObjective_=ClpCopyOfArray(rowObjective,numberRows_);
158  columnLower_=ClpCopyOfArray(collb,numberColumns_,0.0);
159  columnUpper_=ClpCopyOfArray(colub,numberColumns_,COIN_DBL_MAX);
160  // set default solution
161  for (iRow=0;iRow<numberRows_;iRow++) {
162    if (rowLower_[iRow]>0.0) {
163      rowActivity_[iRow]=rowLower_[iRow];
164    } else if (rowUpper_[iRow]<0.0) {
165      rowActivity_[iRow]=rowUpper_[iRow];
166    } else {
167      rowActivity_[iRow]=0.0;
168    }
169  }
170  for (iColumn=0;iColumn<numberColumns_;iColumn++) {
171    if (columnLower_[iColumn]>0.0) {
172      columnActivity_[iColumn]=columnLower_[iColumn];
173    } else if (columnUpper_[iColumn]<0.0) {
174      columnActivity_[iColumn]=columnUpper_[iColumn];
175    } else {
176      columnActivity_[iColumn]=0.0;
177    }
178  }
179}
180// This just loads up a row objective
181void ClpModel::setRowObjective(const double * rowObjective)
182{
183  delete [] rowObjective_;
184  rowObjective_=ClpCopyOfArray(rowObjective,numberRows_);
185}
186void
187ClpModel::loadProblem (  const ClpMatrixBase& matrix,
188                     const double* collb, const double* colub,   
189                     const double* obj,
190                     const double* rowlb, const double* rowub,
191                                const double * rowObjective)
192{
193  gutsOfLoadModel(matrix.getNumRows(),matrix.getNumCols(),
194                  collb, colub, obj, rowlb, rowub, rowObjective);
195  if (matrix.isColOrdered()) {
196    matrix_=matrix.clone();
197  } else {
198    // later may want to keep as unknown class
199    CoinPackedMatrix matrix2;
200    matrix2.reverseOrderedCopyOf(*matrix.getPackedMatrix());
201    matrix.releasePackedMatrix();
202    matrix_=new ClpPackedMatrix(matrix2);
203  }   
204}
205void
206ClpModel::loadProblem (  const CoinPackedMatrix& matrix,
207                     const double* collb, const double* colub,   
208                     const double* obj,
209                     const double* rowlb, const double* rowub,
210                                const double * rowObjective)
211{
212  gutsOfLoadModel(matrix.getNumRows(),matrix.getNumCols(),
213                  collb, colub, obj, rowlb, rowub, rowObjective);
214  if (matrix.isColOrdered()) {
215    matrix_=new ClpPackedMatrix(matrix);
216  } else {
217    CoinPackedMatrix matrix2;
218    matrix2.reverseOrderedCopyOf(matrix);
219    matrix_=new ClpPackedMatrix(matrix2);
220  }   
221}
222void
223ClpModel::loadProblem ( 
224                              const int numcols, const int numrows,
225                              const CoinBigIndex* start, const int* index,
226                              const double* value,
227                              const double* collb, const double* colub,   
228                              const double* obj,
229                              const double* rowlb, const double* rowub,
230                              const double * rowObjective)
231{
232  gutsOfLoadModel(numrows, numcols,
233                  collb, colub, obj, rowlb, rowub, rowObjective);
234  CoinPackedMatrix matrix(true,numrows,numcols,start[numcols],
235                              value,index,start,NULL);
236  matrix_ = new ClpPackedMatrix(matrix);
237}
238void
239ClpModel::loadProblem ( 
240                              const int numcols, const int numrows,
241                              const CoinBigIndex* start, const int* index,
242                              const double* value,const int* length,
243                              const double* collb, const double* colub,   
244                              const double* obj,
245                              const double* rowlb, const double* rowub,
246                              const double * rowObjective)
247{
248  gutsOfLoadModel(numrows, numcols,
249                  collb, colub, obj, rowlb, rowub, rowObjective);
250  // Compute number of elements
251  int numberElements = 0;
252  int i;
253  for (i=0;i<numcols;i++) 
254    numberElements += length[i];
255  CoinPackedMatrix matrix(true,numrows,numcols,numberElements,
256                              value,index,start,length);
257  matrix_ = new ClpPackedMatrix(matrix);
258}
259void
260ClpModel::getRowBound(int iRow, double& lower, double& upper) const
261{
262  lower=-COIN_DBL_MAX;
263  upper=COIN_DBL_MAX;
264  if (rowUpper_)
265    upper=rowUpper_[iRow];
266  if (rowLower_)
267    lower=rowLower_[iRow];
268}
269//#############################################################################
270// Copy constructor.
271ClpModel::ClpModel(const ClpModel &rhs) :
272  optimizationDirection_(rhs.optimizationDirection_),
273  numberRows_(rhs.numberRows_),
274  numberColumns_(rhs.numberColumns_)
275{
276  gutsOfCopy(rhs);
277}
278// Assignment operator. This copies the data
279ClpModel & 
280ClpModel::operator=(const ClpModel & rhs)
281{
282  if (this != &rhs) {
283    if (defaultHandler_) {
284      delete handler_;
285      handler_ = NULL;
286    }
287    gutsOfDelete();
288    optimizationDirection_ = rhs.optimizationDirection_;
289    numberRows_ = rhs.numberRows_;
290    numberColumns_ = rhs.numberColumns_;
291    gutsOfCopy(rhs);
292  }
293  return *this;
294}
295// Does most of copying
296void 
297ClpModel::gutsOfCopy(const ClpModel & rhs, bool trueCopy)
298{
299  defaultHandler_ = rhs.defaultHandler_;
300  if (defaultHandler_) 
301    handler_ = new CoinMessageHandler(*rhs.handler_);
302   else 
303    handler_ = rhs.handler_;
304  messages_ = rhs.messages_;
305  intParam_[ClpMaxNumIteration] = rhs.intParam_[ClpMaxNumIteration];
306  intParam_[ClpMaxNumIterationHotStart] = 
307    rhs.intParam_[ClpMaxNumIterationHotStart];
308
309  dblParam_[ClpDualObjectiveLimit] = rhs.dblParam_[ClpDualObjectiveLimit];
310  dblParam_[ClpPrimalObjectiveLimit] = rhs.dblParam_[ClpPrimalObjectiveLimit];
311  dblParam_[ClpDualTolerance] = rhs.dblParam_[ClpDualTolerance];
312  dblParam_[ClpPrimalTolerance] = rhs.dblParam_[ClpPrimalTolerance];
313  dblParam_[ClpObjOffset] = rhs.dblParam_[ClpObjOffset];
314  dblParam_[ClpMaxSeconds] = rhs.dblParam_[ClpMaxSeconds];
315
316  strParam_[ClpProbName] = rhs.strParam_[ClpProbName];
317
318  optimizationDirection_ = rhs.optimizationDirection_;
319  objectiveValue_=rhs.objectiveValue_;
320  smallElement_ = rhs.smallElement_;
321  numberIterations_ = rhs.numberIterations_;
322  solveType_ = rhs.solveType_;
323  problemStatus_ = rhs.problemStatus_;
324  numberRows_ = rhs.numberRows_;
325  numberColumns_ = rhs.numberColumns_;
326  if (trueCopy) {
327    lengthNames_ = rhs.lengthNames_;
328    rowNames_ = rhs.rowNames_;
329    columnNames_ = rhs.columnNames_;
330    if (rhs.integerType_) {
331      integerType_ = new char[numberColumns_];
332      memcpy(integerType_,rhs.integerType_,numberColumns_*sizeof(char));
333    } else {
334      integerType_ = NULL;
335    }
336    if (rhs.rowActivity_) {
337      rowActivity_=new double[numberRows_];
338      columnActivity_=new double[numberColumns_];
339      dual_=new double[numberRows_];
340      reducedCost_=new double[numberColumns_];
341      ClpDisjointCopyN ( rhs.rowActivity_, numberRows_ ,
342                          rowActivity_);
343      ClpDisjointCopyN ( rhs.columnActivity_, numberColumns_ ,
344                          columnActivity_);
345      ClpDisjointCopyN ( rhs.dual_, numberRows_ , 
346                          dual_);
347      ClpDisjointCopyN ( rhs.reducedCost_, numberColumns_ ,
348                          reducedCost_);
349    } else {
350      rowActivity_=NULL;
351      columnActivity_=NULL;
352      dual_=NULL;
353      reducedCost_=NULL;
354    }
355    rowLower_ = ClpCopyOfArray ( rhs.rowLower_, numberRows_ );
356    rowUpper_ = ClpCopyOfArray ( rhs.rowUpper_, numberRows_ );
357    columnLower_ = ClpCopyOfArray ( rhs.columnLower_, numberColumns_ );
358    columnUpper_ = ClpCopyOfArray ( rhs.columnUpper_, numberColumns_ );
359    if (rhs.objective_)
360      objective_  = rhs.objective_->clone();
361    else
362      objective_ = NULL;
363    rowObjective_ = ClpCopyOfArray ( rhs.rowObjective_, numberRows_ );
364    status_ = ClpCopyOfArray( rhs.status_,numberColumns_+numberRows_);
365    ray_ = NULL;
366    if (problemStatus_==1)
367      ray_ = ClpCopyOfArray (rhs.ray_,numberRows_);
368    else if (problemStatus_==2)
369      ray_ = ClpCopyOfArray (rhs.ray_,numberColumns_);
370    if (rhs.rowCopy_) {
371      rowCopy_ = rhs.rowCopy_->clone();
372    } else {
373      rowCopy_=NULL;
374    }
375    if (rhs.quadraticObjective_) {
376      quadraticObjective_ = new CoinPackedMatrix(*rhs.quadraticObjective_);
377    } else {
378      quadraticObjective_=NULL;
379    }
380    matrix_=NULL;
381    if (rhs.matrix_) {
382      matrix_ = rhs.matrix_->clone();
383    }
384  } else {
385    rowActivity_ = rhs.rowActivity_;
386    columnActivity_ = rhs.columnActivity_;
387    dual_ = rhs.dual_;
388    reducedCost_ = rhs.reducedCost_;
389    rowLower_ = rhs.rowLower_;
390    rowUpper_ = rhs.rowUpper_;
391    objective_ = rhs.objective_;
392    rowObjective_ = rhs.rowObjective_;
393    columnLower_ = rhs.columnLower_;
394    columnUpper_ = rhs.columnUpper_;
395    matrix_ = rhs.matrix_;
396    rowCopy_ = NULL;
397    quadraticObjective_ = rhs.quadraticObjective_;
398    ray_ = rhs.ray_;
399    lengthNames_ = 0;
400    rowNames_ = std::vector<std::string> ();
401    columnNames_ = std::vector<std::string> ();
402    integerType_ = NULL;
403    status_ = rhs.status_;
404  }
405}
406/* Borrow model.  This is so we dont have to copy large amounts
407   of data around.  It assumes a derived class wants to overwrite
408   an empty model with a real one - while it does an algorithm */
409void 
410ClpModel::borrowModel(ClpModel & rhs)
411{
412  if (defaultHandler_) {
413    delete handler_;
414    handler_ = NULL;
415  }
416  gutsOfDelete();
417  optimizationDirection_ = rhs.optimizationDirection_;
418  numberRows_ = rhs.numberRows_;
419  numberColumns_ = rhs.numberColumns_;
420  delete [] rhs.ray_;
421  rhs.ray_=NULL;
422  gutsOfCopy(rhs,false);
423}
424// Return model - nulls all arrays so can be deleted safely
425void 
426ClpModel::returnModel(ClpModel & otherModel)
427{
428  otherModel.objectiveValue_=objectiveValue_;
429  otherModel.numberIterations_ = numberIterations_;
430  otherModel.problemStatus_ = problemStatus_;
431  rowActivity_ = NULL;
432  columnActivity_ = NULL;
433  dual_ = NULL;
434  reducedCost_ = NULL;
435  rowLower_ = NULL;
436  rowUpper_ = NULL;
437  objective_ = NULL;
438  rowObjective_ = NULL;
439  columnLower_ = NULL;
440  columnUpper_ = NULL;
441  matrix_ = NULL;
442  rowCopy_ = NULL;
443  quadraticObjective_=NULL,
444  delete [] otherModel.ray_;
445  otherModel.ray_ = ray_;
446  ray_ = NULL;
447  // do status
448  if (otherModel.status_!=status_) {
449    delete [] otherModel.status_;
450    otherModel.status_ = status_;
451  }
452  status_ = NULL;
453  if (defaultHandler_) {
454    delete handler_;
455    handler_ = NULL;
456  }
457}
458//#############################################################################
459// Parameter related methods
460//#############################################################################
461
462bool
463ClpModel::setIntParam(ClpIntParam key, int value)
464{
465  switch (key) {
466  case ClpMaxNumIteration:
467    if (value < 0)
468      return false;
469    break;
470  case ClpMaxNumIterationHotStart:
471    if (value < 0)
472      return false;
473    break;
474  case ClpLastIntParam:
475    return false;
476  }
477  intParam_[key] = value;
478  return true;
479}
480
481//-----------------------------------------------------------------------------
482
483bool
484ClpModel::setDblParam(ClpDblParam key, double value)
485{
486
487  switch (key) {
488  case ClpDualObjectiveLimit:
489    break;
490
491  case ClpPrimalObjectiveLimit:
492    break;
493
494  case ClpDualTolerance: 
495    if (value<=0.0||value>1.0e10)
496      return false;
497    break;
498   
499  case ClpPrimalTolerance: 
500    if (value<=0.0||value>1.0e10)
501      return false;
502    break;
503   
504  case ClpObjOffset: 
505    break;
506
507  case ClpMaxSeconds: 
508    if(value>=0)
509      value += CoinCpuTime();
510    else
511      value = -1.0;
512    break;
513
514  case ClpLastDblParam:
515    return false;
516  }
517  dblParam_[key] = value;
518  return true;
519}
520
521//-----------------------------------------------------------------------------
522
523bool
524ClpModel::setStrParam(ClpStrParam key, const std::string & value)
525{
526
527  switch (key) {
528  case ClpProbName:
529    break;
530
531  case ClpLastStrParam:
532    return false;
533  }
534  strParam_[key] = value;
535  return true;
536}
537// Useful routines
538// Returns resized array and deletes incoming
539double * resizeDouble(double * array , int size, int newSize, double fill,
540                      bool createArray)
541{
542  if ((array||createArray)&&size!=newSize) {
543    int i;
544    double * newArray = new double[newSize];
545    if (array)
546      memcpy(newArray,array,min(newSize,size)*sizeof(double));
547    delete [] array;
548    array = newArray;
549    for (i=size;i<newSize;i++) 
550      array[i]=fill;
551  } 
552  return array;
553}
554// Returns resized array and updates size
555double * deleteDouble(double * array , int size, 
556                      int number, const int * which,int & newSize)
557{
558  if (array) {
559    int i ;
560    char * deleted = new char[size];
561    int numberDeleted=0;
562    memset(deleted,0,size*sizeof(char));
563    for (i=0;i<number;i++) {
564      int j = which[i];
565      if (j>=0&&j<size&&!deleted[j]) {
566        numberDeleted++;
567        deleted[j]=1;
568      }
569    }
570    newSize = size-numberDeleted;
571    double * newArray = new double[newSize];
572    int put=0;
573    for (i=0;i<size;i++) {
574      if (!deleted[i]) {
575        newArray[put++]=array[i];
576      }
577    }
578    delete [] array;
579    array = newArray;
580    delete [] deleted;
581  }
582  return array;
583}
584char * deleteChar(char * array , int size, 
585                  int number, const int * which,int & newSize,
586                  bool ifDelete)
587{
588  if (array) {
589    int i ;
590    char * deleted = new char[size];
591    int numberDeleted=0;
592    memset(deleted,0,size*sizeof(char));
593    for (i=0;i<number;i++) {
594      int j = which[i];
595      if (j>=0&&j<size&&!deleted[j]) {
596        numberDeleted++;
597        deleted[j]=1;
598      }
599    }
600    newSize = size-numberDeleted;
601    char * newArray = new char[newSize];
602    int put=0;
603    for (i=0;i<size;i++) {
604      if (!deleted[i]) {
605        newArray[put++]=array[i];
606      }
607    }
608    if (ifDelete)
609      delete [] array;
610    array = newArray;
611    delete [] deleted;
612  }
613  return array;
614}
615// Create empty ClpPackedMatrix
616void 
617ClpModel::createEmptyMatrix()
618{
619  delete matrix_;
620  CoinPackedMatrix matrix2;
621  matrix_=new ClpPackedMatrix(matrix2);
622}
623// Resizes
624void 
625ClpModel::resize (int newNumberRows, int newNumberColumns)
626{
627  rowActivity_ = resizeDouble(rowActivity_,numberRows_,
628                              newNumberRows,0.0,true);
629  dual_ = resizeDouble(dual_,numberRows_,
630                       newNumberRows,0.0,true);
631  rowObjective_ = resizeDouble(rowObjective_,numberRows_,
632                               newNumberRows,0.0,false);
633  rowLower_ = resizeDouble(rowLower_,numberRows_,
634                           newNumberRows,-COIN_DBL_MAX,true);
635  rowUpper_ = resizeDouble(rowUpper_,numberRows_,
636                           newNumberRows,COIN_DBL_MAX,true);
637  columnActivity_ = resizeDouble(columnActivity_,numberColumns_,
638                                 newNumberColumns,0.0,true);
639  reducedCost_ = resizeDouble(reducedCost_,numberColumns_,
640                              newNumberColumns,0.0,true);
641  if (objective_)
642    objective_->resize(newNumberColumns);
643  else 
644    objective_ = new ClpLinearObjective(NULL,newNumberColumns);
645  columnLower_ = resizeDouble(columnLower_,numberColumns_,
646                              newNumberColumns,0.0,true);
647  columnUpper_ = resizeDouble(columnUpper_,numberColumns_,
648                              newNumberColumns,COIN_DBL_MAX,true);
649  if (newNumberRows<numberRows_) {
650    int * which = new int[numberRows_-newNumberRows];
651    int i;
652    for (i=newNumberRows;i<numberRows_;i++) 
653      which[i-newNumberRows]=i;
654    matrix_->deleteRows(numberRows_-newNumberRows,which);
655    delete [] which;
656  }
657  if (numberRows_!=newNumberRows||numberColumns_!=newNumberColumns) {
658    // set state back to unknown
659    problemStatus_ = -1;
660    delete [] ray_;
661    ray_ = NULL;
662  }
663  if (status_) {
664    unsigned char * tempC = new unsigned char [newNumberColumns+newNumberRows];
665    unsigned char * tempR = tempC + newNumberColumns;
666    memset(tempC,0,(newNumberColumns+newNumberRows)*sizeof(unsigned char));
667    memcpy(tempC,status_,min(newNumberColumns,numberColumns_)*sizeof(unsigned char));
668    memcpy(tempR,status_+numberColumns_,min(newNumberRows,numberRows_)*sizeof(unsigned char));
669    delete [] status_;
670    status_ = tempC;
671  }
672  numberRows_ = newNumberRows;
673  if (newNumberColumns<numberColumns_) {
674    int * which = new int[numberColumns_-newNumberColumns];
675    int i;
676    for (i=newNumberColumns;i<numberColumns_;i++) 
677      which[i-newNumberColumns]=i;
678    matrix_->deleteCols(numberColumns_-newNumberColumns,which);
679    if (quadraticObjective_) {
680      quadraticObjective_->deleteCols(numberColumns_-newNumberColumns,which);
681      quadraticObjective_->deleteRows(numberColumns_-newNumberColumns,which);
682    }
683    delete [] which;
684  }
685  if (integerType_) {
686    char * temp = new char [newNumberColumns];
687    memset(temp,0,newNumberColumns*sizeof(char));
688    memcpy(temp,integerType_,
689           min(newNumberColumns,numberColumns_)*sizeof(char));
690    delete [] integerType_;
691    integerType_ = temp;
692  }
693  numberColumns_ = newNumberColumns;
694  // for now gets rid of names
695  lengthNames_ = 0;
696  rowNames_ = std::vector<std::string> ();
697  columnNames_ = std::vector<std::string> ();
698}
699// Deletes rows
700void 
701ClpModel::deleteRows(int number, const int * which)
702{
703  int newSize=0;
704  rowActivity_ = deleteDouble(rowActivity_,numberRows_,
705                              number, which, newSize);
706  dual_ = deleteDouble(dual_,numberRows_,
707                              number, which, newSize);
708  rowObjective_ = deleteDouble(rowObjective_,numberRows_,
709                              number, which, newSize);
710  rowLower_ = deleteDouble(rowLower_,numberRows_,
711                              number, which, newSize);
712  rowUpper_ = deleteDouble(rowUpper_,numberRows_,
713                              number, which, newSize);
714  matrix_->deleteRows(number,which);
715  //matrix_->removeGaps();
716  // status
717  if (status_) {
718    unsigned char * tempR  = (unsigned char *) deleteChar((char *)status_+numberColumns_,
719                                        numberRows_,
720                                        number, which, newSize,false);
721    unsigned char * tempC = new unsigned char [numberColumns_+newSize];
722    memcpy(tempC,status_,numberColumns_*sizeof(unsigned char));
723    memcpy(tempC+numberColumns_,tempR,newSize*sizeof(unsigned char));
724    delete [] tempR;
725    delete [] status_;
726    status_ = tempC;
727  }
728  numberRows_=newSize;
729  // set state back to unknown
730  problemStatus_ = -1;
731  delete [] ray_;
732  ray_ = NULL;
733  // for now gets rid of names
734  lengthNames_ = 0;
735  rowNames_ = std::vector<std::string> ();
736  columnNames_ = std::vector<std::string> ();
737}
738// Deletes columns
739void 
740ClpModel::deleteColumns(int number, const int * which)
741{
742  int newSize=0;
743  columnActivity_ = deleteDouble(columnActivity_,numberColumns_,
744                              number, which, newSize);
745  reducedCost_ = deleteDouble(reducedCost_,numberColumns_,
746                              number, which, newSize);
747  objective_->deleteSome(number, which);
748  columnLower_ = deleteDouble(columnLower_,numberColumns_,
749                              number, which, newSize);
750  columnUpper_ = deleteDouble(columnUpper_,numberColumns_,
751                              number, which, newSize);
752  matrix_->deleteCols(number,which);
753  //matrix_->removeGaps();
754  if (quadraticObjective_) {
755    quadraticObjective_->deleteCols(number,which);
756    quadraticObjective_->deleteRows(number,which);
757  }
758  // status
759  if (status_) {
760    unsigned char * tempC  = (unsigned char *) deleteChar((char *)status_,
761                                        numberColumns_,
762                                        number, which, newSize,false);
763    unsigned char * temp = new unsigned char [numberRows_+newSize];
764    memcpy(temp,tempC,newSize*sizeof(unsigned char));
765    memcpy(temp+newSize,status_+numberColumns_,
766           numberRows_*sizeof(unsigned char));
767    delete [] tempC;
768    delete [] status_;
769    status_ = temp;
770  }
771  integerType_ = deleteChar(integerType_,numberColumns_,
772                            number, which, newSize,true);
773  numberColumns_=newSize;
774  // set state back to unknown
775  problemStatus_ = -1;
776  delete [] ray_;
777  ray_ = NULL;
778  // for now gets rid of names
779  lengthNames_ = 0;
780  rowNames_ = std::vector<std::string> ();
781  columnNames_ = std::vector<std::string> ();
782}
783// Add rows
784void 
785ClpModel::addRows(int number, const double * rowLower, 
786                  const double * rowUpper,
787                  const int * rowStarts, const int * columns,
788                  const double * elements)
789{
790  // Create a list of CoinPackedVectors
791  if (number) {
792    CoinPackedVectorBase ** rows=
793      new CoinPackedVectorBase * [number];
794    int iRow;
795    for (iRow=0;iRow<number;iRow++) {
796      int iStart = rowStarts[iRow];
797      rows[iRow] = 
798        new CoinPackedVector(rowStarts[iRow+1]-iStart,
799                             columns+iStart,elements+iStart);
800    }
801    addRows(number, rowLower, rowUpper,
802            rows);
803    for (iRow=0;iRow<number;iRow++) 
804      delete rows[iRow];
805    delete [] rows;
806  }
807}
808// Add rows
809void 
810ClpModel::addRows(int number, const double * rowLower, 
811                  const double * rowUpper,
812                  const int * rowStarts, 
813                  const int * rowLengths, const int * columns,
814                  const double * elements)
815{
816  // Create a list of CoinPackedVectors
817  if (number) {
818    CoinPackedVectorBase ** rows=
819      new CoinPackedVectorBase * [number];
820    int iRow;
821    for (iRow=0;iRow<number;iRow++) {
822      int iStart = rowStarts[iRow];
823      rows[iRow] = 
824        new CoinPackedVector(rowLengths[iRow],
825                             columns+iStart,elements+iStart);
826    }
827    addRows(number, rowLower, rowUpper,
828            rows);
829    for (iRow=0;iRow<number;iRow++) 
830      delete rows[iRow];
831    delete [] rows;
832  }
833}
834void 
835ClpModel::addRows(int number, const double * rowLower, 
836                  const double * rowUpper,
837                  const CoinPackedVectorBase * const * rows)
838{
839  if (!number)
840    return;
841  int numberRowsNow = numberRows_;
842  resize(numberRowsNow+number,numberColumns_);
843  double * lower = rowLower_+numberRowsNow;
844  double * upper = rowUpper_+numberRowsNow;
845  int iRow;
846  if (rowLower) {
847    for (iRow = 0; iRow < number; iRow++) {
848      double value = rowLower[iRow];
849      if (value<-1.0e20)
850        value = -COIN_DBL_MAX;
851      lower[iRow]= value;
852    }
853  } else {
854    for (iRow = 0; iRow < number; iRow++) {
855      lower[iRow]= -COIN_DBL_MAX;
856    }
857  }
858  if (rowUpper) {
859    for (iRow = 0; iRow < number; iRow++) {
860      double value = rowUpper[iRow];
861      if (value>1.0e20)
862        value = COIN_DBL_MAX;
863      upper[iRow]= value;
864    }
865  } else {
866    for (iRow = 0; iRow < number; iRow++) {
867      upper[iRow]= COIN_DBL_MAX;
868    }
869  }
870  // Deal with matrix
871
872  delete rowCopy_;
873  rowCopy_=NULL;
874  if (!matrix_)
875    createEmptyMatrix();
876  // Use matrix() to get round virtual problem
877  matrix()->appendRows(number,rows);
878}
879// Add columns
880void 
881ClpModel::addColumns(int number, const double * columnLower, 
882                     const double * columnUpper,
883                     const double * objIn,
884                     const int * columnStarts, const int * rows,
885                     const double * elements)
886{
887  // Create a list of CoinPackedVectors
888  if (number) {
889    CoinPackedVectorBase ** columns=
890      new CoinPackedVectorBase * [number];
891    int iColumn;
892    for (iColumn=0;iColumn<number;iColumn++) {
893      int iStart = columnStarts[iColumn];
894      columns[iColumn] = 
895        new CoinPackedVector(columnStarts[iColumn+1]-iStart,
896                             rows+iStart,elements+iStart);
897    }
898    addColumns(number, columnLower, columnUpper,
899               objIn, columns);
900    for (iColumn=0;iColumn<number;iColumn++) 
901      delete columns[iColumn];
902    delete [] columns;
903
904  }
905}
906// Add columns
907void 
908ClpModel::addColumns(int number, const double * columnLower, 
909                     const double * columnUpper,
910                     const double * objIn,
911                     const int * columnStarts, 
912                     const int * columnLengths, const int * rows,
913                     const double * elements)
914{
915  // Create a list of CoinPackedVectors
916  if (number) {
917    CoinPackedVectorBase ** columns=
918      new CoinPackedVectorBase * [number];
919    int iColumn;
920    for (iColumn=0;iColumn<number;iColumn++) {
921      int iStart = columnStarts[iColumn];
922      columns[iColumn] = 
923        new CoinPackedVector(columnLengths[iColumn],
924                             rows+iStart,elements+iStart);
925    }
926    addColumns(number, columnLower, columnUpper,
927               objIn, columns);
928    for (iColumn=0;iColumn<number;iColumn++) 
929      delete columns[iColumn];
930    delete [] columns;
931
932  }
933}
934void 
935ClpModel::addColumns(int number, const double * columnLower, 
936                     const double * columnUpper,
937                     const double * objIn,
938                     const CoinPackedVectorBase * const * columns)
939{
940  if (!number)
941    return;
942  int numberColumnsNow = numberColumns_;
943  resize(numberRows_,numberColumnsNow+number);
944  double * lower = columnLower_+numberColumnsNow;
945  double * upper = columnUpper_+numberColumnsNow;
946  double * obj = objective()+numberColumnsNow;
947  int iColumn;
948  if (columnLower) {
949    for (iColumn = 0; iColumn < number; iColumn++) {
950      double value = columnLower[iColumn];
951      if (value<-1.0e20)
952        value = -COIN_DBL_MAX;
953      lower[iColumn]= value;
954    }
955  } else {
956    for (iColumn = 0; iColumn < number; iColumn++) {
957      lower[iColumn]= 0.0;
958    }
959  }
960  if (columnUpper) {
961    for (iColumn = 0; iColumn < number; iColumn++) {
962      double value = columnUpper[iColumn];
963      if (value>1.0e20)
964        value = COIN_DBL_MAX;
965      upper[iColumn]= value;
966    }
967  } else {
968    for (iColumn = 0; iColumn < number; iColumn++) {
969      upper[iColumn]= COIN_DBL_MAX;
970    }
971  }
972  if (objIn) {
973    for (iColumn = 0; iColumn < number; iColumn++) {
974      obj[iColumn] = objIn[iColumn];
975    }
976  } else {
977    for (iColumn = 0; iColumn < number; iColumn++) {
978      obj[iColumn]= 0.0;
979    }
980  }
981  // Deal with matrix
982
983  delete rowCopy_;
984  rowCopy_=NULL;
985  if (!matrix_)
986    createEmptyMatrix();
987  // Use matrix() to get round virtual problem
988  matrix()->appendCols(number,columns);
989}
990// Infeasibility/unbounded ray (NULL returned if none/wrong)
991double * 
992ClpModel::infeasibilityRay() const
993{
994  double * array = NULL;
995  if (problemStatus_==1) 
996    array = ClpCopyOfArray(ray_,numberRows_);
997  return array;
998}
999double * 
1000ClpModel::unboundedRay() const
1001{
1002  double * array = NULL;
1003  if (problemStatus_==2) 
1004    array = ClpCopyOfArray(ray_,numberColumns_);
1005  return array;
1006}
1007void 
1008ClpModel::setMaximumIterations(int value)
1009{
1010  if(value>=0)
1011    intParam_[ClpMaxNumIteration]=value;
1012}
1013void 
1014ClpModel::setMaximumSeconds(double value)
1015{
1016  if(value>=0)
1017    dblParam_[ClpMaxSeconds]=value+CoinCpuTime();
1018  else
1019    dblParam_[ClpMaxSeconds]=-1.0;
1020}
1021// Returns true if hit maximum iterations (or time)
1022bool 
1023ClpModel::hitMaximumIterations() const
1024{
1025  bool hitMax= (numberIterations_>=maximumIterations());
1026  if (dblParam_[ClpMaxSeconds]>=0.0&&!hitMax)
1027    hitMax = (CoinCpuTime()>=dblParam_[ClpMaxSeconds]);
1028  return hitMax;
1029}
1030// Pass in Message handler (not deleted at end)
1031void 
1032ClpModel::passInMessageHandler(CoinMessageHandler * handler)
1033{
1034  if (defaultHandler_)
1035    delete handler_;
1036  defaultHandler_=false;
1037  handler_=handler;
1038}
1039// Set language
1040void 
1041ClpModel::newLanguage(CoinMessages::Language language)
1042{
1043  messages_ = ClpMessage(language);
1044}
1045// Read an mps file from the given filename
1046int 
1047ClpModel::readMps(const char *fileName,
1048                  bool keepNames,
1049                  bool ignoreErrors)
1050{
1051  bool canOpen=false;
1052  if (!strcmp(fileName,"-")||!strcmp(fileName,"stdin")) {
1053    // stdin
1054    canOpen=true;
1055  } else {
1056    FILE *fp=fopen(fileName,"r");
1057    if (fp) {
1058      // can open - lets go for it
1059      fclose(fp);
1060      canOpen=true;
1061    } else {
1062      handler_->message(CLP_UNABLE_OPEN,messages_)
1063        <<fileName<<CoinMessageEol;
1064      return -1;
1065    }
1066  }
1067  CoinMpsIO m;
1068  double time1 = CoinCpuTime(),time2;
1069  int status=m.readMps(fileName,"");
1070  if (!status||ignoreErrors) {
1071    loadProblem(*m.getMatrixByCol(),
1072                m.getColLower(),m.getColUpper(),
1073                m.getObjCoefficients(),
1074                m.getRowLower(),m.getRowUpper());
1075    if (m.integerColumns()) {
1076      integerType_ = new char[numberColumns_];
1077      memcpy(integerType_,m.integerColumns(),numberColumns_*sizeof(char));
1078    } else {
1079      integerType_ = NULL;
1080    }
1081    // set problem name
1082    setStrParam(ClpProbName,m.getProblemName());
1083    // do names
1084    if (keepNames) {
1085      unsigned int maxLength=0;
1086      int iRow;
1087      rowNames_.reserve(numberRows_);
1088      for (iRow=0;iRow<numberRows_;iRow++) {
1089        const char * name = m.rowName(iRow);
1090        maxLength = max(maxLength,(unsigned int) strlen(name));
1091          rowNames_.push_back(name);
1092      }
1093     
1094      int iColumn;
1095      columnNames_.reserve(numberColumns_);
1096      for (iColumn=0;iColumn<numberColumns_;iColumn++) {
1097        const char * name = m.columnName(iColumn);
1098        maxLength = max(maxLength,(unsigned int) strlen(name));
1099        columnNames_.push_back(name);
1100      }
1101      lengthNames_=(int) maxLength;
1102    } else {
1103      lengthNames_=0;
1104    }
1105    setDblParam(ClpObjOffset,m.objectiveOffset());
1106    time2 = CoinCpuTime();
1107    handler_->message(CLP_IMPORT_RESULT,messages_)
1108      <<fileName
1109      <<time2-time1<<CoinMessageEol;
1110  } else {
1111    // errors
1112    handler_->message(CLP_IMPORT_ERRORS,messages_)
1113      <<status<<fileName<<CoinMessageEol;
1114  }
1115
1116  return status;
1117}
1118bool ClpModel::isPrimalObjectiveLimitReached() const
1119{
1120  double limit = 0.0;
1121  getDblParam(ClpPrimalObjectiveLimit, limit);
1122  if (limit > 1e30) {
1123    // was not ever set
1124    return false;
1125  }
1126   
1127  const double obj = objectiveValue();
1128  const int maxmin = optimizationDirection();
1129
1130  if (problemStatus_ == 0) // optimal
1131    return maxmin > 0 ? (obj < limit) /*minim*/ : (obj > limit) /*maxim*/;
1132  else if (problemStatus_==2)
1133    return true;
1134  else
1135    return false;
1136}
1137
1138bool ClpModel::isDualObjectiveLimitReached() const
1139{
1140
1141  double limit = 0.0;
1142  getDblParam(ClpDualObjectiveLimit, limit);
1143  if (limit > 1e30) {
1144    // was not ever set
1145    return false;
1146  }
1147   
1148  const double obj = objectiveValue();
1149  const int maxmin = optimizationDirection();
1150
1151  if (problemStatus_ == 0) // optimal
1152    return maxmin > 0 ? (obj > limit) /*minim*/ : (obj < limit) /*maxim*/;
1153  else if (problemStatus_==1)
1154    return true;
1155  else
1156    return false;
1157
1158}
1159void 
1160ClpModel::copyInIntegerInformation(const char * information)
1161{
1162  delete [] integerType_;
1163  if (information) {
1164    integerType_ = new char[numberColumns_];
1165    memcpy(integerType_,information,numberColumns_*sizeof(char));
1166  } else {
1167    integerType_ = NULL;
1168  }
1169}
1170// Drops names - makes lengthnames 0 and names empty
1171void 
1172ClpModel::dropNames()
1173{
1174  lengthNames_=0;
1175  rowNames_ = std::vector<std::string> ();
1176  columnNames_ = std::vector<std::string> ();
1177}
1178// Drop integer informations
1179void 
1180ClpModel::deleteIntegerInformation()
1181{
1182  delete [] integerType_;
1183  integerType_ = NULL;
1184}
1185/* Return copy of status array (char[numberRows+numberColumns]),
1186   use delete [] */
1187unsigned char * 
1188ClpModel::statusCopy() const
1189{
1190  return ClpCopyOfArray(status_,numberRows_+numberColumns_);
1191}
1192// Copy in status vector
1193void 
1194ClpModel::copyinStatus(const unsigned char * statusArray)
1195{
1196  delete [] status_;
1197  if (statusArray) {
1198    status_ = new unsigned char [numberRows_+numberColumns_];
1199    memcpy(status_,statusArray,(numberRows_+numberColumns_)*sizeof(unsigned char));
1200  } else {
1201    status_=NULL;
1202  }
1203}
1204
1205// Load up quadratic objective
1206void 
1207ClpModel::loadQuadraticObjective(const int numberColumns, const CoinBigIndex * start,
1208                              const int * column, const double * element)
1209{
1210  assert (numberColumns==numberColumns_);
1211  quadraticObjective_ = new CoinPackedMatrix(true,numberColumns,numberColumns,
1212                                             start[numberColumns],element,column,start,NULL);
1213}
1214void 
1215ClpModel::loadQuadraticObjective (  const CoinPackedMatrix& matrix)
1216{
1217  assert (matrix.getNumCols()==numberColumns_);
1218  quadraticObjective_ = new CoinPackedMatrix(matrix);
1219}
1220// Get rid of quadratic objective
1221void 
1222ClpModel::deleteQuadraticObjective()
1223{
1224  delete quadraticObjective_;
1225  quadraticObjective_ = NULL;
1226}
1227// Returns resized array and updates size
1228double * whichDouble(double * array , int number, const int * which)
1229{
1230  double * newArray=NULL;
1231  if (array&&number) {
1232    int i ;
1233    newArray = new double[number];
1234    for (i=0;i<number;i++) 
1235      newArray[i]=array[which[i]];
1236  }
1237  return newArray;
1238}
1239char * whichChar(char * array , int number, const int * which)
1240{
1241  char * newArray=NULL;
1242  if (array&&number) {
1243    int i ;
1244    newArray = new char[number];
1245    for (i=0;i<number;i++) 
1246      newArray[i]=array[which[i]];
1247  }
1248  return newArray;
1249}
1250unsigned char * whichUnsignedChar(unsigned char * array , 
1251                                  int number, const int * which)
1252{
1253  unsigned char * newArray=NULL;
1254  if (array&&number) {
1255    int i ;
1256    newArray = new unsigned char[number];
1257    for (i=0;i<number;i++) 
1258      newArray[i]=array[which[i]];
1259  }
1260  return newArray;
1261}
1262// Subproblem constructor
1263ClpModel::ClpModel ( const ClpModel * rhs,
1264                     int numberRows, const int * whichRow,
1265                     int numberColumns, const int * whichColumn,
1266                     bool dropNames, bool dropIntegers)
1267{
1268#if 0
1269  // Could be recoded to be faster and take less memory
1270  // and to allow re-ordering and duplicates etc
1271  gutsOfCopy(*rhs,true);
1272  int numberRowsWhole = rhs->numberRows();
1273  int * delRow = new int[numberRowsWhole];
1274  memset(delRow,0,numberRowsWhole*sizeof(int));
1275  int i;
1276  for (i=0;i<numberRows;i++) {
1277    int iRow=whichRow[i];
1278    assert (iRow>=0&&iRow<numberRowsWhole);
1279    delRow[iRow]=1;
1280  }
1281  numberRows=0;
1282  for (i=0;i<numberRowsWhole;i++) {
1283    if (delRow[i]==0)
1284      delRow[numberRows++]=i;
1285  }
1286  deleteRows(numberRows,delRow);
1287  delete [] delRow;
1288  int numberColumnsWhole = rhs->numberColumns();
1289  int * delColumn = new int[numberColumnsWhole];
1290  memset(delColumn,0,numberColumnsWhole*sizeof(int));
1291  for (i=0;i<numberColumns;i++) {
1292    int iColumn=whichColumn[i];
1293    assert (iColumn>=0&&iColumn<numberColumnsWhole);
1294    delColumn[iColumn]=1;
1295  }
1296  numberColumns=0;
1297  for (i=0;i<numberColumnsWhole;i++) {
1298    if (delColumn[i]==0)
1299      delColumn[numberColumns++]=i;
1300  }
1301  deleteColumns(numberColumns,delColumn);
1302  delete [] delColumn;
1303#else
1304  defaultHandler_ = rhs->defaultHandler_;
1305  if (defaultHandler_)
1306    handler_ = new CoinMessageHandler(*rhs->handler_);
1307   else
1308    handler_ = rhs->handler_;
1309  messages_ = rhs->messages_;
1310  intParam_[ClpMaxNumIteration] = rhs->intParam_[ClpMaxNumIteration];
1311  intParam_[ClpMaxNumIterationHotStart] =
1312    rhs->intParam_[ClpMaxNumIterationHotStart];
1313
1314  dblParam_[ClpDualObjectiveLimit] = rhs->dblParam_[ClpDualObjectiveLimit];
1315  dblParam_[ClpPrimalObjectiveLimit] = rhs->dblParam_[ClpPrimalObjectiveLimit];
1316  dblParam_[ClpDualTolerance] = rhs->dblParam_[ClpDualTolerance];
1317  dblParam_[ClpPrimalTolerance] = rhs->dblParam_[ClpPrimalTolerance];
1318  dblParam_[ClpObjOffset] = rhs->dblParam_[ClpObjOffset];
1319  dblParam_[ClpMaxSeconds] = rhs->dblParam_[ClpMaxSeconds];
1320
1321  strParam_[ClpProbName] = rhs->strParam_[ClpProbName];
1322
1323  optimizationDirection_ = rhs->optimizationDirection_;
1324  objectiveValue_=rhs->objectiveValue_;
1325  smallElement_ = rhs->smallElement_;
1326  numberIterations_ = rhs->numberIterations_;
1327  solveType_ = rhs->solveType_;
1328  problemStatus_ = rhs->problemStatus_;
1329  // check valid lists
1330  int numberBad=0;
1331  int i;
1332  for (i=0;i<numberRows;i++)
1333    if (whichRow[i]<0||whichRow[i]>=rhs->numberRows_)
1334      numberBad++;
1335  if (numberBad)
1336    throw CoinError("bad row list", "subproblem constructor", "ClpModel");
1337  numberBad=0;
1338  for (i=0;i<numberColumns;i++)
1339    if (whichColumn[i]<0||whichColumn[i]>=rhs->numberColumns_)
1340      numberBad++;
1341  if (numberBad)
1342    throw CoinError("bad column list", "subproblem constructor", "ClpModel");
1343  numberRows_ = numberRows;
1344  numberColumns_ = numberColumns;
1345  if (!dropNames) {
1346    unsigned int maxLength=0;
1347    int iRow;
1348    rowNames_.reserve(numberRows_);
1349    for (iRow=0;iRow<numberRows_;iRow++) {
1350      rowNames_[iRow] = rhs->rowNames_[whichRow[iRow]];
1351      maxLength = max(maxLength,(unsigned int) strlen(rowNames_[iRow].c_str()));
1352    }
1353    int iColumn;
1354    columnNames_.reserve(numberColumns_);
1355    for (iColumn=0;iColumn<numberColumns_;iColumn++) {
1356      columnNames_[iColumn] = rhs->columnNames_[whichColumn[iColumn]];
1357      maxLength = max(maxLength,(unsigned int) strlen(columnNames_[iColumn].c_str()));
1358    }
1359    lengthNames_=(int) maxLength;
1360  } else {
1361    lengthNames_ = 0;
1362    rowNames_ = std::vector<std::string> ();
1363    columnNames_ = std::vector<std::string> ();
1364  }
1365  if (rhs->integerType_&&!dropIntegers) {
1366    integerType_ = whichChar(rhs->integerType_,numberColumns,whichColumn);
1367  } else {
1368    integerType_ = NULL;
1369  }
1370  if (rhs->rowActivity_) {
1371    rowActivity_=whichDouble(rhs->rowActivity_,numberRows,whichRow);
1372    dual_=whichDouble(rhs->dual_,numberRows,whichRow);
1373    columnActivity_=whichDouble(rhs->columnActivity_,numberColumns,
1374                                whichColumn);
1375    reducedCost_=whichDouble(rhs->reducedCost_,numberColumns,
1376                                whichColumn);
1377  } else {
1378    rowActivity_=NULL;
1379    columnActivity_=NULL;
1380    dual_=NULL;
1381    reducedCost_=NULL;
1382  }
1383  rowLower_=whichDouble(rhs->rowLower_,numberRows,whichRow);
1384  rowUpper_=whichDouble(rhs->rowUpper_,numberRows,whichRow);
1385  columnLower_=whichDouble(rhs->columnLower_,numberColumns,whichColumn);
1386  columnUpper_=whichDouble(rhs->columnUpper_,numberColumns,whichColumn);
1387  if (rhs->objective_)
1388    objective_  = rhs->objective_->subsetClone(numberColumns,whichColumn);
1389  else
1390    objective_ = NULL;
1391  rowObjective_=whichDouble(rhs->rowObjective_,numberRows,whichRow);
1392  // status has to be done in two stages
1393  status_ = new unsigned char[numberColumns_+numberRows_];
1394  unsigned char * rowStatus = whichUnsignedChar(rhs->status_+rhs->numberColumns_,
1395                                                numberRows_,whichRow);
1396  unsigned char * columnStatus = whichUnsignedChar(rhs->status_,
1397                                                numberColumns_,whichColumn);
1398  memcpy(status_+numberColumns_,rowStatus,numberRows_);
1399  delete [] rowStatus;
1400  memcpy(status_,columnStatus,numberColumns_);
1401  delete [] columnStatus;
1402  ray_ = NULL;
1403  if (problemStatus_==1)
1404    ray_ = whichDouble (rhs->ray_,numberRows,whichRow);
1405  else if (problemStatus_==2)
1406    ray_ = whichDouble (rhs->ray_,numberColumns,whichColumn);
1407  if (rhs->rowCopy_) {
1408    rowCopy_ = rhs->rowCopy_->subsetClone(numberRows,whichRow,
1409                                          numberColumns,whichColumn);
1410  } else {
1411    rowCopy_=NULL;
1412  }
1413  if (rhs->quadraticObjective_) {
1414    quadraticObjective_ = new CoinPackedMatrix(*rhs->quadraticObjective_,
1415                                               numberColumns,whichColumn,
1416                                               numberColumns,whichColumn);
1417  } else {
1418    quadraticObjective_=NULL;
1419  }
1420  matrix_=NULL;
1421  if (rhs->matrix_) {
1422    matrix_ = rhs->matrix_->subsetClone(numberRows,whichRow,
1423                                        numberColumns,whichColumn);
1424  }
1425#endif
1426}
1427//#############################################################################
1428// Constructors / Destructor / Assignment
1429//#############################################################################
1430
1431//-------------------------------------------------------------------
1432// Default Constructor
1433//-------------------------------------------------------------------
1434ClpDataSave::ClpDataSave () 
1435{
1436  dualBound_ = 0.0;
1437  infeasibilityCost_ = 0.0;
1438  sparseThreshold_ = 0;
1439  perturbation_ = 0;
1440}
1441
1442//-------------------------------------------------------------------
1443// Copy constructor
1444//-------------------------------------------------------------------
1445ClpDataSave::ClpDataSave (const ClpDataSave & rhs) 
1446{ 
1447  dualBound_ = rhs.dualBound_;
1448  infeasibilityCost_ = rhs.infeasibilityCost_;
1449  sparseThreshold_ = rhs.sparseThreshold_;
1450  perturbation_ = rhs.perturbation_;
1451}
1452
1453//-------------------------------------------------------------------
1454// Destructor
1455//-------------------------------------------------------------------
1456ClpDataSave::~ClpDataSave ()
1457{
1458
1459}
1460
1461//----------------------------------------------------------------
1462// Assignment operator
1463//-------------------------------------------------------------------
1464ClpDataSave &
1465ClpDataSave::operator=(const ClpDataSave& rhs)
1466{
1467  if (this != &rhs) {
1468    dualBound_ = rhs.dualBound_;
1469    infeasibilityCost_ = rhs.infeasibilityCost_;
1470    sparseThreshold_ = rhs.sparseThreshold_;
1471    perturbation_ = rhs.perturbation_;
1472  }
1473  return *this;
1474}
Note: See TracBrowser for help on using the repository browser.