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

Last change on this file since 1541 was 1541, checked in by stefan, 11 years ago

merge chgset 1536 from stable/1.11 into trunk: do not copy ray_ if it is NULL in ClpModel::infeasibilityRay

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