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