source: stable/1.15/Clp/src/ClpModel.cpp @ 1989

Last change on this file since 1989 was 1957, checked in by forrest, 6 years ago

llow mor adding columns without elements

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 167.6 KB
Line 
1/* $Id: ClpModel.cpp 1957 2013-05-15 08:58:19Z 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] = 1;
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     randomNumberGenerator_ = rhs.randomNumberGenerator_;
747     if (trueCopy >= 0) {
748          if (defaultHandler_)
749               handler_ = new CoinMessageHandler(*rhs.handler_);
750          else
751               handler_ = rhs.handler_;
752          eventHandler_ = rhs.eventHandler_->clone();
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// Deletes rows AND columns (does not reallocate)
1587void 
1588ClpModel::deleteRowsAndColumns(int numberRows, const int * whichRows,
1589                               int numberColumns, const int * whichColumns)
1590{
1591  if (!numberColumns) {
1592    deleteRows(numberRows,whichRows);
1593  } else if (!numberRows) {
1594    deleteColumns(numberColumns,whichColumns);
1595  } else {
1596    whatsChanged_ &= ~511; // all changed
1597    bool doStatus = status_!=NULL;
1598    int numberTotal=numberRows_+numberColumns_;
1599    int * backRows = new int [numberTotal];
1600    int * backColumns = backRows+numberRows_;
1601    memset(backRows,0,numberTotal*sizeof(int));
1602    int newNumberColumns=0;
1603    for (int i=0;i<numberColumns;i++) {
1604      int iColumn=whichColumns[i];
1605      if (iColumn>=0&&iColumn<numberColumns_)
1606        backColumns[iColumn]=-1;
1607    }
1608    assert (objective_->type()==1);
1609    double * obj = objective(); 
1610    for (int i=0;i<numberColumns_;i++) {
1611      if (!backColumns[i]) {
1612        columnActivity_[newNumberColumns] = columnActivity_[i];
1613        reducedCost_[newNumberColumns] = reducedCost_[i];
1614        obj[newNumberColumns] = obj[i];
1615        columnLower_[newNumberColumns] = columnLower_[i];
1616        columnUpper_[newNumberColumns] = columnUpper_[i];
1617        if (doStatus)
1618          status_[newNumberColumns] = status_[i];
1619        backColumns[i]=newNumberColumns++;
1620      }
1621    }
1622    integerType_ = deleteChar(integerType_, numberColumns_,
1623                              numberColumns, whichColumns, newNumberColumns, true);
1624#ifndef CLP_NO_STD
1625    // Now works if which out of order
1626    if (lengthNames_) {
1627      for (int i=0;i<numberColumns_;i++) {
1628        int iColumn=backColumns[i];
1629        if (iColumn) 
1630          columnNames_[iColumn] = columnNames_[i];
1631      }
1632      columnNames_.erase(columnNames_.begin() + newNumberColumns, columnNames_.end());
1633    }
1634#endif
1635    int newNumberRows=0;
1636    assert (!rowObjective_);
1637    unsigned char * status2 = status_ + numberColumns_;
1638    unsigned char * status2a = status_ + newNumberColumns;
1639    for (int i=0;i<numberRows;i++) {
1640      int iRow=whichRows[i];
1641      if (iRow>=0&&iRow<numberRows_)
1642        backRows[iRow]=-1;
1643    }
1644    for (int i=0;i<numberRows_;i++) {
1645      if (!backRows[i]) {
1646        rowActivity_[newNumberRows] = rowActivity_[i];
1647        dual_[newNumberRows] = dual_[i];
1648        rowLower_[newNumberRows] = rowLower_[i];
1649        rowUpper_[newNumberRows] = rowUpper_[i];
1650        if (doStatus)
1651          status2a[newNumberRows] = status2[i];
1652        backRows[i]=newNumberRows++;
1653      }
1654    }
1655#ifndef CLP_NO_STD
1656    // Now works if which out of order
1657    if (lengthNames_) {
1658      for (int i=0;i<numberRows_;i++) {
1659        int iRow=backRows[i];
1660        if (iRow) 
1661          rowNames_[iRow] = rowNames_[i];
1662      }
1663      rowNames_.erase(rowNames_.begin() + newNumberRows, rowNames_.end());
1664    }
1665#endif
1666    // possible matrix is not full
1667    ClpPackedMatrix * clpMatrix = dynamic_cast<ClpPackedMatrix *>(matrix_);
1668    CoinPackedMatrix * matrix = clpMatrix ? clpMatrix->matrix() : NULL;
1669    if (matrix_->getNumCols() < numberColumns_) {
1670      assert (matrix);
1671      CoinBigIndex nel=matrix->getNumElements();
1672      int n=matrix->getNumCols();
1673      matrix->reserve(numberColumns_,nel);
1674      CoinBigIndex * columnStart = matrix->getMutableVectorStarts();
1675      int * columnLength = matrix->getMutableVectorLengths();
1676      for (int i=n;i<numberColumns_;i++) {
1677        columnStart[i]=nel;
1678        columnLength[i]=0;
1679      }
1680    }
1681    if (matrix) {
1682      matrix->setExtraMajor(0.1);
1683      //CoinPackedMatrix temp(*matrix);
1684      matrix->setExtraGap(0.0);
1685      matrix->setExtraMajor(0.0);
1686      int * row = matrix->getMutableIndices();
1687      CoinBigIndex * columnStart = matrix->getMutableVectorStarts();
1688      int * columnLength = matrix->getMutableVectorLengths();
1689      double * element = matrix->getMutableElements();
1690      newNumberColumns=0;
1691      CoinBigIndex n=0;
1692      for (int iColumn=0;iColumn<numberColumns_;iColumn++) {
1693        if (backColumns[iColumn]>=0) {
1694          CoinBigIndex start = columnStart[iColumn];
1695          int nSave=n;
1696          columnStart[newNumberColumns]=n;
1697          for (CoinBigIndex j=start;j<start+columnLength[iColumn];j++) {
1698            int iRow=row[j];
1699            iRow = backRows[iRow];
1700            if (iRow>=0) {
1701              row[n]=iRow;
1702              element[n++]=element[j];
1703            }
1704          }
1705          columnLength[newNumberColumns++]=n-nSave;
1706        }
1707      }
1708      columnStart[newNumberColumns]=n;
1709      matrix->setNumElements(n);
1710      matrix->setMajorDim(newNumberColumns);
1711      matrix->setMinorDim(newNumberRows);
1712      clpMatrix->setNumberActiveColumns(newNumberColumns);
1713      //temp.deleteRows(numberRows, whichRows);
1714      //temp.deleteCols(numberColumns, whichColumns);
1715      //assert(matrix->isEquivalent2(temp));
1716      //*matrix=temp;
1717    } else {
1718      matrix_->deleteRows(numberRows, whichRows);
1719      matrix_->deleteCols(numberColumns, whichColumns);
1720    }
1721    numberColumns_ = newNumberColumns;
1722    numberRows_ = newNumberRows;
1723    delete [] backRows;
1724    // set state back to unknown
1725    problemStatus_ = -1;
1726    secondaryStatus_ = 0;
1727    delete [] ray_;
1728    ray_ = NULL;
1729    if (savedRowScale_ != rowScale_) {
1730      delete [] rowScale_;
1731      delete [] columnScale_;
1732    }
1733    rowScale_ = NULL;
1734    columnScale_ = NULL;
1735    delete scaledMatrix_;
1736    scaledMatrix_ = NULL;
1737    delete rowCopy_;
1738    rowCopy_ = NULL;
1739  }
1740}
1741// Add one row
1742void
1743ClpModel::addRow(int numberInRow, const int * columns,
1744                 const double * elements, double rowLower, double rowUpper)
1745{
1746     CoinBigIndex starts[2];
1747     starts[0] = 0;
1748     starts[1] = numberInRow;
1749     addRows(1, &rowLower, &rowUpper, starts, columns, elements);
1750}
1751// Add rows
1752void
1753ClpModel::addRows(int number, const double * rowLower,
1754                  const double * rowUpper,
1755                  const CoinBigIndex * rowStarts, const int * columns,
1756                  const double * elements)
1757{
1758     if (number) {
1759          whatsChanged_ &= ~(1 + 2 + 8 + 16 + 32); // all except columns changed
1760          int numberRowsNow = numberRows_;
1761          resize(numberRowsNow + number, numberColumns_);
1762          double * lower = rowLower_ + numberRowsNow;
1763          double * upper = rowUpper_ + numberRowsNow;
1764          int iRow;
1765          if (rowLower) {
1766               for (iRow = 0; iRow < number; iRow++) {
1767                    double value = rowLower[iRow];
1768                    if (value < -1.0e20)
1769                         value = -COIN_DBL_MAX;
1770                    lower[iRow] = value;
1771               }
1772          } else {
1773               for (iRow = 0; iRow < number; iRow++) {
1774                    lower[iRow] = -COIN_DBL_MAX;
1775               }
1776          }
1777          if (rowUpper) {
1778               for (iRow = 0; iRow < number; iRow++) {
1779                    double value = rowUpper[iRow];
1780                    if (value > 1.0e20)
1781                         value = COIN_DBL_MAX;
1782                    upper[iRow] = value;
1783               }
1784          } else {
1785               for (iRow = 0; iRow < number; iRow++) {
1786                    upper[iRow] = COIN_DBL_MAX;
1787               }
1788          }
1789          // Deal with matrix
1790
1791          delete rowCopy_;
1792          rowCopy_ = NULL;
1793          delete scaledMatrix_;
1794          scaledMatrix_ = NULL;
1795          if (!matrix_)
1796               createEmptyMatrix();
1797          setRowScale(NULL);
1798          setColumnScale(NULL);
1799#ifndef CLP_NO_STD
1800          if (lengthNames_) {
1801               rowNames_.resize(numberRows_);
1802          }
1803#endif
1804          if (rowStarts) {
1805               // Make sure matrix has correct number of columns
1806               matrix_->getPackedMatrix()->reserve(numberColumns_, 0, true);
1807               matrix_->appendMatrix(number, 0, rowStarts, columns, elements);
1808          }
1809     }
1810}
1811// Add rows
1812void
1813ClpModel::addRows(int number, const double * rowLower,
1814                  const double * rowUpper,
1815                  const CoinBigIndex * rowStarts,
1816                  const int * rowLengths, const int * columns,
1817                  const double * elements)
1818{
1819     if (number) {
1820          CoinBigIndex numberElements = 0;
1821          int iRow;
1822          for (iRow = 0; iRow < number; iRow++)
1823               numberElements += rowLengths[iRow];
1824          int * newStarts = new int[number+1];
1825          int * newIndex = new int[numberElements];
1826          double * newElements = new double[numberElements];
1827          numberElements = 0;
1828          newStarts[0] = 0;
1829          for (iRow = 0; iRow < number; iRow++) {
1830               int iStart = rowStarts[iRow];
1831               int length = rowLengths[iRow];
1832               CoinMemcpyN(columns + iStart, length, newIndex + numberElements);
1833               CoinMemcpyN(elements + iStart, length, newElements + numberElements);
1834               numberElements += length;
1835               newStarts[iRow+1] = numberElements;
1836          }
1837          addRows(number, rowLower, rowUpper,
1838                  newStarts, newIndex, newElements);
1839          delete [] newStarts;
1840          delete [] newIndex;
1841          delete [] newElements;
1842     }
1843}
1844#ifndef CLP_NO_VECTOR
1845void
1846ClpModel::addRows(int number, const double * rowLower,
1847                  const double * rowUpper,
1848                  const CoinPackedVectorBase * const * rows)
1849{
1850     if (!number)
1851          return;
1852     whatsChanged_ &= ~(1 + 2 + 8 + 16 + 32); // all except columns changed
1853     int numberRowsNow = numberRows_;
1854     resize(numberRowsNow + number, numberColumns_);
1855     double * lower = rowLower_ + numberRowsNow;
1856     double * upper = rowUpper_ + numberRowsNow;
1857     int iRow;
1858     if (rowLower) {
1859          for (iRow = 0; iRow < number; iRow++) {
1860               double value = rowLower[iRow];
1861               if (value < -1.0e20)
1862                    value = -COIN_DBL_MAX;
1863               lower[iRow] = value;
1864          }
1865     } else {
1866          for (iRow = 0; iRow < number; iRow++) {
1867               lower[iRow] = -COIN_DBL_MAX;
1868          }
1869     }
1870     if (rowUpper) {
1871          for (iRow = 0; iRow < number; iRow++) {
1872               double value = rowUpper[iRow];
1873               if (value > 1.0e20)
1874                    value = COIN_DBL_MAX;
1875               upper[iRow] = value;
1876          }
1877     } else {
1878          for (iRow = 0; iRow < number; iRow++) {
1879               upper[iRow] = COIN_DBL_MAX;
1880          }
1881     }
1882     // Deal with matrix
1883
1884     delete rowCopy_;
1885     rowCopy_ = NULL;
1886     delete scaledMatrix_;
1887     scaledMatrix_ = NULL;
1888     if (!matrix_)
1889          createEmptyMatrix();
1890     if (rows)
1891          matrix_->appendRows(number, rows);
1892     setRowScale(NULL);
1893     setColumnScale(NULL);
1894     if (lengthNames_) {
1895          rowNames_.resize(numberRows_);
1896     }
1897}
1898#endif
1899#ifndef SLIM_CLP
1900// Add rows from a build object
1901int
1902ClpModel::addRows(const CoinBuild & buildObject, bool tryPlusMinusOne, bool checkDuplicates)
1903{
1904     CoinAssertHint (buildObject.type() == 0, "Looks as if both addRows and addCols being used"); // check correct
1905     int number = buildObject.numberRows();
1906     int numberErrors = 0;
1907     if (number) {
1908          CoinBigIndex size = 0;
1909          int iRow;
1910          double * lower = new double [number];
1911          double * upper = new double [number];
1912          if ((!matrix_ || !matrix_->getNumElements()) && tryPlusMinusOne) {
1913               // See if can be +-1
1914               for (iRow = 0; iRow < number; iRow++) {
1915                    const int * columns;
1916                    const double * elements;
1917                    int numberElements = buildObject.row(iRow, lower[iRow],
1918                                                         upper[iRow],
1919                                                         columns, elements);
1920                    for (int i = 0; i < numberElements; i++) {
1921                         // allow for zero elements
1922                         if (elements[i]) {
1923                              if (fabs(elements[i]) == 1.0) {
1924                                   size++;
1925                              } else {
1926                                   // bad
1927                                   tryPlusMinusOne = false;
1928                              }
1929                         }
1930                    }
1931                    if (!tryPlusMinusOne)
1932                         break;
1933               }
1934          } else {
1935               // Will add to whatever sort of matrix exists
1936               tryPlusMinusOne = false;
1937          }
1938          if (!tryPlusMinusOne) {
1939               CoinBigIndex numberElements = buildObject.numberElements();
1940               CoinBigIndex * starts = new CoinBigIndex [number+1];
1941               int * column = new int[numberElements];
1942               double * element = new double[numberElements];
1943               starts[0] = 0;
1944               numberElements = 0;
1945               for (iRow = 0; iRow < number; iRow++) {
1946                    const int * columns;
1947                    const double * elements;
1948                    int numberElementsThis = buildObject.row(iRow, lower[iRow], upper[iRow],
1949                                             columns, elements);
1950                    CoinMemcpyN(columns, numberElementsThis, column + numberElements);
1951                    CoinMemcpyN(elements, numberElementsThis, element + numberElements);
1952                    numberElements += numberElementsThis;
1953                    starts[iRow+1] = numberElements;
1954               }
1955               addRows(number, lower, upper, NULL);
1956               // make sure matrix has enough columns
1957               matrix_->setDimensions(-1, numberColumns_);
1958               numberErrors = matrix_->appendMatrix(number, 0, starts, column, element,
1959                                                    checkDuplicates ? numberColumns_ : -1);
1960               delete [] starts;
1961               delete [] column;
1962               delete [] element;
1963          } else {
1964               char * which = NULL; // for duplicates
1965               if (checkDuplicates) {
1966                    which = new char[numberColumns_];
1967                    CoinZeroN(which, numberColumns_);
1968               }
1969               // build +-1 matrix
1970               // arrays already filled in
1971               addRows(number, lower, upper, NULL);
1972               CoinBigIndex * startPositive = new CoinBigIndex [numberColumns_+1];
1973               CoinBigIndex * startNegative = new CoinBigIndex [numberColumns_];
1974               int * indices = new int [size];
1975               CoinZeroN(startPositive, numberColumns_);
1976               CoinZeroN(startNegative, numberColumns_);
1977               int maxColumn = -1;
1978               // need two passes
1979               for (iRow = 0; iRow < number; iRow++) {
1980                    const int * columns;
1981                    const double * elements;
1982                    int numberElements = buildObject.row(iRow, lower[iRow],
1983                                                         upper[iRow],
1984                                                         columns, elements);
1985                    for (int i = 0; i < numberElements; i++) {
1986                         int iColumn = columns[i];
1987                         if (checkDuplicates) {
1988                              if (iColumn >= numberColumns_) {
1989                                   if(which[iColumn])
1990                                        numberErrors++;
1991                                   else
1992                                        which[iColumn] = 1;
1993                              } else {
1994                                   numberErrors++;
1995                                   // and may as well switch off
1996                                   checkDuplicates = false;
1997                              }
1998                         }
1999                         maxColumn = CoinMax(maxColumn, iColumn);
2000                         if (elements[i] == 1.0) {
2001                              startPositive[iColumn]++;
2002                         } else if (elements[i] == -1.0) {
2003                              startNegative[iColumn]++;
2004                         }
2005                    }
2006                    if (checkDuplicates) {
2007                         for (int i = 0; i < numberElements; i++) {
2008                              int iColumn = columns[i];
2009                              which[iColumn] = 0;
2010                         }
2011                    }
2012               }
2013               // check size
2014               int numberColumns = maxColumn + 1;
2015               CoinAssertHint (numberColumns <= numberColumns_,
2016                               "rows having column indices >= numberColumns_");
2017               size = 0;
2018               int iColumn;
2019               for (iColumn = 0; iColumn < numberColumns_; iColumn++) {
2020                    CoinBigIndex n = startPositive[iColumn];
2021                    startPositive[iColumn] = size;
2022                    size += n;
2023                    n = startNegative[iColumn];
2024                    startNegative[iColumn] = size;
2025                    size += n;
2026               }
2027               startPositive[numberColumns_] = size;
2028               for (iRow = 0; iRow < number; iRow++) {
2029                    const int * columns;
2030                    const double * elements;
2031                    int numberElements = buildObject.row(iRow, lower[iRow],
2032                                                         upper[iRow],
2033                                                         columns, elements);
2034                    for (int i = 0; i < numberElements; i++) {
2035                         int iColumn = columns[i];
2036                         maxColumn = CoinMax(maxColumn, iColumn);
2037                         if (elements[i] == 1.0) {
2038                              CoinBigIndex position = startPositive[iColumn];
2039                              indices[position] = iRow;
2040                              startPositive[iColumn]++;
2041                         } else if (elements[i] == -1.0) {
2042                              CoinBigIndex position = startNegative[iColumn];
2043                              indices[position] = iRow;
2044                              startNegative[iColumn]++;
2045                         }
2046                    }
2047               }
2048               // and now redo starts
2049               for (iColumn = numberColumns_ - 1; iColumn >= 0; iColumn--) {
2050                    startPositive[iColumn+1] = startNegative[iColumn];
2051                    startNegative[iColumn] = startPositive[iColumn];
2052               }
2053               startPositive[0] = 0;
2054               for (iColumn = 0; iColumn < numberColumns_; iColumn++) {
2055                    CoinBigIndex start = startPositive[iColumn];
2056                    CoinBigIndex end = startNegative[iColumn];
2057                    std::sort(indices + start, indices + end);
2058                    start = startNegative[iColumn];
2059                    end = startPositive[iColumn+1];
2060                    std::sort(indices + start, indices + end);
2061               }
2062               // Get good object
2063               delete matrix_;
2064               ClpPlusMinusOneMatrix * matrix = new ClpPlusMinusOneMatrix();
2065               matrix->passInCopy(numberRows_, numberColumns,
2066                                  true, indices, startPositive, startNegative);
2067               matrix_ = matrix;
2068               delete [] which;
2069          }
2070          delete [] lower;
2071          delete [] upper;
2072          // make sure matrix correct size
2073          matrix_->setDimensions(numberRows_, numberColumns_);
2074     }
2075     return numberErrors;
2076}
2077#endif
2078#ifndef SLIM_NOIO
2079// Add rows from a model object
2080int
2081ClpModel::addRows( CoinModel & modelObject, bool tryPlusMinusOne, bool checkDuplicates)
2082{
2083     if (modelObject.numberElements() == 0)
2084          return 0;
2085     bool goodState = true;
2086     int numberErrors = 0;
2087     if (modelObject.columnLowerArray()) {
2088          // some column information exists
2089          int numberColumns2 = modelObject.numberColumns();
2090          const double * columnLower = modelObject.columnLowerArray();
2091          const double * columnUpper = modelObject.columnUpperArray();
2092          const double * objective = modelObject.objectiveArray();
2093          const int * integerType = modelObject.integerTypeArray();
2094          for (int i = 0; i < numberColumns2; i++) {
2095               if (columnLower[i] != 0.0)
2096                    goodState = false;
2097               if (columnUpper[i] != COIN_DBL_MAX)
2098                    goodState = false;
2099               if (objective[i] != 0.0)
2100                    goodState = false;
2101               if (integerType[i] != 0)
2102                    goodState = false;
2103          }
2104     }
2105     if (goodState) {
2106          // can do addRows
2107          // Set arrays for normal use
2108          double * rowLower = modelObject.rowLowerArray();
2109          double * rowUpper = modelObject.rowUpperArray();
2110          double * columnLower = modelObject.columnLowerArray();
2111          double * columnUpper = modelObject.columnUpperArray();
2112          double * objective = modelObject.objectiveArray();
2113          int * integerType = modelObject.integerTypeArray();
2114          double * associated = modelObject.associatedArray();
2115          // If strings then do copies
2116          if (modelObject.stringsExist()) {
2117               numberErrors = modelObject.createArrays(rowLower, rowUpper, columnLower, columnUpper,
2118                                                       objective, integerType, associated);
2119          }
2120          int numberRows = numberRows_; // save number of rows
2121          int numberRows2 = modelObject.numberRows();
2122          if (numberRows2 && !numberErrors) {
2123               CoinBigIndex * startPositive = NULL;
2124               CoinBigIndex * startNegative = NULL;
2125               int numberColumns = modelObject.numberColumns();
2126               if ((!matrix_ || !matrix_->getNumElements()) && !numberRows && tryPlusMinusOne) {
2127                    startPositive = new CoinBigIndex[numberColumns+1];
2128                    startNegative = new CoinBigIndex[numberColumns];
2129                    modelObject.countPlusMinusOne(startPositive, startNegative, associated);
2130                    if (startPositive[0] < 0) {
2131                         // no good
2132                         tryPlusMinusOne = false;
2133                         delete [] startPositive;
2134                         delete [] startNegative;
2135                    }
2136               } else {
2137                    // Will add to whatever sort of matrix exists
2138                    tryPlusMinusOne = false;
2139               }
2140               assert (rowLower);
2141               addRows(numberRows2, rowLower, rowUpper, NULL, NULL, NULL);
2142#ifndef SLIM_CLP
2143               if (!tryPlusMinusOne) {
2144#endif
2145                    CoinPackedMatrix matrix;
2146                    modelObject.createPackedMatrix(matrix, associated);
2147                    assert (!matrix.getExtraGap());
2148                    if (matrix_->getNumRows()) {
2149                         // matrix by rows
2150                         matrix.reverseOrdering();
2151                         assert (!matrix.getExtraGap());
2152                         const int * column = matrix.getIndices();
2153                         //const int * rowLength = matrix.getVectorLengths();
2154                         const CoinBigIndex * rowStart = matrix.getVectorStarts();
2155                         const double * element = matrix.getElements();
2156                         // make sure matrix has enough columns
2157                         matrix_->setDimensions(-1, numberColumns_);
2158                         numberErrors += matrix_->appendMatrix(numberRows2, 0, rowStart, column, element,
2159                                                               checkDuplicates ? numberColumns_ : -1);
2160                    } else {
2161                         delete matrix_;
2162                         matrix_ = new ClpPackedMatrix(matrix);
2163                    }
2164#ifndef SLIM_CLP
2165               } else {
2166                    // create +-1 matrix
2167                    CoinBigIndex size = startPositive[numberColumns];
2168                    int * indices = new int[size];
2169                    modelObject.createPlusMinusOne(startPositive, startNegative, indices,
2170                                                   associated);
2171                    // Get good object
2172                    ClpPlusMinusOneMatrix * matrix = new ClpPlusMinusOneMatrix();
2173                    matrix->passInCopy(numberRows2, numberColumns,
2174                                       true, indices, startPositive, startNegative);
2175                    delete matrix_;
2176                    matrix_ = matrix;
2177               }
2178               // Do names if wanted
2179               if (modelObject.rowNames()->numberItems()) {
2180                    const char *const * rowNames = modelObject.rowNames()->names();
2181                    copyRowNames(rowNames, numberRows, numberRows_);
2182               }
2183#endif
2184          }
2185          if (rowLower != modelObject.rowLowerArray()) {
2186               delete [] rowLower;
2187               delete [] rowUpper;
2188               delete [] columnLower;
2189               delete [] columnUpper;
2190               delete [] objective;
2191               delete [] integerType;
2192               delete [] associated;
2193               if (numberErrors)
2194                    handler_->message(CLP_BAD_STRING_VALUES, messages_)
2195                              << numberErrors
2196                              << CoinMessageEol;
2197          }
2198          return numberErrors;
2199     } else {
2200          // not suitable for addRows
2201          handler_->message(CLP_COMPLICATED_MODEL, messages_)
2202                    << modelObject.numberRows()
2203                    << modelObject.numberColumns()
2204                    << CoinMessageEol;
2205          return -1;
2206     }
2207}
2208#endif
2209// Add one column
2210void
2211ClpModel::addColumn(int numberInColumn,
2212                    const int * rows,
2213                    const double * elements,
2214                    double columnLower,
2215                    double  columnUpper,
2216                    double  objective)
2217{
2218     CoinBigIndex starts[2];
2219     starts[0] = 0;
2220     starts[1] = numberInColumn;
2221     addColumns(1, &columnLower, &columnUpper, &objective, starts, rows, elements);
2222}
2223// Add columns
2224void
2225ClpModel::addColumns(int number, const double * columnLower,
2226                     const double * columnUpper,
2227                     const double * objIn,
2228                     const int * columnStarts, const int * rows,
2229                     const double * elements)
2230{
2231     // Create a list of CoinPackedVectors
2232     if (number) {
2233          whatsChanged_ &= ~(1 + 2 + 4 + 64 + 128 + 256); // all except rows changed
2234          int numberColumnsNow = numberColumns_;
2235          resize(numberRows_, numberColumnsNow + number);
2236          double * lower = columnLower_ + numberColumnsNow;
2237          double * upper = columnUpper_ + numberColumnsNow;
2238          double * obj = objective() + numberColumnsNow;
2239          int iColumn;
2240          if (columnLower) {
2241               for (iColumn = 0; iColumn < number; iColumn++) {
2242                    double value = columnLower[iColumn];
2243                    if (value < -1.0e20)
2244                         value = -COIN_DBL_MAX;
2245                    lower[iColumn] = value;
2246               }
2247          } else {
2248               for (iColumn = 0; iColumn < number; iColumn++) {
2249                    lower[iColumn] = 0.0;
2250               }
2251          }
2252          if (columnUpper) {
2253               for (iColumn = 0; iColumn < number; iColumn++) {
2254                    double value = columnUpper[iColumn];
2255                    if (value > 1.0e20)
2256                         value = COIN_DBL_MAX;
2257                    upper[iColumn] = value;
2258               }
2259          } else {
2260               for (iColumn = 0; iColumn < number; iColumn++) {
2261                    upper[iColumn] = COIN_DBL_MAX;
2262               }
2263          }
2264          if (objIn) {
2265               for (iColumn = 0; iColumn < number; iColumn++) {
2266                    obj[iColumn] = objIn[iColumn];
2267               }
2268          } else {
2269               for (iColumn = 0; iColumn < number; iColumn++) {
2270                    obj[iColumn] = 0.0;
2271               }
2272          }
2273          // Deal with matrix
2274
2275          delete rowCopy_;
2276          rowCopy_ = NULL;
2277          delete scaledMatrix_;
2278          scaledMatrix_ = NULL;
2279          if (!matrix_)
2280               createEmptyMatrix();
2281          setRowScale(NULL);
2282          setColumnScale(NULL);
2283#ifndef CLP_NO_STD
2284          if (lengthNames_) {
2285               columnNames_.resize(numberColumns_);
2286          }
2287#endif
2288          // Do even if elements NULL (to resize)
2289          matrix_->appendMatrix(number, 1, columnStarts, rows, elements);
2290     }
2291}
2292// Add columns
2293void
2294ClpModel::addColumns(int number, const double * columnLower,
2295                     const double * columnUpper,
2296                     const double * objIn,
2297                     const int * columnStarts,
2298                     const int * columnLengths, const int * rows,
2299                     const double * elements)
2300{
2301     if (number) {
2302          CoinBigIndex numberElements = 0;
2303          int iColumn;
2304          for (iColumn = 0; iColumn < number; iColumn++)
2305               numberElements += columnLengths[iColumn];
2306          int * newStarts = new int[number+1];
2307          int * newIndex = new int[numberElements];
2308          double * newElements = new double[numberElements];
2309          numberElements = 0;
2310          newStarts[0] = 0;
2311          for (iColumn = 0; iColumn < number; iColumn++) {
2312               int iStart = columnStarts[iColumn];
2313               int length = columnLengths[iColumn];
2314               CoinMemcpyN(rows + iStart, length, newIndex + numberElements);
2315               CoinMemcpyN(elements + iStart, length, newElements + numberElements);
2316               numberElements += length;
2317               newStarts[iColumn+1] = numberElements;
2318          }
2319          addColumns(number, columnLower, columnUpper, objIn,
2320                     newStarts, newIndex, newElements);
2321          delete [] newStarts;
2322          delete [] newIndex;
2323          delete [] newElements;
2324     }
2325}
2326#ifndef CLP_NO_VECTOR
2327void
2328ClpModel::addColumns(int number, const double * columnLower,
2329                     const double * columnUpper,
2330                     const double * objIn,
2331                     const CoinPackedVectorBase * const * columns)
2332{
2333     if (!number)
2334          return;
2335     whatsChanged_ &= ~(1 + 2 + 4 + 64 + 128 + 256); // all except rows changed
2336     int numberColumnsNow = numberColumns_;
2337     resize(numberRows_, numberColumnsNow + number);
2338     double * lower = columnLower_ + numberColumnsNow;
2339     double * upper = columnUpper_ + numberColumnsNow;
2340     double * obj = objective() + numberColumnsNow;
2341     int iColumn;
2342     if (columnLower) {
2343          for (iColumn = 0; iColumn < number; iColumn++) {
2344               double value = columnLower[iColumn];
2345               if (value < -1.0e20)
2346                    value = -COIN_DBL_MAX;
2347               lower[iColumn] = value;
2348          }
2349     } else {
2350          for (iColumn = 0; iColumn < number; iColumn++) {
2351               lower[iColumn] = 0.0;
2352          }
2353     }
2354     if (columnUpper) {
2355          for (iColumn = 0; iColumn < number; iColumn++) {
2356               double value = columnUpper[iColumn];
2357               if (value > 1.0e20)
2358                    value = COIN_DBL_MAX;
2359               upper[iColumn] = value;
2360          }
2361     } else {
2362          for (iColumn = 0; iColumn < number; iColumn++) {
2363               upper[iColumn] = COIN_DBL_MAX;
2364          }
2365     }
2366     if (objIn) {
2367          for (iColumn = 0; iColumn < number; iColumn++) {
2368               obj[iColumn] = objIn[iColumn];
2369          }
2370     } else {
2371          for (iColumn = 0; iColumn < number; iColumn++) {
2372               obj[iColumn] = 0.0;
2373          }
2374     }
2375     // Deal with matrix
2376
2377     delete rowCopy_;
2378     rowCopy_ = NULL;
2379     delete scaledMatrix_;
2380     scaledMatrix_ = NULL;
2381     if (!matrix_)
2382          createEmptyMatrix();
2383     if (columns)
2384          matrix_->appendCols(number, columns);
2385     setRowScale(NULL);
2386     setColumnScale(NULL);
2387     if (lengthNames_) {
2388          columnNames_.resize(numberColumns_);
2389     }
2390}
2391#endif
2392#ifndef SLIM_CLP
2393// Add columns from a build object
2394int
2395ClpModel::addColumns(const CoinBuild & buildObject, bool tryPlusMinusOne, bool checkDuplicates)
2396{
2397     CoinAssertHint (buildObject.type() == 1, "Looks as if both addRows and addCols being used"); // check correct
2398     int number = buildObject.numberColumns();
2399     int numberErrors = 0;
2400     if (number) {
2401          CoinBigIndex size = 0;
2402          int maximumLength = 0;
2403          double * lower = new double [number];
2404          double * upper = new double [number];
2405          int iColumn;
2406          double * objective = new double [number];
2407          if ((!matrix_ || !matrix_->getNumElements()) && tryPlusMinusOne) {
2408               // See if can be +-1
2409               for (iColumn = 0; iColumn < number; iColumn++) {
2410                    const int * rows;
2411                    const double * elements;
2412                    int numberElements = buildObject.column(iColumn, lower[iColumn],
2413                                                            upper[iColumn], objective[iColumn],
2414                                                            rows, elements);
2415                    maximumLength = CoinMax(maximumLength, numberElements);
2416                    for (int i = 0; i < numberElements; i++) {
2417                         // allow for zero elements
2418                         if (elements[i]) {
2419                              if (fabs(elements[i]) == 1.0) {
2420                                   size++;
2421                              } else {
2422                                   // bad
2423                                   tryPlusMinusOne = false;
2424                              }
2425                         }
2426                    }
2427                    if (!tryPlusMinusOne)
2428                         break;
2429               }
2430          } else {
2431               // Will add to whatever sort of matrix exists
2432               tryPlusMinusOne = false;
2433          }
2434          if (!tryPlusMinusOne) {
2435               CoinBigIndex numberElements = buildObject.numberElements();
2436               CoinBigIndex * starts = new CoinBigIndex [number+1];
2437               int * row = new int[numberElements];
2438               double * element = new double[numberElements];
2439               starts[0] = 0;
2440               numberElements = 0;
2441               for (iColumn = 0; iColumn < number; iColumn++) {
2442                    const int * rows;
2443                    const double * elements;
2444                    int numberElementsThis = buildObject.column(iColumn, lower[iColumn], upper[iColumn],
2445                                             objective[iColumn], rows, elements);
2446                    CoinMemcpyN(rows, numberElementsThis, row + numberElements);
2447                    CoinMemcpyN(elements, numberElementsThis, element + numberElements);
2448                    numberElements += numberElementsThis;
2449                    starts[iColumn+1] = numberElements;
2450               }
2451               addColumns(number, lower, upper, objective, NULL);
2452               // make sure matrix has enough rows
2453               matrix_->setDimensions(numberRows_, -1);
2454               numberErrors = matrix_->appendMatrix(number, 1, starts, row, element,
2455                                                    checkDuplicates ? numberRows_ : -1);
2456               delete [] starts;
2457               delete [] row;
2458               delete [] element;
2459          } else {
2460               // arrays already filled in
2461               addColumns(number, lower, upper, objective, NULL);
2462               char * which = NULL; // for duplicates
2463               if (checkDuplicates) {
2464                    which = new char[numberRows_];
2465                    CoinZeroN(which, numberRows_);
2466               }
2467               // build +-1 matrix
2468               CoinBigIndex * startPositive = new CoinBigIndex [number+1];
2469               CoinBigIndex * startNegative = new CoinBigIndex [number];
2470               int * indices = new int [size];
2471               int * neg = new int[maximumLength];
2472               startPositive[0] = 0;
2473               size = 0;
2474               int maxRow = -1;
2475               for (iColumn = 0; iColumn < number; iColumn++) {
2476                    const int * rows;
2477                    const double * elements;
2478                    int numberElements = buildObject.column(iColumn, lower[iColumn],
2479                                                            upper[iColumn], objective[iColumn],
2480                                                            rows, elements);
2481                    int nNeg = 0;
2482                    CoinBigIndex start = size;
2483                    for (int i = 0; i < numberElements; i++) {
2484                         int iRow = rows[i];
2485                         if (checkDuplicates) {
2486                              if (iRow >= numberRows_) {
2487                                   if(which[iRow])
2488                                        numberErrors++;
2489                                   else
2490                                        which[iRow] = 1;
2491                              } else {
2492                                   numberErrors++;
2493                                   // and may as well switch off
2494                                   checkDuplicates = false;
2495                              }
2496                         }
2497                         maxRow = CoinMax(maxRow, iRow);
2498                         if (elements[i] == 1.0) {
2499                              indices[size++] = iRow;
2500                         } else if (elements[i] == -1.0) {
2501                              neg[nNeg++] = iRow;
2502                         }
2503                    }
2504                    std::sort(indices + start, indices + size);
2505                    std::sort(neg, neg + nNeg);
2506                    startNegative[iColumn] = size;
2507                    CoinMemcpyN(neg, nNeg, indices + size);
2508                    size += nNeg;
2509                    startPositive[iColumn+1] = size;
2510               }
2511               delete [] neg;
2512               // check size
2513               assert (maxRow + 1 <= numberRows_);
2514               // Get good object
2515               delete matrix_;
2516               ClpPlusMinusOneMatrix * matrix = new ClpPlusMinusOneMatrix();
2517               matrix->passInCopy(numberRows_, number, true, indices, startPositive, startNegative);
2518               matrix_ = matrix;
2519               delete [] which;
2520          }
2521          delete [] objective;
2522          delete [] lower;
2523          delete [] upper;
2524     }
2525     return 0;
2526}
2527#endif
2528#ifndef SLIM_NOIO
2529// Add columns from a model object
2530int
2531ClpModel::addColumns( CoinModel & modelObject, bool tryPlusMinusOne, bool checkDuplicates)
2532{
2533     if (modelObject.numberElements() == 0)
2534          return 0;
2535     bool goodState = true;
2536     if (modelObject.rowLowerArray()) {
2537          // some row information exists
2538          int numberRows2 = modelObject.numberRows();
2539          const double * rowLower = modelObject.rowLowerArray();
2540          const double * rowUpper = modelObject.rowUpperArray();
2541          for (int i = 0; i < numberRows2; i++) {
2542               if (rowLower[i] != -COIN_DBL_MAX)
2543                    goodState = false;
2544               if (rowUpper[i] != COIN_DBL_MAX)
2545                    goodState = false;
2546          }
2547     }
2548     if (goodState) {
2549          // can do addColumns
2550          int numberErrors = 0;
2551          // Set arrays for normal use
2552          double * rowLower = modelObject.rowLowerArray();
2553          double * rowUpper = modelObject.rowUpperArray();
2554          double * columnLower = modelObject.columnLowerArray();
2555          double * columnUpper = modelObject.columnUpperArray();
2556          double * objective = modelObject.objectiveArray();
2557          int * integerType = modelObject.integerTypeArray();
2558          double * associated = modelObject.associatedArray();
2559          // If strings then do copies
2560          if (modelObject.stringsExist()) {
2561               numberErrors = modelObject.createArrays(rowLower, rowUpper, columnLower, columnUpper,
2562                                                       objective, integerType, associated);
2563          }
2564          int numberColumns = numberColumns_; // save number of columns
2565          int numberColumns2 = modelObject.numberColumns();
2566          if (numberColumns2 && !numberErrors) {
2567               CoinBigIndex * startPositive = NULL;
2568               CoinBigIndex * startNegative = NULL;
2569               if ((!matrix_ || !matrix_->getNumElements()) && !numberColumns && tryPlusMinusOne) {
2570                    startPositive = new CoinBigIndex[numberColumns2+1];
2571                    startNegative = new CoinBigIndex[numberColumns2];
2572                    modelObject.countPlusMinusOne(startPositive, startNegative, associated);
2573                    if (startPositive[0] < 0) {
2574                         // no good
2575                         tryPlusMinusOne = false;
2576                         delete [] startPositive;
2577                         delete [] startNegative;
2578                    }
2579               } else {
2580                    // Will add to whatever sort of matrix exists
2581                    tryPlusMinusOne = false;
2582               }
2583               assert (columnLower);
2584               addColumns(numberColumns2, columnLower, columnUpper, objective, NULL, NULL, NULL);
2585#ifndef SLIM_CLP
2586               if (!tryPlusMinusOne) {
2587#endif
2588                    CoinPackedMatrix matrix;
2589                    modelObject.createPackedMatrix(matrix, associated);
2590                    assert (!matrix.getExtraGap());
2591                    if (matrix_->getNumCols()) {
2592                         const int * row = matrix.getIndices();
2593                         //const int * columnLength = matrix.getVectorLengths();
2594                         const CoinBigIndex * columnStart = matrix.getVectorStarts();
2595                         const double * element = matrix.getElements();
2596                         // make sure matrix has enough rows
2597                         matrix_->setDimensions(numberRows_, -1);
2598                         numberErrors += matrix_->appendMatrix(numberColumns2, 1, columnStart, row, element,
2599                                                               checkDuplicates ? numberRows_ : -1);
2600                    } else {
2601                         delete matrix_;
2602                         matrix_ = new ClpPackedMatrix(matrix);
2603                    }
2604#ifndef SLIM_CLP
2605               } else {
2606                    // create +-1 matrix
2607                    CoinBigIndex size = startPositive[numberColumns2];
2608                    int * indices = new int[size];
2609                    modelObject.createPlusMinusOne(startPositive, startNegative, indices,
2610                                                   associated);
2611                    // Get good object
2612                    ClpPlusMinusOneMatrix * matrix = new ClpPlusMinusOneMatrix();
2613                    matrix->passInCopy(numberRows_, numberColumns2,
2614                                       true, indices, startPositive, startNegative);
2615                    delete matrix_;
2616                    matrix_ = matrix;
2617               }
2618#endif
2619#ifndef CLP_NO_STD
2620               // Do names if wanted
2621               if (modelObject.columnNames()->numberItems()) {
2622                    const char *const * columnNames = modelObject.columnNames()->names();
2623                    copyColumnNames(columnNames, numberColumns, numberColumns_);
2624               }
2625#endif
2626               // Do integers if wanted
2627               assert(integerType);
2628               for (int iColumn = 0; iColumn < numberColumns2; iColumn++) {
2629                    if (integerType[iColumn])
2630                         setInteger(iColumn + numberColumns);
2631               }
2632          }
2633          if (columnLower != modelObject.columnLowerArray()) {
2634               delete [] rowLower;
2635               delete [] rowUpper;
2636               delete [] columnLower;
2637               delete [] columnUpper;
2638               delete [] objective;
2639               delete [] integerType;
2640               delete [] associated;
2641               if (numberErrors)
2642                    handler_->message(CLP_BAD_STRING_VALUES, messages_)
2643                              << numberErrors
2644                              << CoinMessageEol;
2645          }
2646          return numberErrors;
2647     } else {
2648          // not suitable for addColumns
2649          handler_->message(CLP_COMPLICATED_MODEL, messages_)
2650                    << modelObject.numberRows()
2651                    << modelObject.numberColumns()
2652                    << CoinMessageEol;
2653          return -1;
2654     }
2655}
2656#endif
2657// chgRowLower
2658void
2659ClpModel::chgRowLower(const double * rowLower)
2660{
2661     int numberRows = numberRows_;
2662     int iRow;
2663     whatsChanged_ = 0; // Use ClpSimplex stuff to keep
2664     if (rowLower) {
2665          for (iRow = 0; iRow < numberRows; iRow++) {
2666               double value = rowLower[iRow];
2667               if (value < -1.0e20)
2668                    value = -COIN_DBL_MAX;
2669               rowLower_[iRow] = value;
2670          }
2671     } else {
2672          for (iRow = 0; iRow < numberRows; iRow++) {
2673               rowLower_[iRow] = -COIN_DBL_MAX;
2674          }
2675     }
2676}
2677// chgRowUpper
2678void
2679ClpModel::chgRowUpper(const double * rowUpper)
2680{
2681     whatsChanged_ = 0; // Use ClpSimplex stuff to keep
2682     int numberRows = numberRows_;
2683     int iRow;
2684     if (rowUpper) {
2685          for (iRow = 0; iRow < numberRows; iRow++) {
2686               double value = rowUpper[iRow];
2687               if (value > 1.0e20)
2688                    value = COIN_DBL_MAX;
2689               rowUpper_[iRow] = value;
2690          }
2691     } else {
2692          for (iRow = 0; iRow < numberRows; iRow++) {
2693               rowUpper_[iRow] = COIN_DBL_MAX;;
2694          }
2695     }
2696}
2697// chgColumnLower
2698void
2699ClpModel::chgColumnLower(const double * columnLower)
2700{
2701     whatsChanged_ = 0; // Use ClpSimplex stuff to keep
2702     int numberColumns = numberColumns_;
2703     int iColumn;
2704     if (columnLower) {
2705          for (iColumn = 0; iColumn < numberColumns; iColumn++) {
2706               double value = columnLower[iColumn];
2707               if (value < -1.0e20)
2708                    value = -COIN_DBL_MAX;
2709               columnLower_[iColumn] = value;
2710          }
2711     } else {
2712          for (iColumn = 0; iColumn < numberColumns; iColumn++) {
2713               columnLower_[iColumn] = 0.0;
2714          }
2715     }
2716}
2717// chgColumnUpper
2718void
2719ClpModel::chgColumnUpper(const double * columnUpper)
2720{
2721     whatsChanged_ = 0; // Use ClpSimplex stuff to keep
2722     int numberColumns = numberColumns_;
2723     int iColumn;
2724     if (columnUpper) {
2725          for (iColumn = 0; iColumn < numberColumns; iColumn++) {
2726               double value = columnUpper[iColumn];
2727               if (value > 1.0e20)
2728                    value = COIN_DBL_MAX;
2729               columnUpper_[iColumn] = value;
2730          }
2731     } else {
2732          for (iColumn = 0; iColumn < numberColumns; iColumn++) {
2733               columnUpper_[iColumn] = COIN_DBL_MAX;;
2734          }
2735     }
2736}
2737// chgObjCoefficients
2738void
2739ClpModel::chgObjCoefficients(const double * objIn)
2740{
2741     whatsChanged_ = 0; // Use ClpSimplex stuff to keep
2742     double * obj = objective();
2743     int numberColumns = numberColumns_;
2744     int iColumn;
2745     if (objIn) {
2746          for (iColumn = 0; iColumn < numberColumns; iColumn++) {
2747               obj[iColumn] = objIn[iColumn];
2748          }
2749     } else {
2750          for (iColumn = 0; iColumn < numberColumns; iColumn++) {
2751               obj[iColumn] = 0.0;
2752          }
2753     }
2754}
2755// Infeasibility/unbounded ray (NULL returned if none/wrong)
2756double *
2757ClpModel::infeasibilityRay(bool fullRay) const
2758{
2759     double * array = NULL;
2760     if (problemStatus_ == 1 && ray_) {
2761       if (!fullRay) {
2762         array = ClpCopyOfArray(ray_, numberRows_);
2763       } else {
2764         array = new double [numberRows_+numberColumns_];
2765         memcpy(array,ray_,numberRows_*sizeof(double));
2766         memset(array+numberRows_,0,numberColumns_*sizeof(double));
2767         transposeTimes(-1.0,array,array+numberRows_);
2768       }
2769     }
2770     return array;
2771}
2772double *
2773ClpModel::unboundedRay() const
2774{
2775     double * array = NULL;
2776     if (problemStatus_ == 2)
2777          array = ClpCopyOfArray(ray_, numberColumns_);
2778     return array;
2779}
2780void
2781ClpModel::setMaximumIterations(int value)
2782{
2783     if(value >= 0)
2784          intParam_[ClpMaxNumIteration] = value;
2785}
2786void
2787ClpModel::setMaximumSeconds(double value)
2788{
2789     if(value >= 0)
2790          dblParam_[ClpMaxSeconds] = value + CoinCpuTime();
2791     else
2792          dblParam_[ClpMaxSeconds] = -1.0;
2793}
2794// Returns true if hit maximum iterations (or time)
2795bool
2796ClpModel::hitMaximumIterations() const
2797{
2798     // replaced - compiler error? bool hitMax= (numberIterations_>=maximumIterations());
2799     bool hitMax = (numberIterations_ >= intParam_[ClpMaxNumIteration]);
2800     if (dblParam_[ClpMaxSeconds] >= 0.0 && !hitMax) {
2801          hitMax = (CoinCpuTime() >= dblParam_[ClpMaxSeconds]);
2802     }
2803     return hitMax;
2804}
2805// On stopped - sets secondary status
2806void
2807ClpModel::onStopped()
2808{
2809     if (problemStatus_ == 3) {
2810          secondaryStatus_ = 0;
2811          if (CoinCpuTime() >= dblParam_[ClpMaxSeconds] && dblParam_[ClpMaxSeconds] >= 0.0)
2812               secondaryStatus_ = 9;
2813     }
2814}
2815// Pass in Message handler (not deleted at end)
2816void
2817ClpModel::passInMessageHandler(CoinMessageHandler * handler)
2818{
2819     if (defaultHandler_)
2820          delete handler_;
2821     defaultHandler_ = false;
2822     handler_ = handler;
2823}
2824// Pass in Message handler (not deleted at end) and return current
2825CoinMessageHandler *
2826ClpModel::pushMessageHandler(CoinMessageHandler * handler,
2827                             bool & oldDefault)
2828{
2829     CoinMessageHandler * returnValue = handler_;
2830     oldDefault = defaultHandler_;
2831     defaultHandler_ = false;
2832     handler_ = handler;
2833     return returnValue;
2834}
2835// back to previous message handler
2836void
2837ClpModel::popMessageHandler(CoinMessageHandler * oldHandler, bool oldDefault)
2838{
2839     if (defaultHandler_)
2840          delete handler_;
2841     defaultHandler_ = oldDefault;
2842     handler_ = oldHandler;
2843}
2844// Overrides message handler with a default one
2845void 
2846ClpModel::setDefaultMessageHandler()
2847{
2848     int logLevel = handler_->logLevel();
2849     if (defaultHandler_)
2850          delete handler_;
2851     defaultHandler_ = true;
2852     handler_ = new CoinMessageHandler();
2853     handler_->setLogLevel(logLevel);
2854}
2855// Set language
2856void
2857ClpModel::newLanguage(CoinMessages::Language language)
2858{
2859     messages_ = ClpMessage(language);
2860}
2861#ifndef SLIM_NOIO
2862// Read an mps file from the given filename
2863int
2864ClpModel::readMps(const char *fileName,
2865                  bool keepNames,
2866                  bool ignoreErrors)
2867{
2868     if (!strcmp(fileName, "-") || !strcmp(fileName, "stdin")) {
2869          // stdin
2870     } else {
2871          std::string name = fileName;
2872          bool readable = fileCoinReadable(name);
2873          if (!readable) {
2874               handler_->message(CLP_UNABLE_OPEN, messages_)
2875                         << fileName << CoinMessageEol;
2876               return -1;
2877          }
2878     }
2879     CoinMpsIO m;
2880     m.passInMessageHandler(handler_);
2881     *m.messagesPointer() = coinMessages();
2882     bool savePrefix = m.messageHandler()->prefix();
2883     m.messageHandler()->setPrefix(handler_->prefix());
2884     m.setSmallElementValue(CoinMax(smallElement_, m.getSmallElementValue()));
2885     double time1 = CoinCpuTime(), time2;
2886     int status = 0;
2887     try {
2888          status = m.readMps(fileName, "");
2889     } catch (CoinError e) {
2890          e.print();
2891          status = -1;
2892     }
2893     m.messageHandler()->setPrefix(savePrefix);
2894     if (!status || (ignoreErrors && (status > 0 && status < 100000))) {
2895          loadProblem(*m.getMatrixByCol(),
2896                      m.getColLower(), m.getColUpper(),
2897                      m.getObjCoefficients(),
2898                      m.getRowLower(), m.getRowUpper());
2899          if (m.integerColumns()) {
2900               integerType_ = new char[numberColumns_];
2901               CoinMemcpyN(m.integerColumns(), numberColumns_, integerType_);
2902          } else {
2903               integerType_ = NULL;
2904          }
2905#ifndef SLIM_CLP
2906          // get quadratic part
2907          if (m.reader()->whichSection (  ) == COIN_QUAD_SECTION ) {
2908               int * start = NULL;
2909               int * column = NULL;
2910               double * element = NULL;
2911               status = m.readQuadraticMps(NULL, start, column, element, 2);
2912               if (!status || ignoreErrors)
2913                    loadQuadraticObjective(numberColumns_, start, column, element);
2914               delete [] start;
2915               delete [] column;
2916               delete [] element;
2917          }
2918#endif
2919#ifndef CLP_NO_STD
2920          // set problem name
2921          setStrParam(ClpProbName, m.getProblemName());
2922          // do names
2923          if (keepNames) {
2924               unsigned int maxLength = 0;
2925               int iRow;
2926               rowNames_ = std::vector<std::string> ();
2927               columnNames_ = std::vector<std::string> ();
2928               rowNames_.reserve(numberRows_);
2929               for (iRow = 0; iRow < numberRows_; iRow++) {
2930                    const char * name = m.rowName(iRow);
2931                    maxLength = CoinMax(maxLength, static_cast<unsigned int> (strlen(name)));
2932                    rowNames_.push_back(name);
2933               }
2934
2935               int iColumn;
2936               columnNames_.reserve(numberColumns_);
2937               for (iColumn = 0; iColumn < numberColumns_; iColumn++) {
2938                    const char * name = m.columnName(iColumn);
2939                    maxLength = CoinMax(maxLength, static_cast<unsigned int> (strlen(name)));
2940                    columnNames_.push_back(name);
2941               }
2942               lengthNames_ = static_cast<int> (maxLength);
2943          } else {
2944               lengthNames_ = 0;
2945          }
2946#endif
2947          setDblParam(ClpObjOffset, m.objectiveOffset());
2948          time2 = CoinCpuTime();
2949          handler_->message(CLP_IMPORT_RESULT, messages_)
2950                    << fileName
2951                    << time2 - time1 << CoinMessageEol;
2952     } else {
2953          // errors
2954          handler_->message(CLP_IMPORT_ERRORS, messages_)
2955                    << status << fileName << CoinMessageEol;
2956     }
2957
2958     return status;
2959}
2960// Read GMPL files from the given filenames
2961int
2962ClpModel::readGMPL(const char *fileName, const char * dataName,
2963                   bool keepNames)
2964{
2965     FILE *fp = fopen(fileName, "r");
2966     if (fp) {
2967          // can open - lets go for it
2968          fclose(fp);
2969          if (dataName) {
2970               fp = fopen(dataName, "r");
2971               if (fp) {
2972                    fclose(fp);
2973               } else {
2974                    handler_->message(CLP_UNABLE_OPEN, messages_)
2975                              << dataName << CoinMessageEol;
2976                    return -1;
2977               }
2978          }
2979     } else {
2980          handler_->message(CLP_UNABLE_OPEN, messages_)
2981                    << fileName << CoinMessageEol;
2982          return -1;
2983     }
2984     CoinMpsIO m;
2985     m.passInMessageHandler(handler_);
2986     *m.messagesPointer() = coinMessages();
2987     bool savePrefix = m.messageHandler()->prefix();
2988     m.messageHandler()->setPrefix(handler_->prefix());
2989     double time1 = CoinCpuTime(), time2;
2990     int status = m.readGMPL(fileName, dataName, keepNames);
2991     m.messageHandler()->setPrefix(savePrefix);
2992     if (!status) {
2993          loadProblem(*m.getMatrixByCol(),
2994                      m.getColLower(), m.getColUpper(),
2995                      m.getObjCoefficients(),
2996                      m.getRowLower(), m.getRowUpper());
2997          if (m.integerColumns()) {
2998               integerType_ = new char[numberColumns_];
2999               CoinMemcpyN(m.integerColumns(), numberColumns_, integerType_);
3000          } else {
3001               integerType_ = NULL;
3002          }
3003#ifndef CLP_NO_STD
3004          // set problem name
3005          setStrParam(ClpProbName, m.getProblemName());
3006          // do names
3007          if (keepNames) {
3008               unsigned int maxLength = 0;
3009               int iRow;
3010               rowNames_ = std::vector<std::string> ();
3011               columnNames_ = std::vector<std::string> ();
3012               rowNames_.reserve(numberRows_);
3013               for (iRow = 0; iRow < numberRows_; iRow++) {
3014                    const char * name = m.rowName(iRow);
3015                    maxLength = CoinMax(maxLength, static_cast<unsigned int> (strlen(name)));
3016                    rowNames_.push_back(name);
3017               }
3018
3019               int iColumn;
3020               columnNames_.reserve(numberColumns_);
3021               for (iColumn = 0; iColumn < numberColumns_; iColumn++) {
3022                    const char * name = m.columnName(iColumn);
3023                    maxLength = CoinMax(maxLength, static_cast<unsigned int> (strlen(name)));
3024                    columnNames_.push_back(name);
3025               }
3026               lengthNames_ = static_cast<int> (maxLength);
3027          } else {
3028               lengthNames_ = 0;
3029          }
3030#endif
3031          setDblParam(ClpObjOffset, m.objectiveOffset());
3032          time2 = CoinCpuTime();
3033          handler_->message(CLP_IMPORT_RESULT, messages_)
3034                    << fileName
3035                    << time2 - time1 << CoinMessageEol;
3036     } else {
3037          // errors
3038          handler_->message(CLP_IMPORT_ERRORS, messages_)
3039                    << status << fileName << CoinMessageEol;
3040     }
3041     return status;
3042}
3043#endif
3044bool ClpModel::isPrimalObjectiveLimitReached() const
3045{
3046     double limit = 0.0;
3047     getDblParam(ClpPrimalObjectiveLimit, limit);
3048     if (limit > 1e30) {
3049          // was not ever set
3050          return false;
3051     }
3052
3053     const double obj = objectiveValue();
3054     const double maxmin = optimizationDirection();
3055
3056     if (problemStatus_ == 0) // optimal
3057          return maxmin > 0 ? (obj < limit) /*minim*/ : (-obj < limit) /*maxim*/;
3058     else if (problemStatus_ == 2)
3059          return true;
3060     else
3061          return false;
3062}
3063
3064bool ClpModel::isDualObjectiveLimitReached() const
3065{
3066
3067     double limit = 0.0;
3068     getDblParam(ClpDualObjectiveLimit, limit);
3069     if (limit > 1e30) {
3070          // was not ever set
3071          return false;
3072     }
3073
3074     const double obj = objectiveValue();
3075     const double maxmin = optimizationDirection();
3076
3077     if (problemStatus_ == 0) // optimal
3078          return maxmin > 0 ? (obj > limit) /*minim*/ : (-obj > limit) /*maxim*/;
3079     else if (problemStatus_ == 1)
3080          return true;
3081     else
3082          return false;
3083
3084}
3085void
3086ClpModel::copyInIntegerInformation(const char * information)
3087{
3088     delete [] integerType_;
3089     if (information) {
3090          integerType_ = new char[numberColumns_];
3091          CoinMemcpyN(information, numberColumns_, integerType_);
3092     } else {
3093          integerType_ = NULL;
3094     }
3095}
3096void
3097ClpModel::setContinuous(int index)
3098{
3099
3100     if (integerType_) {
3101#ifndef NDEBUG
3102          if (index < 0 || index >= numberColumns_) {
3103               indexError(index, "setContinuous");
3104          }
3105#endif
3106          integerType_[index] = 0;
3107     }
3108}
3109//-----------------------------------------------------------------------------
3110void
3111ClpModel::setInteger(int index)
3112{
3113     if (!integerType_) {
3114          integerType_ = new char[numberColumns_];
3115          CoinZeroN ( integerType_, numberColumns_);
3116     }
3117#ifndef NDEBUG
3118     if (index < 0 || index >= numberColumns_) {
3119          indexError(index, "setInteger");
3120     }
3121#endif
3122     integerType_[index] = 1;
3123}
3124/* Return true if the index-th variable is an integer variable */
3125bool
3126ClpModel::isInteger(int index) const
3127{
3128     if (!integerType_) {
3129          return false;
3130     } else {
3131#ifndef NDEBUG
3132          if (index < 0 || index >= numberColumns_) {
3133               indexError(index, "isInteger");
3134          }
3135#endif
3136          return (integerType_[index] != 0);
3137     }
3138}
3139#ifndef CLP_NO_STD
3140// Drops names - makes lengthnames 0 and names empty
3141void
3142ClpModel::dropNames()
3143{
3144     lengthNames_ = 0;
3145     rowNames_ = std::vector<std::string> ();
3146     columnNames_ = std::vector<std::string> ();
3147}
3148#endif
3149// Drop integer informations
3150void
3151ClpModel::deleteIntegerInformation()
3152{
3153     delete [] integerType_;
3154     integerType_ = NULL;
3155}
3156/* Return copy of status array (char[numberRows+numberColumns]),
3157   use delete [] */
3158unsigned char *
3159ClpModel::statusCopy() const
3160{
3161     return ClpCopyOfArray(status_, numberRows_ + numberColumns_);
3162}
3163// Copy in status vector
3164void
3165ClpModel::copyinStatus(const unsigned char * statusArray)
3166{
3167     delete [] status_;
3168     if (statusArray) {
3169          status_ = new unsigned char [numberRows_+numberColumns_];
3170          CoinMemcpyN(statusArray, (numberRows_ + numberColumns_), status_);
3171     } else {
3172          status_ = NULL;
3173     }
3174}
3175#ifndef SLIM_CLP
3176// Load up quadratic objective
3177void
3178ClpModel::loadQuadraticObjective(const int numberColumns, const CoinBigIndex * start,
3179                                 const int * column, const double * element)
3180{
3181     whatsChanged_ = 0; // Use ClpSimplex stuff to keep
3182     CoinAssert (numberColumns == numberColumns_);
3183     assert ((dynamic_cast< ClpLinearObjective*>(objective_)));
3184     double offset;
3185     ClpObjective * obj = new ClpQuadraticObjective(objective_->gradient(NULL, NULL, offset, false),
3186               numberColumns,
3187               start, column, element);
3188     delete objective_;
3189     objective_ = obj;
3190
3191}
3192void
3193ClpModel::loadQuadraticObjective (  const CoinPackedMatrix& matrix)
3194{
3195     whatsChanged_ = 0; // Use ClpSimplex stuff to keep
3196     CoinAssert (matrix.getNumCols() == numberColumns_);
3197     assert ((dynamic_cast< ClpLinearObjective*>(objective_)));
3198     double offset;
3199     ClpQuadraticObjective * obj =
3200          new ClpQuadraticObjective(objective_->gradient(NULL, NULL, offset, false),
3201                                    numberColumns_,
3202                                    NULL, NULL, NULL);
3203     delete objective_;
3204     objective_ = obj;
3205     obj->loadQuadraticObjective(matrix);
3206}
3207// Get rid of quadratic objective
3208void
3209ClpModel::deleteQuadraticObjective()
3210{
3211     whatsChanged_ = 0; // Use ClpSimplex stuff to keep
3212     ClpQuadraticObjective * obj = (dynamic_cast< ClpQuadraticObjective*>(objective_));
3213     if (obj)
3214          obj->deleteQuadraticObjective();
3215}
3216#endif
3217void
3218ClpModel::setObjective(ClpObjective * objective)
3219{
3220     whatsChanged_ = 0; // Use ClpSimplex stuff to keep
3221     delete objective_;
3222     objective_ = objective->clone();
3223}
3224// Returns resized array and updates size
3225double * whichDouble(double * array , int number, const int * which)
3226{
3227     double * newArray = NULL;
3228     if (array && number) {
3229          int i ;
3230          newArray = new double[number];
3231          for (i = 0; i < number; i++)
3232               newArray[i] = array[which[i]];
3233     }
3234     return newArray;
3235}
3236char * whichChar(char * array , int number, const int * which)
3237{
3238     char * newArray = NULL;
3239     if (array && number) {
3240          int i ;
3241          newArray = new char[number];
3242          for (i = 0; i < number; i++)
3243               newArray[i] = array[which[i]];
3244     }
3245     return newArray;
3246}
3247unsigned char * whichUnsignedChar(unsigned char * array ,
3248                                  int number, const int * which)
3249{
3250     unsigned char * newArray = NULL;
3251     if (array && number) {
3252          int i ;
3253          newArray = new unsigned char[number];
3254          for (i = 0; i < number; i++)
3255               newArray[i] = array[which[i]];
3256     }
3257     return newArray;
3258}
3259// Replace Clp Matrix (current is not deleted)
3260void
3261ClpModel::replaceMatrix( ClpMatrixBase * matrix, bool deleteCurrent)
3262{
3263     if (deleteCurrent)
3264          delete matrix_;
3265     matrix_ = matrix;
3266     whatsChanged_ = 0; // Too big a change
3267}
3268// Subproblem constructor
3269ClpModel::ClpModel ( const ClpModel * rhs,
3270                     int numberRows, const int * whichRow,
3271                     int numberColumns, const int * whichColumn,
3272                     bool dropNames, bool dropIntegers)
3273     :  specialOptions_(rhs->specialOptions_),
3274        maximumColumns_(-1),
3275        maximumRows_(-1),
3276        maximumInternalColumns_(-1),
3277        maximumInternalRows_(-1),
3278        savedRowScale_(NULL),
3279        savedColumnScale_(NULL)
3280{
3281     defaultHandler_ = rhs->defaultHandler_;
3282     if (defaultHandler_)
3283          handler_ = new CoinMessageHandler(*rhs->handler_);
3284     else
3285          handler_ = rhs->handler_;
3286     eventHandler_ = rhs->eventHandler_->clone();
3287     randomNumberGenerator_ = rhs->randomNumberGenerator_;
3288     messages_ = rhs->messages_;
3289     coinMessages_ = rhs->coinMessages_;
3290     maximumColumns_ = -1;
3291     maximumRows_ = -1;
3292     maximumInternalColumns_ = -1;
3293     maximumInternalRows_ = -1;
3294     savedRowScale_ = NULL;
3295     savedColumnScale_ = NULL;
3296     intParam_[ClpMaxNumIteration] = rhs->intParam_[ClpMaxNumIteration];
3297     intParam_[ClpMaxNumIterationHotStart] =
3298          rhs->intParam_[ClpMaxNumIterationHotStart];
3299     intParam_[ClpNameDiscipline] = rhs->intParam_[ClpNameDiscipline] ;
3300
3301     dblParam_[ClpDualObjectiveLimit] = rhs->dblParam_[ClpDualObjectiveLimit];
3302     dblParam_[ClpPrimalObjectiveLimit] = rhs->dblParam_[ClpPrimalObjectiveLimit];
3303     dblParam_[ClpDualTolerance] = rhs->dblParam_[ClpDualTolerance];
3304     dblParam_[ClpPrimalTolerance] = rhs->dblParam_[ClpPrimalTolerance];
3305     dblParam_[ClpObjOffset] = rhs->dblParam_[ClpObjOffset];
3306     dblParam_[ClpMaxSeconds] = rhs->dblParam_[ClpMaxSeconds];
3307     dblParam_[ClpPresolveTolerance] = rhs->dblParam_[ClpPresolveTolerance];
3308#ifndef CLP_NO_STD
3309     strParam_[ClpProbName] = rhs->strParam_[ClpProbName];
3310#endif
3311     specialOptions_ = rhs->specialOptions_;
3312     optimizationDirection_ = rhs->optimizationDirection_;
3313     objectiveValue_ = rhs->objectiveValue_;
3314     smallElement_ = rhs->smallElement_;
3315     objectiveScale_ = rhs->objectiveScale_;
3316     rhsScale_ = rhs->rhsScale_;
3317     numberIterations_ = rhs->numberIterations_;
3318     solveType_ = rhs->solveType_;
3319     whatsChanged_ = 0; // Too big a change
3320     problemStatus_ = rhs->problemStatus_;
3321     secondaryStatus_ = rhs->secondaryStatus_;
3322     // check valid lists
3323     int numberBad = 0;
3324     int i;
3325     for (i = 0; i < numberRows; i++)
3326          if (whichRow[i] < 0 || whichRow[i] >= rhs->numberRows_)
3327               numberBad++;
3328     CoinAssertHint(!numberBad, "Bad row list for subproblem constructor");
3329     numberBad = 0;
3330     for (i = 0; i < numberColumns; i++)
3331          if (whichColumn[i] < 0 || whichColumn[i] >= rhs->numberColumns_)
3332               numberBad++;
3333     CoinAssertHint(!numberBad, "Bad Column list for subproblem constructor");
3334     numberRows_ = numberRows;
3335     numberColumns_ = numberColumns;
3336     userPointer_ = rhs->userPointer_;
3337     trustedUserPointer_ = rhs->trustedUserPointer_;
3338     numberThreads_ = 0;
3339#ifndef CLP_NO_STD
3340     if (!dropNames) {
3341          unsigned int maxLength = 0;
3342          int iRow;
3343          rowNames_ = std::vector<std::string> ();
3344          columnNames_ = std::vector<std::string> ();
3345          rowNames_.reserve(numberRows_);
3346          for (iRow = 0; iRow < numberRows_; iRow++) {
3347               rowNames_.push_back(rhs->rowNames_[whichRow[iRow]]);
3348               maxLength = CoinMax(maxLength, static_cast<unsigned int> (strlen(rowNames_[iRow].c_str())));
3349          }
3350          int iColumn;
3351          columnNames_.reserve(numberColumns_);
3352          for (iColumn = 0; iColumn < numberColumns_; iColumn++) {
3353               columnNames_.push_back(rhs->columnNames_[whichColumn[iColumn]]);
3354               maxLength = CoinMax(maxLength, static_cast<unsigned int> (strlen(columnNames_[iColumn].c_str())));
3355          }
3356          lengthNames_ = static_cast<int> (maxLength);
3357     } else {
3358          lengthNames_ = 0;
3359          rowNames_ = std::vector<std::string> ();
3360          columnNames_ = std::vector<std::string> ();
3361     }
3362#endif
3363     if (rhs->integerType_ && !dropIntegers) {
3364          integerType_ = whichChar(rhs->integerType_, numberColumns, whichColumn);
3365     } else {
3366          integerType_ = NULL;
3367     }
3368     if (rhs->rowActivity_) {
3369          rowActivity_ = whichDouble(rhs->rowActivity_, numberRows, whichRow);
3370          dual_ = whichDouble(rhs->dual_, numberRows, whichRow);
3371          columnActivity_ = whichDouble(rhs->columnActivity_, numberColumns,
3372                                        whichColumn);
3373          reducedCost_ = whichDouble(rhs->reducedCost_, numberColumns,
3374                                     whichColumn);
3375     } else {
3376          rowActivity_ = NULL;
3377          columnActivity_ = NULL;
3378          dual_ = NULL;
3379          reducedCost_ = NULL;
3380     }
3381     rowLower_ = whichDouble(rhs->rowLower_, numberRows, whichRow);
3382     rowUpper_ = whichDouble(rhs->rowUpper_, numberRows, whichRow);
3383     columnLower_ = whichDouble(rhs->columnLower_, numberColumns, whichColumn);
3384     columnUpper_ = whichDouble(rhs->columnUpper_, numberColumns, whichColumn);
3385     if (rhs->objective_)
3386          objective_  = rhs->objective_->subsetClone(numberColumns, whichColumn);
3387     else
3388          objective_ = NULL;
3389     rowObjective_ = whichDouble(rhs->rowObjective_, numberRows, whichRow);
3390     // status has to be done in two stages
3391     if (rhs->status_) {
3392       status_ = new unsigned char[numberColumns_+numberRows_];
3393       unsigned char * rowStatus = whichUnsignedChar(rhs->status_ + rhs->numberColumns_,
3394                                                     numberRows_, whichRow);
3395       unsigned char * columnStatus = whichUnsignedChar(rhs->status_,
3396                                                        numberColumns_, whichColumn);
3397       CoinMemcpyN(rowStatus, numberRows_, status_ + numberColumns_);
3398       delete [] rowStatus;
3399       CoinMemcpyN(columnStatus, numberColumns_, status_);
3400       delete [] columnStatus;
3401     } else {
3402       status_=NULL;
3403     }
3404     ray_ = NULL;
3405     if (problemStatus_ == 1)
3406          ray_ = whichDouble (rhs->ray_, numberRows, whichRow);
3407     else if (problemStatus_ == 2)
3408          ray_ = whichDouble (rhs->ray_, numberColumns, whichColumn);
3409     rowScale_ = NULL;
3410     columnScale_ = NULL;
3411     inverseRowScale_ = NULL;
3412     inverseColumnScale_ = NULL;
3413     scalingFlag_ = rhs->scalingFlag_;
3414     rowCopy_ = NULL;
3415     scaledMatrix_ = NULL;
3416     matrix_ = NULL;
3417     if (rhs->matrix_) {
3418          matrix_ = rhs->matrix_->subsetClone(numberRows, whichRow,
3419                                              numberColumns, whichColumn);
3420     }
3421     randomNumberGenerator_ = rhs->randomNumberGenerator_;
3422}
3423#ifndef CLP_NO_STD
3424// Copies in names
3425void
3426ClpModel::copyNames(const std::vector<std::string> & rowNames,
3427                    const std::vector<std::string> & columnNames)
3428{
3429     unsigned int maxLength = 0;
3430     int iRow;
3431     rowNames_ = std::vector<std::string> ();
3432     columnNames_ = std::vector<std::string> ();
3433     rowNames_.reserve(numberRows_);
3434     for (iRow = 0; iRow < numberRows_; iRow++) {
3435          rowNames_.push_back(rowNames[iRow]);
3436          maxLength = CoinMax(maxLength, static_cast<unsigned int> (strlen(rowNames_[iRow].c_str())));
3437     }
3438     int iColumn;
3439     columnNames_.reserve(numberColumns_);
3440     for (iColumn = 0; iColumn < numberColumns_; iColumn++) {
3441          columnNames_.push_back(columnNames[iColumn]);
3442          maxLength = CoinMax(maxLength, static_cast<unsigned int> (strlen(columnNames_[iColumn].c_str())));
3443     }
3444     lengthNames_ = static_cast<int> (maxLength);
3445}
3446// Return name or Rnnnnnnn
3447std::string
3448ClpModel::getRowName(int iRow) const
3449{
3450#ifndef NDEBUG
3451     if (iRow < 0 || iRow >= numberRows_) {
3452          indexError(iRow, "getRowName");
3453     }
3454#endif
3455     int size = static_cast<int>(rowNames_.size());
3456     if (size > iRow) {
3457          return rowNames_[iRow];
3458     } else {
3459          char name[9];
3460          sprintf(name, "R%7.7d", iRow);
3461          std::string rowName(name);
3462          return rowName;
3463     }
3464}
3465// Set row name
3466void
3467ClpModel::setRowName(int iRow, std::string &name)
3468{
3469#ifndef NDEBUG
3470     if (iRow < 0 || iRow >= numberRows_) {
3471          indexError(iRow, "setRowName");
3472     }
3473#endif
3474     unsigned int maxLength = lengthNames_;
3475     int size = static_cast<int>(rowNames_.size());
3476     if (size <= iRow)
3477          rowNames_.resize(iRow + 1);
3478     rowNames_[iRow] = name;
3479     maxLength = CoinMax(maxLength, static_cast<unsigned int> (strlen(name.c_str())));
3480     // May be too big - but we would have to check both rows and columns to be exact
3481     lengthNames_ = static_cast<int> (maxLength);
3482}
3483// Return name or Cnnnnnnn
3484std::string
3485ClpModel::getColumnName(int iColumn) const
3486{
3487#ifndef NDEBUG
3488     if (iColumn < 0 || iColumn >= numberColumns_) {
3489          indexError(iColumn, "getColumnName");
3490     }
3491#endif
3492     int size = static_cast<int>(columnNames_.size());
3493     if (size > iColumn) {
3494          return columnNames_[iColumn];
3495     } else {
3496          char name[9];
3497          sprintf(name, "C%7.7d", iColumn);
3498          std::string columnName(name);
3499          return columnName;
3500     }
3501}
3502// Set column name
3503void
3504ClpModel::setColumnName(int iColumn, std::string &name)
3505{
3506#ifndef NDEBUG
3507     if (iColumn < 0 || iColumn >= numberColumns_) {
3508          indexError(iColumn, "setColumnName");
3509     }
3510#endif
3511     unsigned int maxLength = lengthNames_;
3512     int size = static_cast<int>(columnNames_.size());
3513     if (size <= iColumn)
3514          columnNames_.resize(iColumn + 1);
3515     columnNames_[iColumn] = name;
3516     maxLength = CoinMax(maxLength, static_cast<unsigned int> (strlen(name.c_str())));
3517     // May be too big - but we would have to check both columns and columns to be exact
3518     lengthNames_ = static_cast<int> (maxLength);
3519}
3520// Copies in Row names - modifies names first .. last-1
3521void
3522ClpModel::copyRowNames(const std::vector<std::string> & rowNames, int first, int last)
3523{
3524     // Do column names if necessary
3525     if (!lengthNames_&&numberColumns_) {
3526       lengthNames_=8;
3527       copyColumnNames(NULL,0,numberColumns_);
3528     }
3529     unsigned int maxLength = lengthNames_;
3530     int size = static_cast<int>(rowNames_.size());
3531     if (size != numberRows_)
3532          rowNames_.resize(numberRows_);
3533     int iRow;
3534     for (iRow = first; iRow < last; iRow++) {
3535          rowNames_[iRow] = rowNames[iRow-first];
3536          maxLength = CoinMax(maxLength, static_cast<unsigned int> (strlen(rowNames_[iRow-first].c_str())));
3537     }
3538     // May be too big - but we would have to check both rows and columns to be exact
3539     lengthNames_ = static_cast<int> (maxLength);
3540}
3541// Copies in Column names - modifies names first .. last-1
3542void
3543ClpModel::copyColumnNames(const std::vector<std::string> & columnNames, int first, int last)
3544{
3545     // Do row names if necessary
3546     if (!lengthNames_&&numberRows_) {
3547       lengthNames_=8;
3548       copyRowNames(NULL,0,numberRows_);
3549     }
3550     unsigned int maxLength = lengthNames_;
3551     int size = static_cast<int>(columnNames_.size());
3552     if (size != numberColumns_)
3553          columnNames_.resize(numberColumns_);
3554     int iColumn;
3555     for (iColumn = first; iColumn < last; iColumn++) {
3556          columnNames_[iColumn] = columnNames[iColumn-first];
3557          maxLength = CoinMax(maxLength, static_cast<unsigned int> (strlen(columnNames_[iColumn-first].c_str())));
3558     }
3559     // May be too big - but we would have to check both rows and columns to be exact
3560     lengthNames_ = static_cast<int> (maxLength);
3561}
3562// Copies in Row names - modifies names first .. last-1
3563void
3564ClpModel::copyRowNames(const char * const * rowNames, int first, int last)
3565{
3566     // Do column names if necessary
3567     if (!lengthNames_&&numberColumns_) {
3568       lengthNames_=8;
3569       copyColumnNames(NULL,0,numberColumns_);
3570     }
3571     unsigned int maxLength = lengthNames_;
3572     int size = static_cast<int>(rowNames_.size());
3573     if (size != numberRows_)
3574          rowNames_.resize(numberRows_);
3575     int iRow;
3576     for (iRow = first; iRow < last; iRow++) {
3577          if (rowNames && rowNames[iRow-first] && strlen(rowNames[iRow-first])) {
3578               rowNames_[iRow] = rowNames[iRow-first];
3579               maxLength = CoinMax(maxLength, static_cast<unsigned int> (strlen(rowNames[iRow-first])));
3580          } else {
3581               maxLength = CoinMax(maxLength, static_cast<unsigned int> (8));
3582               char name[9];
3583               sprintf(name, "R%7.7d", iRow);
3584               rowNames_[iRow] = name;
3585          }
3586     }
3587     // May be too big - but we would have to check both rows and columns to be exact
3588     lengthNames_ = static_cast<int> (maxLength);
3589}
3590// Copies in Column names - modifies names first .. last-1
3591void
3592ClpModel::copyColumnNames(const char * const * columnNames, int first, int last)
3593{
3594     // Do row names if necessary
3595     if (!lengthNames_&&numberRows_) {
3596       lengthNames_=8;
3597       copyRowNames(NULL,0,numberRows_);
3598     }
3599     unsigned int maxLength = lengthNames_;
3600     int size = static_cast<int>(columnNames_.size());
3601     if (size != numberColumns_)
3602          columnNames_.resize(numberColumns_);
3603     int iColumn;
3604     for (iColumn = first; iColumn < last; iColumn++) {
3605          if (columnNames && columnNames[iColumn-first] && strlen(columnNames[iColumn-first])) {
3606               columnNames_[iColumn] = columnNames[iColumn-first];
3607               maxLength = CoinMax(maxLength, static_cast<unsigned int> (strlen(columnNames[iColumn-first])));
3608          } else {
3609               maxLength = CoinMax(maxLength, static_cast<unsigned int> (8));
3610               char name[9];
3611               sprintf(name, "C%7.7d", iColumn);
3612               columnNames_[iColumn] = name;
3613          }
3614     }
3615     // May be too big - but we would have to check both rows and columns to be exact
3616     lengthNames_ = static_cast<int> (maxLength);
3617}
3618#endif
3619// Primal objective limit
3620void
3621ClpModel::setPrimalObjectiveLimit(double value)
3622{
3623     dblParam_[ClpPrimalObjectiveLimit] = value;
3624}
3625// Dual objective limit
3626void
3627ClpModel::setDualObjectiveLimit(double value)
3628{
3629     dblParam_[ClpDualObjectiveLimit] = value;
3630}
3631// Objective offset
3632void
3633ClpModel::setObjectiveOffset(double value)
3634{
3635     dblParam_[ClpObjOffset] = value;
3636}
3637// Solve a problem with no elements - return status
3638int ClpModel::emptyProblem(int * infeasNumber, double * infeasSum, bool printMessage)
3639{
3640     secondaryStatus_ = 6; // so user can see something odd
3641     if (printMessage)
3642          handler_->message(CLP_EMPTY_PROBLEM, messages_)
3643                    << numberRows_
3644                    << numberColumns_
3645                    << 0
3646                    << CoinMessageEol;
3647     int returnCode = 0;
3648     if (numberRows_ || numberColumns_) {
3649          if (!status_) {
3650               status_ = new unsigned char[numberRows_+numberColumns_];
3651               CoinZeroN(status_, numberRows_ + numberColumns_);
3652          }
3653     }
3654     // status is set directly (as can be used by Interior methods)
3655     // check feasible
3656     int numberPrimalInfeasibilities = 0;
3657     double sumPrimalInfeasibilities = 0.0;
3658     int numberDualInfeasibilities = 0;
3659     double sumDualInfeasibilities = 0.0;
3660     if (numberRows_) {
3661          for (int i = 0; i < numberRows_; i++) {
3662               dual_[i] = 0.0;
3663               if (rowLower_[i] <= rowUpper_[i]) {
3664                    if (rowLower_[i] > -1.0e30 || rowUpper_[i] < 1.0e30) {
3665                         if (rowLower_[i] <= 0.0 && rowUpper_[i] >= 0.0) {
3666                              if (fabs(rowLower_[i]) < fabs(rowUpper_[i]))
3667                                   rowActivity_[i] = rowLower_[i];
3668                              else
3669                                   rowActivity_[i] = rowUpper_[i];
3670                         } else {
3671                              rowActivity_[i] = 0.0;
3672                              numberPrimalInfeasibilities++;
3673                              sumPrimalInfeasibilities += CoinMin(rowLower_[i], -rowUpper_[i]);
3674                              returnCode = 1;
3675                         }
3676                    } else {
3677                         rowActivity_[i] = 0.0;
3678                    }
3679               } else {
3680                    rowActivity_[i] = 0.0;
3681                    numberPrimalInfeasibilities++;
3682                    sumPrimalInfeasibilities += rowLower_[i] - rowUpper_[i];
3683                    returnCode = 1;
3684               }
3685               status_[i+numberColumns_] = 1;
3686          }
3687     }
3688     objectiveValue_ = 0.0;
3689     if (numberColumns_) {
3690          const double * cost = objective();
3691          for (int i = 0; i < numberColumns_; i++) {
3692               reducedCost_[i] = cost[i];
3693               double objValue = cost[i] * optimizationDirection_;
3694               if (columnLower_[i] <= columnUpper_[i]) {
3695                    if (columnLower_[i] > -1.0e30 || columnUpper_[i] < 1.0e30) {
3696                         if (!objValue) {
3697                              if (fabs(columnLower_[i]) < fabs(columnUpper_[i])) {
3698                                   columnActivity_[i] = columnLower_[i];
3699                                   status_[i] = 3;
3700                              } else {
3701                                   columnActivity_[i] = columnUpper_[i];
3702                                   status_[i] = 2;
3703                              }
3704                         } else if (objValue > 0.0) {
3705                              if (columnLower_[i] > -1.0e30) {
3706                                   columnActivity_[i] = columnLower_[i];
3707                                   status_[i] = 3;
3708                              } else {
3709                                   columnActivity_[i] = columnUpper_[i];
3710                                   status_[i] = 2;
3711                                   numberDualInfeasibilities++;;
3712                                   sumDualInfeasibilities += fabs(objValue);
3713                                   returnCode |= 2;
3714                              }
3715                              objectiveValue_ += columnActivity_[i] * objValue;
3716                         } else {
3717                              if (columnUpper_[i] < 1.0e30) {
3718                                   columnActivity_[i] = columnUpper_[i];
3719                                   status_[i] = 2;
3720                              } else {
3721                                   columnActivity_[i] = columnLower_[i];
3722                                   status_[i] = 3;
3723                                   numberDualInfeasibilities++;;
3724                                   sumDualInfeasibilities += fabs(objValue);
3725                                   returnCode |= 2;
3726                              }
3727                              objectiveValue_ += columnActivity_[i] * objValue;
3728                         }
3729                    } else {
3730                         columnActivity_[i] = 0.0;
3731                         if (objValue) {
3732                              numberDualInfeasibilities++;;
3733                              sumDualInfeasibilities += fabs(objValue);
3734                              returnCode |= 2;
3735                         }
3736                         status_[i] = 0;
3737                    }
3738               } else {
3739                    if (fabs(columnLower_[i]) < fabs(columnUpper_[i])) {
3740                         columnActivity_[i] = columnLower_[i];
3741                         status_[i] = 3;
3742                    } else {
3743                         columnActivity_[i] = columnUpper_[i];
3744                         status_[i] = 2;
3745                    }
3746                    numberPrimalInfeasibilities++;
3747                    sumPrimalInfeasibilities += columnLower_[i] - columnUpper_[i];
3748                    returnCode |= 1;
3749               }
3750          }
3751     }
3752     objectiveValue_ /= (objectiveScale_ * rhsScale_);
3753     if (infeasNumber) {
3754          infeasNumber[0] = numberDualInfeasibilities;
3755          infeasSum[0] = sumDualInfeasibilities;
3756          infeasNumber[1] = numberPrimalInfeasibilities;
3757          infeasSum[1] = sumPrimalInfeasibilities;
3758     }
3759     if (returnCode == 3)
3760          returnCode = 4;
3761     return returnCode;
3762}
3763#ifndef SLIM_NOIO
3764/* Write the problem in MPS format to the specified file.
3765
3766Row and column names may be null.
3767formatType is
3768<ul>
3769<li> 0 - normal
3770<li> 1 - extra accuracy
3771<li> 2 - IEEE hex (later)
3772</ul>
3773
3774Returns non-zero on I/O error
3775*/
3776int
3777ClpModel::writeMps(const char *filename,
3778                   int formatType, int numberAcross,
3779                   double objSense) const
3780{
3781     matrix_->setDimensions(numberRows_, numberColumns_);
3782
3783     // Get multiplier for objective function - default 1.0
3784     double * objective = new double[numberColumns_];
3785     CoinMemcpyN(getObjCoefficients(), numberColumns_, objective);
3786     if (objSense * getObjSense() < 0.0) {
3787          for (int i = 0; i < numberColumns_; ++i)
3788               objective [i] = - objective[i];
3789     }
3790     // get names
3791     const char * const * const rowNames = rowNamesAsChar();
3792     const char * const * const columnNames = columnNamesAsChar();
3793     CoinMpsIO writer;
3794     writer.passInMessageHandler(handler_);
3795     *writer.messagesPointer() = coinMessages();
3796     writer.setMpsData(*(matrix_->getPackedMatrix()), COIN_DBL_MAX,
3797                       getColLower(), getColUpper(),
3798                       objective,
3799                       reinterpret_cast<const char*> (NULL) /*integrality*/,
3800                       getRowLower(), getRowUpper(),
3801                       columnNames, rowNames);
3802     // Pass in array saying if each variable integer
3803     writer.copyInIntegerInformation(integerInformation());
3804     writer.setObjectiveOffset(objectiveOffset());
3805     delete [] objective;
3806     CoinPackedMatrix * quadratic = NULL;
3807#ifndef SLIM_CLP
3808     // allow for quadratic objective
3809#ifndef NO_RTTI
3810     ClpQuadraticObjective * quadraticObj = (dynamic_cast< ClpQuadraticObjective*>(objective_));
3811#else
3812     ClpQuadraticObjective * quadraticObj = NULL;
3813     if (objective_->type() == 2)
3814          quadraticObj = (static_cast< ClpQuadraticObjective*>(objective_));
3815#endif
3816     if (quadraticObj)
3817          quadratic = quadraticObj->quadraticObjective();
3818#endif
3819     int returnCode = writer.writeMps(filename, 0 /* do not gzip it*/, formatType, numberAcross,
3820                                      quadratic);
3821     if (rowNames) {
3822          deleteNamesAsChar(rowNames, numberRows_ + 1);
3823          deleteNamesAsChar(columnNames, numberColumns_);
3824     }
3825     return returnCode;
3826}
3827#ifndef CLP_NO_STD
3828// Create row names as char **
3829const char * const *
3830ClpModel::rowNamesAsChar() const
3831{
3832     char ** rowNames = NULL;
3833     if (lengthNames()) {
3834          rowNames = new char * [numberRows_+1];
3835          int numberNames = static_cast<int>(rowNames_.size());
3836          numberNames = CoinMin(numberRows_, numberNames);
3837          int iRow;
3838          for (iRow = 0; iRow < numberNames; iRow++) {
3839               if (rowName(iRow) != "") {
3840                    rowNames[iRow] =
3841                         CoinStrdup(rowName(iRow).c_str());
3842               } else {
3843                    char name[9];
3844                    sprintf(name, "R%7.7d", iRow);
3845                    rowNames[iRow] = CoinStrdup(name);
3846               }
3847#ifdef STRIPBLANKS
3848               char * xx = rowNames[iRow];
3849               int i;
3850               int length = strlen(xx);
3851               int n = 0;
3852               for (i = 0; i < length; i++) {
3853                    if (xx[i] != ' ')
3854                         xx[n++] = xx[i];
3855               }
3856               xx[n] = '\0';
3857#endif
3858          }
3859          char name[9];
3860          for ( ; iRow < numberRows_; iRow++) {
3861               sprintf(name, "R%7.7d", iRow);
3862               rowNames[iRow] = CoinStrdup(name);
3863          }
3864          rowNames[numberRows_] = CoinStrdup("OBJROW");
3865     }
3866     return reinterpret_cast<const char * const *>(rowNames);
3867}
3868// Create column names as char **
3869const char * const *
3870ClpModel::columnNamesAsChar() const
3871{
3872     char ** columnNames = NULL;
3873     if (lengthNames()) {
3874          columnNames = new char * [numberColumns_];
3875          int numberNames = static_cast<int>(columnNames_.size());
3876          numberNames = CoinMin(numberColumns_, numberNames);
3877          int iColumn;
3878          for (iColumn = 0; iColumn < numberNames; iColumn++) {
3879               if (columnName(iColumn) != "") {
3880                    columnNames[iColumn] =
3881                         CoinStrdup(columnName(iColumn).c_str());
3882               } else {
3883                    char name[9];
3884                    sprintf(name, "C%7.7d", iColumn);
3885                    columnNames[iColumn] = CoinStrdup(name);
3886               }
3887#ifdef STRIPBLANKS
3888               char * xx = columnNames[iColumn];
3889               int i;
3890               int length = strlen(xx);
3891               int n = 0;
3892               for (i = 0; i < length; i++) {
3893                    if (xx[i] != ' ')
3894                         xx[n++] = xx[i];
3895               }
3896               xx[n] = '\0';
3897#endif
3898          }
3899          char name[9];
3900          for ( ; iColumn < numberColumns_; iColumn++) {
3901               sprintf(name, "C%7.7d", iColumn);
3902               columnNames[iColumn] = CoinStrdup(name);
3903          }
3904     }
3905     return /*reinterpret_cast<const char * const *>*/(columnNames);
3906}
3907// Delete char * version of names
3908void
3909ClpModel::deleteNamesAsChar(const char * const * names, int number) const
3910{
3911     for (int i = 0; i < number; i++) {
3912          free(const_cast<char *>(names[i]));
3913     }
3914     delete [] const_cast<char **>(names);
3915}
3916#endif
3917#endif
3918// Pass in Event handler (cloned and deleted at end)
3919void
3920ClpModel::passInEventHandler(const ClpEventHandler * eventHandler)
3921{
3922     delete eventHandler_;
3923     eventHandler_ = eventHandler->clone();
3924}
3925// Sets or unsets scaling, 0 -off, 1 on, 2 dynamic(later)
3926void
3927ClpModel::scaling(int mode)
3928{
3929     // If mode changes then we treat as new matrix (need new row copy)
3930     if (mode != scalingFlag_) {
3931          whatsChanged_ &= ~(2 + 4 + 8);
3932          // Get rid of scaled matrix
3933          setClpScaledMatrix(NULL);
3934     }
3935     if (mode > 0 && mode < 6) {
3936          scalingFlag_ = mode;
3937     } else if (!mode) {
3938          scalingFlag_ = 0;
3939          setRowScale(NULL);
3940          setColumnScale(NULL);
3941     }
3942}
3943void
3944ClpModel::times(double scalar,
3945                const double * x, double * y) const
3946{
3947     if (!scaledMatrix_ || !rowScale_) {
3948          if (rowScale_)
3949               matrix_->times(scalar, x, y, rowScale_, columnScale_);
3950          else
3951               matrix_->times(scalar, x, y);
3952     } else {
3953          scaledMatrix_->times(scalar, x, y);
3954     }
3955}
3956void
3957ClpModel::transposeTimes(double scalar,
3958                         const double * x, double * y) const
3959{
3960     if (!scaledMatrix_ || !rowScale_) {
3961          if (rowScale_)
3962               matrix_->transposeTimes(scalar, x, y, rowScale_, columnScale_, NULL);
3963          else
3964               matrix_->transposeTimes(scalar, x, y);
3965     } else {
3966          scaledMatrix_->transposeTimes(scalar, x, y);
3967     }
3968}
3969// Does much of scaling
3970void
3971ClpModel::gutsOfScaling()
3972{
3973     int i;
3974     if (rowObjective_) {
3975          for (i = 0; i < numberRows_; i++)
3976               rowObjective_[i] /= rowScale_[i];
3977     }
3978     for (i = 0; i < numberRows_; i++) {
3979          double multiplier = rowScale_[i];
3980          double inverseMultiplier = 1.0 / multiplier;
3981          rowActivity_[i] *= multiplier;
3982          dual_[i] *= inverseMultiplier;
3983          if (rowLower_[i] > -1.0e30)
3984               rowLower_[i] *= multiplier;
3985          else
3986               rowLower_[i] = -COIN_DBL_MAX;
3987          if (rowUpper_[i] < 1.0e30)
3988               rowUpper_[i] *= multiplier;
3989          else
3990               rowUpper_[i] = COIN_DBL_MAX;
3991     }
3992     for (i = 0; i < numberColumns_; i++) {
3993          double multiplier = 1.0 * inverseColumnScale_[i];
3994          columnActivity_[i] *= multiplier;
3995          reducedCost_[i] *= columnScale_[i];
3996          if (columnLower_[i] > -1.0e30)
3997               columnLower_[i] *= multiplier;
3998          else
3999               columnLower_[i] = -COIN_DBL_MAX;
4000          if (columnUpper_[i] < 1.0e30)
4001               columnUpper_[i] *= multiplier;
4002          else
4003               columnUpper_[i] = COIN_DBL_MAX;
4004
4005     }
4006     //now replace matrix
4007     //and objective
4008     matrix_->reallyScale(rowScale_, columnScale_);
4009     objective_->reallyScale(columnScale_);
4010}
4011/* If we constructed a "really" scaled model then this reverses the operation.
4012      Quantities may not be exactly as they were before due to rounding errors */
4013void
4014ClpModel::unscale()
4015{
4016     if (rowScale_) {
4017          int i;
4018          // reverse scaling
4019          for (i = 0; i < numberRows_; i++)
4020               rowScale_[i] = 1.0 * inverseRowScale_[i];
4021          for (i = 0; i < numberColumns_; i++)
4022               columnScale_[i] = 1.0 * inverseColumnScale_[i];
4023          gutsOfScaling();
4024     }
4025
4026     scalingFlag_ = 0;
4027     setRowScale(NULL);
4028     setColumnScale(NULL);
4029}
4030void
4031ClpModel::setSpecialOptions(unsigned int value)
4032{
4033     specialOptions_ = value;
4034}
4035/* This creates a coinModel object
4036 */
4037CoinModel *
4038ClpModel::createCoinModel() const
4039{
4040     CoinModel * coinModel = new CoinModel();
4041     CoinPackedMatrix matrixByRow;
4042     matrixByRow.setExtraGap(0.0);
4043     matrixByRow.setExtraMajor(0.0);
4044     matrixByRow.reverseOrderedCopyOf(*matrix());
4045     coinModel->setObjectiveOffset(objectiveOffset());
4046     coinModel->setProblemName(problemName().c_str());
4047
4048     // Build by row from scratch
4049     const double * element = matrixByRow.getElements();
4050     const int * column = matrixByRow.getIndices();
4051     const CoinBigIndex * rowStart = matrixByRow.getVectorStarts();
4052     const int * rowLength = matrixByRow.getVectorLengths();
4053     int i;
4054     for (i = 0; i < numberRows_; i++) {
4055          coinModel->addRow(rowLength[i], column + rowStart[i],
4056                            element + rowStart[i], rowLower_[i], rowUpper_[i]);
4057     }
4058     // Now do column part
4059     const double * objective = this->objective();
4060     for (i = 0; i < numberColumns_; i++) {
4061          coinModel->setColumnBounds(i, columnLower_[i], columnUpper_[i]);
4062          coinModel->setColumnObjective(i, objective[i]);
4063     }
4064     for ( i = 0; i < numberColumns_; i++) {
4065          if (isInteger(i))
4066               coinModel->setColumnIsInteger(i, true);
4067     }
4068     // do names - clear out
4069     coinModel->zapRowNames();
4070     coinModel->zapColumnNames();
4071     for (i = 0; i < numberRows_; i++) {
4072          char temp[30];
4073          strcpy(temp, rowName(i).c_str());
4074          size_t length = strlen(temp);
4075          for (size_t j = 0; j < length; j++) {
4076               if (temp[j] == '-')
4077                    temp[j] = '_';
4078          }
4079          coinModel->setRowName(i, temp);
4080     }
4081     for (i = 0; i < numberColumns_; i++) {
4082          char temp[30];
4083          strcpy(temp, columnName(i).c_str());
4084          size_t length = strlen(temp);
4085          for (size_t j = 0; j < length; j++) {
4086               if (temp[j] == '-')
4087                    temp[j] = '_';
4088          }
4089          coinModel->setColumnName(i, temp);
4090     }
4091     ClpQuadraticObjective * obj = (dynamic_cast< ClpQuadraticObjective*>(objective_));
4092     if (obj) {
4093          const CoinPackedMatrix * quadObj = obj->quadraticObjective();
4094          // add in quadratic
4095          const double * element = quadObj->getElements();
4096          const int * row = quadObj->getIndices();
4097          const CoinBigIndex * columnStart = quadObj->getVectorStarts();
4098          const int * columnLength = quadObj->getVectorLengths();
4099          for (i = 0; i < numberColumns_; i++) {
4100               int nels = columnLength[i];
4101               if (nels) {
4102                    CoinBigIndex start = columnStart[i];
4103                    double constant = coinModel->getColumnObjective(i);
4104                    char temp[100000];
4105                    char temp2[30];
4106                    sprintf(temp, "%g", constant);
4107                    for (CoinBigIndex k = start; k < start + nels; k++) {
4108                         int kColumn = row[k];
4109                         double value = element[k];
4110#if 1
4111                         // ampl gives twice with assumed 0.5
4112                         if (kColumn < i)
4113                              continue;
4114                         else if (kColumn == i)
4115                              value *= 0.5;
4116#endif
4117                         if (value == 1.0)
4118                              sprintf(temp2, "+%s", coinModel->getColumnName(kColumn));
4119                         else if (value == -1.0)
4120                              sprintf(temp2, "-%s", coinModel->getColumnName(kColumn));
4121                         else if (value > 0.0)
4122                              sprintf(temp2, "+%g*%s", value, coinModel->getColumnName(kColumn));
4123                         else
4124                              sprintf(temp2, "%g*%s", value, coinModel->getColumnName(kColumn));
4125                         strcat(temp, temp2);
4126                         assert (strlen(temp) < 100000);
4127                    }
4128                    coinModel->setObjective(i, temp);
4129                    if (logLevel() > 2)
4130                         printf("el for objective column %s is %s\n", coinModel->getColumnName(i), temp);
4131               }
4132          }
4133     }
4134     return coinModel;
4135}
4136// Start or reset using maximumRows_ and Columns_
4137void
4138ClpModel::startPermanentArrays()
4139{
4140     COIN_DETAIL_PRINT(printf("startperm a %d rows, %d maximum rows\n",
4141                              numberRows_, maximumRows_));
4142     if ((specialOptions_ & 65536) != 0) {
4143          if (numberRows_ > maximumRows_ || numberColumns_ > maximumColumns_) {
4144               if (numberRows_ > maximumRows_) {
4145                    if (maximumRows_ > 0)
4146                         maximumRows_ = numberRows_ + 10 + numberRows_ / 100;
4147                    else
4148                         maximumRows_ = numberRows_;
4149               }
4150               if (numberColumns_ > maximumColumns_) {
4151                    if (maximumColumns_ > 0)
4152                         maximumColumns_ = numberColumns_ + 10 + numberColumns_ / 100;
4153                    else
4154                         maximumColumns_ = numberColumns_;
4155               }
4156               // need to make sure numberRows_ OK and size of matrices
4157               resize(maximumRows_, maximumColumns_);
4158               COIN_DETAIL_PRINT(printf("startperm b %d rows, %d maximum rows\n",
4159                                        numberRows_, maximumRows_));
4160          } else {
4161               return;
4162          }
4163     } else {
4164          specialOptions_ |= 65536;
4165          maximumRows_ = numberRows_;
4166          maximumColumns_ = numberColumns_;
4167          baseMatrix_ = *matrix();
4168          baseMatrix_.cleanMatrix();
4169          baseRowCopy_.setExtraGap(0.0);
4170          baseRowCopy_.setExtraMajor(0.0);
4171          baseRowCopy_.reverseOrderedCopyOf(baseMatrix_);
4172          COIN_DETAIL_PRINT(printf("startperm c %d rows, %d maximum rows\n",
4173                                   numberRows_, maximumRows_));
4174     }
4175}
4176// Stop using maximumRows_ and Columns_
4177void
4178ClpModel::stopPermanentArrays()
4179{
4180     specialOptions_ &= ~65536;
4181     maximumRows_ = -1;
4182     maximumColumns_ = -1;
4183     if (rowScale_ != savedRowScale_) {
4184          delete [] savedRowScale_;
4185          delete [] savedColumnScale_;
4186     }
4187     savedRowScale_ = NULL;
4188     savedColumnScale_ = NULL;
4189}
4190// Set new row matrix
4191void
4192ClpModel::setNewRowCopy(ClpMatrixBase * newCopy)
4193{
4194     delete rowCopy_;
4195     rowCopy_ = newCopy;
4196}
4197/* Find a network subset.
4198   rotate array should be numberRows.  On output
4199   -1 not in network
4200   0 in network as is
4201   1 in network with signs swapped
4202  Returns number of network rows (positive if exact network, negative if needs extra row)
4203  From Gulpinar, Gutin, Maros and Mitra
4204*/
4205int
4206ClpModel::findNetwork(char * rotate, double fractionNeeded)
4207{
4208     int * mapping = new int [numberRows_];
4209     // Get column copy
4210     CoinPackedMatrix * columnCopy = matrix();
4211     // Get a row copy in standard format
4212     CoinPackedMatrix * copy = new CoinPackedMatrix();
4213     copy->setExtraGap(0.0);
4214     copy->setExtraMajor(0.0);
4215     copy->reverseOrderedCopyOf(*columnCopy);
4216     // make sure ordered and no gaps
4217     copy->cleanMatrix();
4218     // get matrix data pointers
4219     const int * columnIn = copy->getIndices();
4220     const CoinBigIndex * rowStartIn = copy->getVectorStarts();
4221     const int * rowLength = copy->getVectorLengths();
4222     const double * elementByRowIn = copy->getElements();
4223     int iRow, iColumn;
4224     int numberEligible = 0;
4225     int numberIn = 0;
4226     int numberElements = 0;
4227     for (iRow = 0; iRow < numberRows_; iRow++) {
4228          bool possible = true;
4229          mapping[iRow] = -1;
4230          rotate[iRow] = -1;
4231          for (CoinBigIndex j = rowStartIn[iRow]; j < rowStartIn[iRow] + rowLength[iRow]; j++) {
4232               //int iColumn = column[j];
4233               double value = elementByRowIn[j];
4234               if (fabs(value) != 1.0) {
4235                    possible = false;
4236                    break;
4237               }
4238          }
4239          if (rowLength[iRow] && possible) {
4240               mapping[iRow] = numberEligible;
4241               numberEligible++;
4242               numberElements += rowLength[iRow];
4243          }
4244     }
4245     if (numberEligible < fractionNeeded * numberRows_) {
4246          delete [] mapping;
4247          delete copy;
4248          return 0;
4249     }
4250     // create arrays
4251     int * eligible = new int [numberRows_];
4252     int * column = new int [numberElements];
4253     CoinBigIndex * rowStart = new CoinBigIndex [numberEligible+1];
4254     char * elementByRow = new char [numberElements];
4255     numberEligible = 0;
4256     numberElements = 0;
4257     rowStart[0] = 0;
4258     for (iRow = 0; iRow < numberRows_; iRow++) {
4259          if (mapping[iRow] < 0)
4260               continue;
4261          assert (numberEligible == mapping[iRow]);
4262          rotate[numberEligible] = 0;
4263          for (CoinBigIndex j = rowStartIn[iRow]; j < rowStartIn[iRow] + rowLength[iRow]; j++) {
4264               column[numberElements] = columnIn[j];
4265               double value = elementByRowIn[j];
4266               if (value == 1.0)
4267                    elementByRow[numberElements++] = 1;
4268               else
4269                    elementByRow[numberElements++] = -1;
4270          }
4271          numberEligible++;
4272          rowStart[numberEligible] = numberElements;
4273     }
4274     // get rid of copy to save space
4275     delete copy;
4276     const int * rowIn = columnCopy->getIndices();
4277     const CoinBigIndex * columnStartIn = columnCopy->getVectorStarts();
4278     const int * columnLengthIn = columnCopy->getVectorLengths();
4279     const double * elementByColumnIn = columnCopy->getElements();
4280     int * columnLength = new int [numberColumns_];
4281     // May just be that is a network - worth checking
4282     bool isNetworkAlready = true;
4283     bool trueNetwork = true;
4284     for (iColumn = 0; iColumn < numberColumns_; iColumn++) {
4285          double product = 1.0;
4286          int n = 0;
4287          for (CoinBigIndex j = columnStartIn[iColumn]; j < columnStartIn[iColumn] + columnLengthIn[iColumn]; j++) {
4288               iRow = mapping[rowIn[j]];
4289               if (iRow >= 0) {
4290                    n++;
4291                    product *= elementByColumnIn[j];
4292               }
4293          }
4294          if (n >= 2) {
4295               if (product != -1.0 || n > 2)
4296                    isNetworkAlready = false;
4297          } else if (n == 1) {
4298               trueNetwork = false;
4299          }
4300          columnLength[iColumn] = n;
4301     }
4302     if (!isNetworkAlready) {
4303          // For sorting
4304          double * count = new double [numberRows_];
4305          int * which = new int [numberRows_];
4306          int numberLast = -1;
4307          // Count for columns
4308          char * columnCount = new char[numberColumns_];
4309          memset(columnCount, 0, numberColumns_);
4310          char * currentColumnCount = new char[numberColumns_];
4311          // Now do main loop
4312          while (numberIn > numberLast) {
4313               numberLast = numberIn;
4314               int numberLeft = 0;
4315               for (iRow = 0; iRow < numberEligible; iRow++) {
4316                    if (rotate[iRow] == 0 && rowStart[iRow+1] > rowStart[iRow]) {
4317                         which[numberLeft] = iRow;
4318                         int merit = 0;
4319                         bool OK = true;
4320                         bool reflectionOK = true;
4321                         for (CoinBigIndex j = rowStart[iRow]; j < rowStart[iRow+1]; j++) {
4322                              iColumn = column[j];
4323                              int iCount = columnCount[iColumn];
4324                              int absCount = CoinAbs(iCount);
4325                              if (absCount < 2) {
4326                                   merit = CoinMax(columnLength[iColumn] - absCount - 1, merit);
4327                                   if (elementByRow[j] == iCount)
4328                                        OK = false;
4329                                   else if (elementByRow[j] == -iCount)
4330                                        reflectionOK = false;
4331                              } else {
4332                                   merit = -2;
4333                                   break;
4334                              }
4335                         }
4336                         if (merit > -2 && (OK || reflectionOK) &&
4337                                   (!OK || !reflectionOK || !numberIn)) {
4338                              //if (!numberLast) merit=1;
4339                              count[numberLeft++] = (rowStart[iRow+1] - rowStart[iRow] - 1) *
4340                                                    (static_cast<double>(merit));
4341                              if (OK)
4342                                   rotate[iRow] = 0;
4343                              else
4344                                   rotate[iRow] = 1;
4345                         } else {
4346                              // no good
4347                              rotate[iRow] = -1;
4348                         }
4349                    }
4350               }
4351               CoinSort_2(count, count + numberLeft, which);
4352               // Get G
4353               memset(currentColumnCount, 0, numberColumns_);
4354               for (iRow = 0; iRow < numberLeft; iRow++) {
4355                    int jRow = which[iRow];
4356                    bool possible = true;
4357                    for (int i = 0; i < numberIn; i++) {
4358                         for (CoinBigIndex j = rowStart[jRow]; j < rowStart[jRow+1]; j++) {
4359                              if (currentColumnCount[column[j]]) {
4360                                   possible = false;
4361                                   break;
4362                              }
4363                         }
4364                    }
4365                    if (possible) {
4366                         rotate[jRow] = static_cast<char>(rotate[jRow] + 2);
4367                         eligible[numberIn++] = jRow;
4368                         char multiplier = static_cast<char>((rotate[jRow] == 2) ? 1 : -1);
4369                         for (CoinBigIndex j = rowStart[jRow]; j < rowStart[jRow+1]; j++) {
4370                              iColumn = column[j];
4371                              currentColumnCount[iColumn]++;
4372                              int iCount = columnCount[iColumn];
4373                              int absCount = CoinAbs(iCount);
4374                              if (!absCount) {
4375                                   columnCount[iColumn] = static_cast<char>(elementByRow[j] * multiplier);
4376                              } else {
4377                                   columnCount[iColumn] = 2;
4378                              }
4379                         }
4380                    }
4381               }
4382          }
4383#ifndef NDEBUG
4384          for (iRow = 0; iRow < numberIn; iRow++) {
4385               int kRow = eligible[iRow];
4386               assert (rotate[kRow] >= 2);
4387          }
4388#endif
4389          trueNetwork = true;
4390          for (iColumn = 0; iColumn < numberColumns_; iColumn++) {
4391               if (CoinAbs(static_cast<int>(columnCount[iColumn])) == 1) {
4392                    trueNetwork = false;
4393                    break;
4394               }
4395          }
4396          delete [] currentColumnCount;
4397          delete [] columnCount;
4398          delete [] which;
4399          delete [] count;
4400     } else {
4401          numberIn = numberEligible;
4402          for (iRow = 0; iRow < numberRows_; iRow++) {
4403               int kRow = mapping[iRow];
4404               if (kRow >= 0) {
4405                    rotate[kRow] = 2;
4406               }
4407          }
4408     }
4409     if (!trueNetwork)
4410          numberIn = - numberIn;
4411     delete [] column;
4412     delete [] rowStart;
4413     delete [] elementByRow;
4414     delete [] columnLength;
4415     // redo rotate
4416     char * rotate2 = CoinCopyOfArray(rotate, numberEligible);
4417     for (iRow = 0; iRow < numberRows_; iRow++) {
4418          int kRow = mapping[iRow];
4419          if (kRow >= 0) {
4420               int iState = rotate2[kRow];
4421               if (iState > 1)
4422                    iState -= 2;
4423               else
4424                    iState = -1;
4425               rotate[iRow] = static_cast<char>(iState);
4426          } else {
4427               rotate[iRow] = -1;
4428          }
4429     }
4430     delete [] rotate2;
4431     delete [] eligible;
4432     delete [] mapping;
4433     return numberIn;
4434}
4435//#############################################################################
4436// Constructors / Destructor / Assignment
4437//#############################################################################
4438
4439//-------------------------------------------------------------------
4440// Default Constructor
4441//-------------------------------------------------------------------
4442ClpDataSave::ClpDataSave ()
4443{
4444     dualBound_ = 0.0;
4445     infeasibilityCost_ = 0.0;
4446     sparseThreshold_ = 0;
4447     pivotTolerance_ = 0.0;
4448     zeroFactorizationTolerance_ = 1.0e13;
4449     zeroSimplexTolerance_ = 1.0e-13;
4450     acceptablePivot_ = 0.0;
4451     objectiveScale_ = 1.0;
4452     perturbation_ = 0;
4453     forceFactorization_ = -1;
4454     scalingFlag_ = 0;
4455     specialOptions_ = 0;
4456}
4457
4458//-------------------------------------------------------------------
4459// Copy constructor
4460//-------------------------------------------------------------------
4461ClpDataSave::ClpDataSave (const ClpDataSave & rhs)
4462{
4463     dualBound_ = rhs.dualBound_;
4464     infeasibilityCost_ = rhs.infeasibilityCost_;
4465     pivotTolerance_ = rhs.pivotTolerance_;
4466     zeroFactorizationTolerance_ = rhs.zeroFactorizationTolerance_;
4467     zeroSimplexTolerance_ = rhs.zeroSimplexTolerance_;
4468     acceptablePivot_ = rhs.acceptablePivot_;
4469     objectiveScale_ = rhs.objectiveScale_;
4470     sparseThreshold_ = rhs.sparseThreshold_;
4471     perturbation_ = rhs.perturbation_;
4472     forceFactorization_ = rhs.forceFactorization_;
4473     scalingFlag_ = rhs.scalingFlag_;
4474     specialOptions_ = rhs.specialOptions_;
4475}
4476
4477//-------------------------------------------------------------------
4478// Destructor
4479//-------------------------------------------------------------------
4480ClpDataSave::~ClpDataSave ()
4481{
4482}
4483
4484//----------------------------------------------------------------
4485// Assignment operator
4486//-------------------------------------------------------------------
4487ClpDataSave &
4488ClpDataSave::operator=(const ClpDataSave& rhs)
4489{
4490     if (this != &rhs) {
4491          dualBound_ = rhs.dualBound_;
4492          infeasibilityCost_ = rhs.infeasibilityCost_;
4493          pivotTolerance_ = rhs.pivotTolerance_;
4494          zeroFactorizationTolerance_ = zeroFactorizationTolerance_;
4495          zeroSimplexTolerance_ = zeroSimplexTolerance_;
4496          acceptablePivot_ = rhs.acceptablePivot_;
4497          objectiveScale_ = rhs.objectiveScale_;
4498          sparseThreshold_ = rhs.sparseThreshold_;
4499          perturbation_ = rhs.perturbation_;
4500          forceFactorization_ = rhs.forceFactorization_;
4501          scalingFlag_ = rhs.scalingFlag_;
4502          specialOptions_ = rhs.specialOptions_;
4503     }
4504     return *this;
4505}
4506// Create C++ lines to get to current state
4507void
4508ClpModel::generateCpp( FILE * fp)
4509{
4510     // Stuff that can't be done easily
4511     if (!lengthNames_) {
4512          // no names
4513          fprintf(fp, "  clpModel->dropNames();\n");
4514     }
4515     ClpModel defaultModel;
4516     ClpModel * other = &defaultModel;
4517     int iValue1, iValue2;
4518     double dValue1, dValue2;
4519     iValue1 = this->maximumIterations();
4520     iValue2 = other->maximumIterations();
4521     fprintf(fp, "%d  int save_maximumIterations = clpModel->maximumIterations();\n", iValue1 == iValue2 ? 2 : 1);
4522     fprintf(fp, "%d  clpModel->setMaximumIterations(%d);\n", iValue1 == iValue2 ? 4 : 3, iValue1);
4523     fprintf(fp, "%d  clpModel->setMaximumIterations(save_maximumIterations);\n", iValue1 == iValue2 ? 7 : 6);
4524     dValue1 = this->primalTolerance();
4525     dValue2 = other->primalTolerance();
4526     fprintf(fp, "%d  double save_primalTolerance = clpModel->primalTolerance();\n", dValue1 == dValue2 ? 2 : 1);
4527     fprintf(fp, "%d  clpModel->setPrimalTolerance(%g);\n", dValue1 == dValue2 ? 4 : 3, dValue1);
4528     fprintf(fp, "%d  clpModel->setPrimalTolerance(save_primalTolerance);\n", dValue1 == dValue2 ? 7 : 6);
4529     dValue1 = this->dualTolerance();
4530     dValue2 = other->dualTolerance();
4531     fprintf(fp, "%d  double save_dualTolerance = clpModel->dualTolerance();\n", dValue1 == dValue2 ? 2 : 1);
4532     fprintf(fp, "%d  clpModel->setDualTolerance(%g);\n", dValue1 == dValue2 ? 4 : 3, dValue1);
4533     fprintf(fp, "%d  clpModel->setDualTolerance(save_dualTolerance);\n", dValue1 == dValue2 ? 7 : 6);
4534     iValue1 = this->numberIterations();
4535     iValue2 = other->numberIterations();
4536     fprintf(fp, "%d  int save_numberIterations = clpModel->numberIterations();\n", iValue1 == iValue2 ? 2 : 1);
4537     fprintf(fp, "%d  clpModel->setNumberIterations(%d);\n", iValue1 == iValue2 ? 4 : 3, iValue1);
4538     fprintf(fp, "%d  clpModel->setNumberIterations(save_numberIterations);\n", iValue1 == iValue2 ? 7 : 6);
4539     dValue1 = this->maximumSeconds();
4540     dValue2 = other->maximumSeconds();
4541     fprintf(fp, "%d  double save_maximumSeconds = clpModel->maximumSeconds();\n", dValue1 == dValue2 ? 2 : 1);
4542     fprintf(fp, "%d  clpModel->setMaximumSeconds(%g);\n", dValue1 == dValue2 ? 4 : 3, dValue1);
4543     fprintf(fp, "%d  clpModel->setMaximumSeconds(save_maximumSeconds);\n", dValue1 == dValue2 ? 7 : 6);
4544     dValue1 = this->optimizationDirection();
4545     dValue2 = other->optimizationDirection();
4546     fprintf(fp, "%d  double save_optimizationDirection = clpModel->optimizationDirection();\n", dValue1 == dValue2 ? 2 : 1);
4547     fprintf(fp, "%d  clpModel->setOptimizationDirection(%g);\n", dValue1 == dValue2 ? 4 : 3, dValue1);
4548     fprintf(fp, "%d  clpModel->setOptimizationDirection(save_optimizationDirection);\n", dValue1 == dValue2 ? 7 : 6);
4549     dValue1 = this->objectiveScale();
4550     dValue2 = other->objectiveScale();
4551     fprintf(fp, "%d  double save_objectiveScale = clpModel->objectiveScale();\n", dValue1 == dValue2 ? 2 : 1);
4552     fprintf(fp, "%d  clpModel->setObjectiveScale(%g);\n", dValue1 == dValue2 ? 4 : 3, dValue1);
4553     fprintf(fp, "%d  clpModel->setObjectiveScale(save_objectiveScale);\n", dValue1 == dValue2 ? 7 : 6);
4554     dValue1 = this->rhsScale();
4555     dValue2 = other->rhsScale();
4556     fprintf(fp, "%d  double save_rhsScale = clpModel->rhsScale();\n", dValue1 == dValue2 ? 2 : 1);
4557     fprintf(fp, "%d  clpModel->setRhsScale(%g);\n", dValue1 == dValue2 ? 4 : 3, dValue1);
4558     fprintf(fp, "%d  clpModel->setRhsScale(save_rhsScale);\n", dValue1 == dValue2 ? 7 : 6);
4559     iValue1 = this->scalingFlag();
4560     iValue2 = other->scalingFlag();
4561     fprintf(fp, "%d  int save_scalingFlag = clpModel->scalingFlag();\n", iValue1 == iValue2 ? 2 : 1);
4562     fprintf(fp, "%d  clpModel->scaling(%d);\n", iValue1 == iValue2 ? 4 : 3, iValue1);
4563     fprintf(fp, "%d  clpModel->scaling(save_scalingFlag);\n", iValue1 == iValue2 ? 7 : 6);
4564     dValue1 = this->getSmallElementValue();
4565     dValue2 = other->getSmallElementValue();
4566     fprintf(fp, "%d  double save_getSmallElementValue = clpModel->getSmallElementValue();\n", dValue1 == dValue2 ? 2 : 1);
4567     fprintf(fp, "%d  clpModel->setSmallElementValue(%g);\n", dValue1 == dValue2 ? 4 : 3, dValue1);
4568     fprintf(fp, "%d  clpModel->setSmallElementValue(save_getSmallElementValue);\n", dValue1 == dValue2 ? 7 : 6);
4569     iValue1 = this->logLevel();
4570     iValue2 = other->logLevel();
4571     fprintf(fp, "%d  int save_logLevel = clpModel->logLevel();\n", iValue1 == iValue2 ? 2 : 1);
4572     fprintf(fp, "%d  clpModel->setLogLevel(%d);\n", iValue1 == iValue2 ? 4 : 3, iValue1);
4573     fprintf(fp, "%d  clpModel->setLogLevel(save_logLevel);\n", iValue1 == iValue2 ? 7 : 6);
4574}
Note: See TracBrowser for help on using the repository browser.