1 /* $Id: CoinPostsolveMatrix.cpp 2083 2019-01-06 19:38:09Z unxusr $ */
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 <stdio.h>
7
8 #include <cassert>
9 #include <iostream>
10
11 #include "CoinHelperFunctions.hpp"
12 #include "CoinPresolveMatrix.hpp"
13
14 #if PRESOLVE_DEBUG || PRESOLVE_CONSISTENCY
15 #include "CoinPresolvePsdebug.hpp"
16 #endif
17
18 /*! \file
19
20 This file contains methods for CoinPostsolveMatrix, the object used during
21 postsolve transformations.
22 */
23
24 /*
25 Constructor and destructor for CoinPostsolveMatrix.
26 */
27
28 /*
29 Default constructor
30
31 Postpone allocation of space until we actually load the object.
32 */
33
CoinPostsolveMatrix(int ncols_alloc,int nrows_alloc,CoinBigIndex nelems_alloc)34 CoinPostsolveMatrix::CoinPostsolveMatrix(int ncols_alloc, int nrows_alloc, CoinBigIndex nelems_alloc)
35
36 : CoinPrePostsolveMatrix(ncols_alloc, nrows_alloc, nelems_alloc)
37 , free_list_(0)
38 , maxlink_(nelems_alloc)
39 , link_(0)
40 , cdone_(0)
41 , rdone_(0)
42
43 { /* nothing to do here */
44
45 return;
46 }
47
48 /*
49 Destructor
50 */
51
~CoinPostsolveMatrix()52 CoinPostsolveMatrix::~CoinPostsolveMatrix()
53
54 {
55 delete[] link_;
56
57 delete[] cdone_;
58 delete[] rdone_;
59
60 return;
61 }
62
63 /*
64 This routine loads a CoinPostsolveMatrix object from a CoinPresolveMatrix
65 object. The CoinPresolveMatrix object will be stripped, its components
66 transferred to the CoinPostsolveMatrix object, and the empty shell of the
67 CoinPresolveObject will be destroyed.
68
69 The routine expects an empty CoinPostsolveMatrix object, and will leak
70 any memory already allocated.
71 */
72
assignPresolveToPostsolve(CoinPresolveMatrix * & preObj)73 void CoinPostsolveMatrix::assignPresolveToPostsolve(CoinPresolveMatrix *&preObj)
74
75 {
76 /*
77 Start with simple data --- allocated and current size.
78 */
79 ncols0_ = preObj->ncols0_;
80 nrows0_ = preObj->nrows0_;
81 nelems0_ = preObj->nelems0_;
82 bulk0_ = preObj->bulk0_;
83
84 ncols_ = preObj->ncols_;
85 nrows_ = preObj->nrows_;
86 nelems_ = preObj->nelems_;
87 /*
88 Now bring over the column-major matrix and other problem data.
89 */
90 mcstrt_ = preObj->mcstrt_;
91 preObj->mcstrt_ = 0;
92 hincol_ = preObj->hincol_;
93 preObj->hincol_ = 0;
94 hrow_ = preObj->hrow_;
95 preObj->hrow_ = 0;
96 colels_ = preObj->colels_;
97 preObj->colels_ = 0;
98
99 cost_ = preObj->cost_;
100 preObj->cost_ = 0;
101 originalOffset_ = preObj->originalOffset_;
102 clo_ = preObj->clo_;
103 preObj->clo_ = 0;
104 cup_ = preObj->cup_;
105 preObj->cup_ = 0;
106 rlo_ = preObj->rlo_;
107 preObj->rlo_ = 0;
108 rup_ = preObj->rup_;
109 preObj->rup_ = 0;
110
111 originalColumn_ = preObj->originalColumn_;
112 preObj->originalColumn_ = 0;
113 originalRow_ = preObj->originalRow_;
114 preObj->originalRow_ = 0;
115
116 ztolzb_ = preObj->ztolzb_;
117 ztoldj_ = preObj->ztoldj_;
118 maxmin_ = preObj->maxmin_;
119 /*
120 Now the problem solution. Often this will be empty, but that's not a problem.
121 */
122 sol_ = preObj->sol_;
123 preObj->sol_ = 0;
124 rowduals_ = preObj->rowduals_;
125 preObj->rowduals_ = 0;
126 acts_ = preObj->acts_;
127 preObj->acts_ = 0;
128 rcosts_ = preObj->rcosts_;
129 preObj->rcosts_ = 0;
130 colstat_ = preObj->colstat_;
131 preObj->colstat_ = 0;
132 rowstat_ = preObj->rowstat_;
133 preObj->rowstat_ = 0;
134 /*
135 The CoinPostsolveMatrix comes with messages and a handler, but replace them
136 with the versions from the CoinPresolveObject, in case they've been
137 customized. Let preObj believe it's no longer responsible for the handler.
138 */
139 if (defaultHandler_ == true)
140 delete handler_;
141 handler_ = preObj->handler_;
142 preObj->defaultHandler_ = false;
143 messages_ = preObj->messages_;
144 /*
145 Initialise the postsolve portions of this object. Which amounts to setting
146 up the thread links to match the column-major matrix representation. This
147 would be trivial except that the presolve matrix is loosely packed. We can
148 either compress the matrix, or record the existing free space pattern. Bet
149 that the latter is more efficient. Remember that mcstrt_[ncols_] actually
150 points to the end of the bulk storage area, so when we process the last
151 column in the bulk storage area, we'll add the free space block at the end
152 of bulk storage to the free list.
153
154 We need to allow for a 0x0 matrix here --- a pathological case, but it slips
155 in when (for example) confirming a solution in an ILP code.
156 */
157 free_list_ = NO_LINK;
158 maxlink_ = bulk0_;
159 link_ = new CoinBigIndex[maxlink_];
160
161 if (ncols_ > 0) {
162 CoinBigIndex minkcs = -1;
163 for (int j = 0; j < ncols_; j++) {
164 CoinBigIndex kcs = mcstrt_[j];
165 int lenj = hincol_[j];
166 assert(lenj > 0);
167 CoinBigIndex kce = kcs + lenj - 1;
168 CoinBigIndex k;
169
170 for (k = kcs; k < kce; k++) {
171 link_[k] = k + 1;
172 }
173 link_[k++] = NO_LINK;
174
175 if (preObj->clink_[j].pre == NO_LINK) {
176 minkcs = kcs;
177 }
178 int nxtj = preObj->clink_[j].suc;
179 assert(nxtj >= 0 && nxtj <= ncols_);
180 CoinBigIndex nxtcs = mcstrt_[nxtj];
181 for (; k < nxtcs; k++) {
182 link_[k] = free_list_;
183 free_list_ = k;
184 }
185 }
186
187 assert(minkcs >= 0);
188 if (minkcs > 0) {
189 for (CoinBigIndex k = 0; k < minkcs; k++) {
190 link_[k] = free_list_;
191 free_list_ = k;
192 }
193 }
194 } else {
195 for (CoinBigIndex k = 0; k < maxlink_; k++) {
196 link_[k] = free_list_;
197 free_list_ = k;
198 }
199 }
200 /*
201 That's it, preObj can die now.
202 */
203 delete preObj;
204 preObj = 0;
205
206 #if PRESOLVE_DEBUG || PRESOLVE_CONSISTENCY
207 /*
208 These are used to track the action of postsolve transforms during debugging.
209 */
210 cdone_ = new char[ncols0_];
211 CoinFillN(cdone_, ncols_, PRESENT_IN_REDUCED);
212 CoinZeroN(cdone_ + ncols_, ncols0_ - ncols_);
213 rdone_ = new char[nrows0_];
214 CoinFillN(rdone_, nrows_, PRESENT_IN_REDUCED);
215 CoinZeroN(rdone_ + nrows_, nrows0_ - nrows_);
216 #else
217 cdone_ = 0;
218 rdone_ = 0;
219 #endif
220
221 #if PRESOLVE_CONSISTENCY
222 presolve_check_free_list(this, true);
223 presolve_check_threads(this);
224 #endif
225
226 return;
227 }
228
229 /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
230 */
231