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

Last change on this file since 1594 was 1594, checked in by lou, 10 years ago

Documentation.

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