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

Last change on this file since 1792 was 1792, checked in by forrest, 8 years ago

obscure bug on mix of adds using simplex and coinmodel

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