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

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

fix some ampl stuff, add ClpSolver? and a few fixes

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