source: trunk/ClpModel.cpp @ 225

Last change on this file since 225 was 225, checked in by forrest, 16 years ago

This should break everything

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