1/* $Id: CoinSnapshot.cpp 1448 2011-06-19 15:34:41Z stefan $ */
2// Copyright (C) 2005, 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
7#include "CoinUtilsConfig.h"
8#include "CoinHelperFunctions.hpp"
9#include "CoinSnapshot.hpp"
10#include "CoinPackedMatrix.hpp"
11#include "CoinFinite.hpp"
12
13//#############################################################################
14// Constructors / Destructor / Assignment
15//#############################################################################
16
17//-------------------------------------------------------------------
18// Default Constructor
19//-------------------------------------------------------------------
20CoinSnapshot::CoinSnapshot ()
21{
22 gutsOfDestructor(13);
23}
24
25//-------------------------------------------------------------------
26// Copy constructor
27//-------------------------------------------------------------------
28CoinSnapshot::CoinSnapshot (const CoinSnapshot & rhs)
29{
30 gutsOfDestructor(13);
31 gutsOfCopy(rhs);
32}
33
34//-------------------------------------------------------------------
35// Destructor
36//-------------------------------------------------------------------
37CoinSnapshot::~CoinSnapshot ()
38{
39 gutsOfDestructor(15);
40}
41
42//----------------------------------------------------------------
43// Assignment operator
44//-------------------------------------------------------------------
45CoinSnapshot &
46CoinSnapshot::operator=(const CoinSnapshot& rhs)
47{
48 if (this != &rhs) {
49 gutsOfDestructor(15);
50 gutsOfCopy(rhs);
51 }
52 return *this;
53}
54// Does main work of destructor
55void
56CoinSnapshot::gutsOfDestructor(int type)
57{
58 if ((type&2)!=0) {
59 if (owned_.colLower)
60 delete [] colLower_;
61 if (owned_.colUpper)
62 delete [] colUpper_;
63 if (owned_.rowLower)
64 delete [] rowLower_;
65 if (owned_.rowUpper)
66 delete [] rowUpper_;
67 if (owned_.rightHandSide)
68 delete [] rightHandSide_;
69 if (owned_.objCoefficients)
70 delete [] objCoefficients_;
71 if (owned_.colType)
72 delete [] colType_;
73 if (owned_.matrixByRow)
74 delete matrixByRow_;
75 if (owned_.matrixByCol)
76 delete matrixByCol_;
77 if (owned_.originalMatrixByRow)
78 delete originalMatrixByRow_;
79 if (owned_.originalMatrixByCol)
80 delete originalMatrixByCol_;
81 if (owned_.colSolution)
82 delete [] colSolution_;
83 if (owned_.rowPrice)
84 delete [] rowPrice_;
85 if (owned_.reducedCost)
86 delete [] reducedCost_;
87 if (owned_.rowActivity)
88 delete [] rowActivity_;
89 if (owned_.doNotSeparateThis)
90 delete [] doNotSeparateThis_;
91 }
92 if ((type&4)!=0) {
93 objSense_ = 1.0;
94 infinity_ = COIN_DBL_MAX;
95 dualTolerance_ = 1.0e-7;
96 primalTolerance_ = 1.0e-7;
97 integerTolerance_ = 1.0e-7;
98 }
99 if ((type&8)!=0) {
100 objValue_ = COIN_DBL_MAX;
101 objOffset_ = 0.0;
102 integerUpperBound_ = COIN_DBL_MAX;
103 integerLowerBound_ = -COIN_DBL_MAX;
104 }
105 if ((type&1)!=0) {
106 colLower_ = NULL;
107 colUpper_ = NULL;
108 rowLower_ = NULL;
109 rowUpper_ = NULL;
110 rightHandSide_ = NULL;
111 objCoefficients_ = NULL;
112 colType_ = NULL;
113 matrixByRow_ = NULL;
114 matrixByCol_ = NULL;
115 originalMatrixByRow_ = NULL;
116 originalMatrixByCol_ = NULL;
117 colSolution_ = NULL;
118 rowPrice_ = NULL;
119 reducedCost_ = NULL;
120 rowActivity_ = NULL;
121 doNotSeparateThis_ = NULL;
122 numCols_ = 0;
123 numRows_ = 0;
124 numElements_ = 0;
125 numIntegers_ = 0;
126 // say nothing owned
127 memset(&owned_,0,sizeof(owned_));
128 }
129}
130// Does main work of copy
131void
132CoinSnapshot::gutsOfCopy(const CoinSnapshot & rhs)
133{
134 objSense_ = rhs.objSense_;
135 infinity_ = rhs.infinity_;
136 objValue_ = rhs.objValue_;
137 objOffset_ = rhs.objOffset_;
138 dualTolerance_ = rhs.dualTolerance_;
139 primalTolerance_ = rhs.primalTolerance_;
140 integerTolerance_ = rhs.integerTolerance_;
141 integerUpperBound_ = rhs.integerUpperBound_;
142 integerLowerBound_ = rhs.integerLowerBound_;
143 numCols_ = rhs.numCols_;
144 numRows_ = rhs.numRows_;
145 numElements_ = rhs.numElements_;
146 numIntegers_ = rhs.numIntegers_;
147 owned_ = rhs.owned_;
148 if (owned_.colLower)
149 colLower_ = CoinCopyOfArray(rhs.colLower_,numCols_);
150 else
151 colLower_ = rhs.colLower_;
152 if (owned_.colUpper)
153 colUpper_ = CoinCopyOfArray(rhs.colUpper_,numCols_);
154 else
155 colUpper_ = rhs.colUpper_;
156 if (owned_.rowLower)
157 rowLower_ = CoinCopyOfArray(rhs.rowLower_,numRows_);
158 else
159 rowLower_ = rhs.rowLower_;
160 if (owned_.rowUpper)
161 rowUpper_ = CoinCopyOfArray(rhs.rowUpper_,numRows_);
162 else
163 rowUpper_ = rhs.rowUpper_;
164 if (owned_.rightHandSide)
165 rightHandSide_ = CoinCopyOfArray(rhs.rightHandSide_,numRows_);
166 else
167 rightHandSide_ = rhs.rightHandSide_;
168 if (owned_.objCoefficients)
169 objCoefficients_ = CoinCopyOfArray(rhs.objCoefficients_,numCols_);
170 else
171 objCoefficients_ = rhs.objCoefficients_;
172 if (owned_.colType)
173 colType_ = CoinCopyOfArray(rhs.colType_,numCols_);
174 else
175 colType_ = rhs.colType_;
176 if (owned_.colSolution)
177 colSolution_ = CoinCopyOfArray(rhs.colSolution_,numCols_);
178 else
179 colSolution_ = rhs.colSolution_;
180 if (owned_.rowPrice)
181 rowPrice_ = CoinCopyOfArray(rhs.rowPrice_,numRows_);
182 else
183 rowPrice_ = rhs.rowPrice_;
184 if (owned_.reducedCost)
185 reducedCost_ = CoinCopyOfArray(rhs.reducedCost_,numCols_);
186 else
187 reducedCost_ = rhs.reducedCost_;
188 if (owned_.rowActivity)
189 rowActivity_ = CoinCopyOfArray(rhs.rowActivity_,numRows_);
190 else
191 rowActivity_ = rhs.rowActivity_;
192 if (owned_.doNotSeparateThis)
193 doNotSeparateThis_ = CoinCopyOfArray(rhs.doNotSeparateThis_,numCols_);
194 else
195 doNotSeparateThis_ = rhs.doNotSeparateThis_;
196 if (owned_.matrixByRow)
197 matrixByRow_ = new CoinPackedMatrix(*rhs.matrixByRow_);
198 else
199 matrixByRow_ = rhs.matrixByRow_;
200 if (owned_.matrixByCol)
201 matrixByCol_ = new CoinPackedMatrix(*rhs.matrixByCol_);
202 else
203 matrixByCol_ = rhs.matrixByCol_;
204 if (owned_.originalMatrixByRow)
205 originalMatrixByRow_ = new CoinPackedMatrix(*rhs.originalMatrixByRow_);
206 else
207 originalMatrixByRow_ = rhs.originalMatrixByRow_;
208 if (owned_.originalMatrixByCol)
209 originalMatrixByCol_ = new CoinPackedMatrix(*rhs.originalMatrixByCol_);
210 else
211 originalMatrixByCol_ = rhs.originalMatrixByCol_;
212}
213/* Load in an problem by copying the arguments (the constraints on the
214 rows are given by lower and upper bounds). If a pointer is NULL then the
215 following values are the default:
216 <ul>
217 <li> <code>colub</code>: all columns have upper bound infinity
218 <li> <code>collb</code>: all columns have lower bound 0
219 <li> <code>rowub</code>: all rows have upper bound infinity
220 <li> <code>rowlb</code>: all rows have lower bound -infinity
221 <li> <code>obj</code>: all variables have 0 objective coefficient
222 </ul>
223*/
224void
225CoinSnapshot::loadProblem(const CoinPackedMatrix& matrix,
226 const double* collb, const double* colub,
227 const double* obj,
228 const double* rowlb, const double* rowub,
229 bool makeRowCopy)
230{
231 // Keep scalars (apart from objective value etc)
232 gutsOfDestructor(3+8);
233 numRows_ = matrix.getNumRows();
234 numCols_ = matrix.getNumCols();
235 numElements_ = matrix.getNumElements();
236 owned_.matrixByCol = 1;
237 matrixByCol_ = new CoinPackedMatrix(matrix);
238 if (makeRowCopy) {
239 owned_.matrixByRow = 1;
240 CoinPackedMatrix * matrixByRow = new CoinPackedMatrix(matrix);
241 matrixByRow->reverseOrdering();
242 matrixByRow_ = matrixByRow;
243 }
244 colLower_ = CoinCopyOfArray(collb,numCols_,0.0);
245 colUpper_ = CoinCopyOfArray(colub,numCols_,infinity_);
246 objCoefficients_ = CoinCopyOfArray(obj,numCols_,0.0);
247 rowLower_ = CoinCopyOfArray(rowlb,numRows_,-infinity_);
248 rowUpper_ = CoinCopyOfArray(rowub,numRows_,infinity_);
249 // do rhs as well
250 createRightHandSide();
251}
252
253// Set pointer to array[getNumCols()] of column lower bounds
254void
255CoinSnapshot::setColLower(const double * array, bool copyIn)
256{
257 if (owned_.colLower)
258 delete [] colLower_;
259 if (copyIn) {
260 owned_.colLower=1;
261 colLower_ = CoinCopyOfArray(array,numCols_);
262 } else {
263 owned_.colLower=0;
264 colLower_ = array;
265 }
266}
267// Set pointer to array[getNumCols()] of column upper bounds
268void
269CoinSnapshot::setColUpper(const double * array, bool copyIn)
270{
271 if (owned_.colUpper)
272 delete [] colUpper_;
273 if (copyIn) {
274 owned_.colUpper=1;
275 colUpper_ = CoinCopyOfArray(array,numCols_);
276 } else {
277 owned_.colUpper=0;
278 colUpper_ = array;
279 }
280}
281// Set pointer to array[getNumRows()] of row lower bounds
282void
283CoinSnapshot::setRowLower(const double * array, bool copyIn)
284{
285 if (owned_.rowLower)
286 delete [] rowLower_;
287 if (copyIn) {
288 owned_.rowLower=1;
289 rowLower_ = CoinCopyOfArray(array,numRows_);
290 } else {
291 owned_.rowLower=0;
292 rowLower_ = array;
293 }
294}
295// Set pointer to array[getNumRows()] of row upper bounds
296void
297CoinSnapshot::setRowUpper(const double * array, bool copyIn)
298{
299 if (owned_.rowUpper)
300 delete [] rowUpper_;
301 if (copyIn) {
302 owned_.rowUpper=1;
303 rowUpper_ = CoinCopyOfArray(array,numRows_);
304 } else {
305 owned_.rowUpper=0;
306 rowUpper_ = array;
307 }
308}
309/* Set pointer to array[getNumRows()] of rhs side values
310 This gives same results as OsiSolverInterface for useful cases
311 If getRowUpper()[i] != infinity then
312 getRightHandSide()[i] == getRowUpper()[i]
313 else
314 getRightHandSide()[i] == getRowLower()[i]
315*/
316void
317CoinSnapshot::setRightHandSide(const double * array, bool copyIn)
318{
319 if (owned_.rightHandSide)
320 delete [] rightHandSide_;
321 if (copyIn) {
322 owned_.rightHandSide=1;
323 rightHandSide_ = CoinCopyOfArray(array,numRows_);
324 } else {
325 owned_.rightHandSide=0;
326 rightHandSide_ = array;
327 }
328}
329/* Create array[getNumRows()] of rhs side values
330 This gives same results as OsiSolverInterface for useful cases
331 If getRowUpper()[i] != infinity then
332 getRightHandSide()[i] == getRowUpper()[i]
333 else
334 getRightHandSide()[i] == getRowLower()[i]
335*/
336void
337CoinSnapshot::createRightHandSide()
338{
339 if (owned_.rightHandSide)
340 delete [] rightHandSide_;
341 owned_.rightHandSide=1;
342 assert (rowUpper_);
343 assert (rowLower_);
344 double * rightHandSide = CoinCopyOfArray(rowUpper_,numRows_);
345 for (int i=0;i<numRows_;i++) {
346 if (rightHandSide[i]==infinity_)
347 rightHandSide[i] = rowLower_[i];
348 }
349 rightHandSide_ = rightHandSide;
350}
351// Set pointer to array[getNumCols()] of objective function coefficients
352void
353CoinSnapshot::setObjCoefficients(const double * array, bool copyIn)
354{
355 if (owned_.objCoefficients)
356 delete [] objCoefficients_;
357 if (copyIn) {
358 owned_.objCoefficients=1;
359 objCoefficients_ = CoinCopyOfArray(array,numCols_);
360 } else {
361 owned_.objCoefficients=0;
362 objCoefficients_ = array;
363 }
364}
365// Set colType array ('B', 'I', or 'C' for Binary, Integer and Continuous)
366void
367CoinSnapshot::setColType(const char *array, bool copyIn)
368{
369 if (owned_.colType)
370 delete [] colType_;
371 if (copyIn) {
372 owned_.colType=1;
373 colType_ = CoinCopyOfArray(array,numCols_);
374 } else {
375 owned_.colType=0;
376 colType_ = array;
377 }
378 int i;
379 numIntegers_=0;
380 for (i=0;i<numCols_;i++) {
381 if (colType_[i]=='B'||colType_[i]=='I')
382 numIntegers_++;
383 }
384}
385// Set pointer to row-wise copy of current matrix
386void
387CoinSnapshot::setMatrixByRow(const CoinPackedMatrix * matrix, bool copyIn)
388{
389 if (owned_.matrixByRow)
390 delete matrixByRow_;
391 if (copyIn) {
392 owned_.matrixByRow=1;
393 matrixByRow_ = new CoinPackedMatrix(*matrix);
394 } else {
395 owned_.matrixByRow=0;
396 matrixByRow_ = matrix;
397 }
398 assert (matrixByRow_->getNumCols()==numCols_);
399 assert (matrixByRow_->getNumRows()==numRows_);
400}
401// Create row-wise copy from MatrixByCol
402void
403CoinSnapshot::createMatrixByRow()
404{
405 if (owned_.matrixByRow)
406 delete matrixByRow_;
407 assert (matrixByCol_);
408 owned_.matrixByRow = 1;
409 CoinPackedMatrix * matrixByRow = new CoinPackedMatrix(*matrixByCol_);
410 matrixByRow->reverseOrdering();
411 matrixByRow_ = matrixByRow;
412}
413// Set pointer to column-wise copy of current matrix
414void
415CoinSnapshot::setMatrixByCol(const CoinPackedMatrix * matrix, bool copyIn)
416{
417 if (owned_.matrixByCol)
418 delete matrixByCol_;
419 if (copyIn) {
420 owned_.matrixByCol=1;
421 matrixByCol_ = new CoinPackedMatrix(*matrix);
422 } else {
423 owned_.matrixByCol=0;
424 matrixByCol_ = matrix;
425 }
426 assert (matrixByCol_->getNumCols()==numCols_);
427 assert (matrixByCol_->getNumRows()==numRows_);
428}
429// Set pointer to row-wise copy of "original" matrix
430void
431CoinSnapshot::setOriginalMatrixByRow(const CoinPackedMatrix * matrix, bool copyIn)
432{
433 if (owned_.originalMatrixByRow)
434 delete originalMatrixByRow_;
435 if (copyIn) {
436 owned_.originalMatrixByRow=1;
437 originalMatrixByRow_ = new CoinPackedMatrix(*matrix);
438 } else {
439 owned_.originalMatrixByRow=0;
440 originalMatrixByRow_ = matrix;
441 }
442 assert (matrixByRow_->getNumCols()==numCols_);
443}
444// Set pointer to column-wise copy of "original" matrix
445void
446CoinSnapshot::setOriginalMatrixByCol(const CoinPackedMatrix * matrix, bool copyIn)
447{
448 if (owned_.originalMatrixByCol)
449 delete originalMatrixByCol_;
450 if (copyIn) {
451 owned_.originalMatrixByCol=1;
452 originalMatrixByCol_ = new CoinPackedMatrix(*matrix);
453 } else {
454 owned_.originalMatrixByCol=0;
455 originalMatrixByCol_ = matrix;
456 }
457 assert (matrixByCol_->getNumCols()==numCols_);
458}
459// Set pointer to array[getNumCols()] of primal variable values
460void
461CoinSnapshot::setColSolution(const double * array, bool copyIn)
462{
463 if (owned_.colSolution)
464 delete [] colSolution_;
465 if (copyIn) {
466 owned_.colSolution=1;
467 colSolution_ = CoinCopyOfArray(array,numCols_);
468 } else {
469 owned_.colSolution=0;
470 colSolution_ = array;
471 }
472}
473// Set pointer to array[getNumRows()] of dual variable values
474void
475CoinSnapshot::setRowPrice(const double * array, bool copyIn)
476{
477 if (owned_.rowPrice)
478 delete [] rowPrice_;
479 if (copyIn) {
480 owned_.rowPrice=1;
481 rowPrice_ = CoinCopyOfArray(array,numRows_);
482 } else {
483 owned_.rowPrice=0;
484 rowPrice_ = array;
485 }
486}
487// Set a pointer to array[getNumCols()] of reduced costs
488void
489CoinSnapshot::setReducedCost(const double * array, bool copyIn)
490{
491 if (owned_.reducedCost)
492 delete [] reducedCost_;
493 if (copyIn) {
494 owned_.reducedCost=1;
495 reducedCost_ = CoinCopyOfArray(array,numCols_);
496 } else {
497 owned_.reducedCost=0;
498 reducedCost_ = array;
499 }
500}
501// Set pointer to array[getNumRows()] of row activity levels (constraint matrix times the solution vector).
502void
503CoinSnapshot::setRowActivity(const double * array, bool copyIn)
504{
505 if (owned_.rowActivity)
506 delete [] rowActivity_;
507 if (copyIn) {
508 owned_.rowActivity=1;
509 rowActivity_ = CoinCopyOfArray(array,numRows_);
510 } else {
511 owned_.rowActivity=0;
512 rowActivity_ = array;
513 }
514}
515// Set pointer to array[getNumCols()] of primal variable values which should not be separated (for debug)
516void
517CoinSnapshot::setDoNotSeparateThis(const double * array, bool copyIn)
518{
519 if (owned_.doNotSeparateThis)
520 delete [] doNotSeparateThis_;
521 if (copyIn) {
522 owned_.doNotSeparateThis=1;
523 doNotSeparateThis_ = CoinCopyOfArray(array,numCols_);
524 } else {
525 owned_.doNotSeparateThis=0;
526 doNotSeparateThis_ = array;
527 }
528}
529