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

Last change on this file since 2035 was 2035, checked in by forrest, 5 years ago

fix compiler warnings and try and help with quadratic IP

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