domain.cpp
Go to the documentation of this file.
1 /* $Id: domain.cpp 490 2011-01-14 16:07:12Z pbelotti $
2  *
3  * Name: domain.cpp
4  * Author: Pietro Belotti
5  * Purpose: implementation of methods of classes for point and bounding box
6  *
7  * (C) Carnegie-Mellon University, 2008-09.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include "CoinHelperFunctions.hpp"
12 #include "OsiSolverInterface.hpp"
13 #include "OsiCuts.hpp"
14 
15 #include "CouenneDomain.hpp"
16 #include "CouennePrecisions.hpp"
17 
18 // a buffer against continuous reallocs
19 #define EXTRA_STORAGE 1024
20 
21 using namespace Couenne;
22 
25  CouNumber *x,
26  CouNumber *lb,
27  CouNumber *ub,
28  bool copy):
29  dimension_ (dim),
30  x_ (x),
31  lb_ (lb),
32  ub_ (ub),
33  copied_ (copy) {
34 
35  if ((dimension_ > 0) && copied_) {
36 
37  int size = dim * sizeof (CouNumber);
38 
39  x_ = (CouNumber *) malloc (size);
40  lb_ = (CouNumber *) malloc (size);
41  ub_ = (CouNumber *) malloc (size);
42 
43  if (x) CoinCopyN (x, dim, x_); else CoinFillN (x_, dim, 0.);
44  if (lb) CoinCopyN (lb, dim, lb_); else CoinFillN (lb_, dim, -COUENNE_INFINITY);
45  if (ub) CoinCopyN (ub, dim, ub_); else CoinFillN (ub_, dim, COUENNE_INFINITY);
46  }
47 }
48 
49 
52  const CouNumber *x,
53  const CouNumber *lb,
54  const CouNumber *ub,
55  bool copy):
56  dimension_ (dim),
57  x_ (const_cast<CouNumber *>(x)),
58  lb_ (const_cast<CouNumber *>(lb)),
59  ub_ (const_cast<CouNumber *>(ub)),
60  copied_ (copy) {
61 
62  if ((dimension_ > 0) && copied_) {
63 
64  x_ = (CouNumber *) malloc (dim * sizeof (CouNumber));
65  lb_ = (CouNumber *) malloc (dim * sizeof (CouNumber));
66  ub_ = (CouNumber *) malloc (dim * sizeof (CouNumber));
67 
68  if (x) CoinCopyN (x, dim, x_); else CoinFillN (x_, dim, 0.);
69  if (lb) CoinCopyN (lb, dim, lb_); else CoinFillN (lb_, dim, -COUENNE_INFINITY);
70  if (ub) CoinCopyN (ub, dim, ub_); else CoinFillN (ub_, dim, COUENNE_INFINITY);
71  }
72 }
73 
74 
77  dimension_ (src.dimension_),
78  x_ (src.x_),
79  lb_ (src.lb_),
80  ub_ (src.ub_),
81  copied_ (src.copied_) {
82 
83  if ((dimension_ > 0) && copied_) {
84 
85  x_ = (CouNumber *) malloc (dimension_ * sizeof (CouNumber));
86  lb_ = (CouNumber *) malloc (dimension_ * sizeof (CouNumber));
87  ub_ = (CouNumber *) malloc (dimension_ * sizeof (CouNumber));
88 
89  CoinCopyN (src.x_, dimension_, x_);
90  CoinCopyN (src.lb_, dimension_, lb_);
91  CoinCopyN (src.ub_, dimension_, ub_);
92  }
93 }
94 
95 
97 void DomainPoint::resize (int newdim) {
98 
99  if (newdim == dimension_) return;
100 
101  assert (copied_); // cannot resize domain point as it was not copied
102 
103  if (newdim==0) { // clear
104 
105  free (x_); x_ = NULL;
106  free (lb_); lb_ = NULL;
107  free (ub_); ub_ = NULL;
108 
109  dimension_ = newdim;
110 
111  } else if (newdim < dimension_) { // resize exactly
112 
113  x_ = (CouNumber *) realloc (x_, newdim * sizeof (CouNumber));
114  lb_ = (CouNumber *) realloc (lb_, newdim * sizeof (CouNumber));
115  ub_ = (CouNumber *) realloc (ub_, newdim * sizeof (CouNumber));
116 
117  dimension_ = newdim;
118 
119  } else if (newdim > dimension_) { // expand and leave some extra space
120 
121  newdim += EXTRA_STORAGE;
122 
123  x_ = (CouNumber *) realloc (x_, newdim * sizeof (CouNumber));
124  lb_ = (CouNumber *) realloc (lb_, newdim * sizeof (CouNumber));
125  ub_ = (CouNumber *) realloc (ub_, newdim * sizeof (CouNumber));
126 
127  dimension_ = newdim;
128  }
129 }
130 
131 
134 
135  copied_ = src.copied_;
136 
137  if (src.dimension_ != dimension_) {
138  if (x_) free (x_); x_ = (CouNumber *) malloc (src.dimension_ * sizeof (CouNumber));
139  if (lb_) free (lb_); lb_ = (CouNumber *) malloc (src.dimension_ * sizeof (CouNumber));
140  if (ub_) free (ub_); ub_ = (CouNumber *) malloc (src.dimension_ * sizeof (CouNumber));
141  dimension_ = src.dimension_;
142  }
143 
144  CoinCopyN (src.x_, dimension_, x_);
145  CoinCopyN (src.lb_, dimension_, lb_);
146  CoinCopyN (src.ub_, dimension_, ub_);
147 
148  return *this;
149 }
150 
151 
154 
155  if (point_)
156  delete point_;
157 
158  while (!(domStack_.empty ())) {
159  delete domStack_.top ();
160  domStack_.pop ();
161  }
162 }
163 
164 
166 void Domain::push (int dim, CouNumber *x, CouNumber *lb, CouNumber *ub, bool copy) {
167 
168  if (!x) x = point_ -> x ();
169  if (!lb) lb = point_ -> lb ();
170  if (!ub) ub = point_ -> ub ();
171 
172  if (point_)
173  domStack_.push (point_);
174 
175  point_ = new DomainPoint (dim, x, lb, ub, copy);
176 }
177 
178 
180 void Domain::push (int dim,
181  const CouNumber *x,
182  const CouNumber *lb,
183  const CouNumber *ub,
184  bool copy) {
185 
186  if (point_)
187  domStack_.push (point_);
188 
189  point_ = new DomainPoint (dim, x, lb, ub, copy);
190 }
191 
192 
195 void Domain::push (const OsiSolverInterface *si,
196  OsiCuts *cs,
197  bool copy) {
198 
199  int dim = si -> getNumCols ();
200 
201  if (point_)
202  domStack_.push (point_);
203 
204  point_ = new DomainPoint (dim,
205  si -> getColSolution (),
206  si -> getColLower (),
207  si -> getColUpper (), copy);
208 
209  // copy latest tightened bounds to problem, if any ColCut is there
210 
211  if (cs)
212  for (int i = cs -> sizeColCuts (); i--;) {
213 
214  OsiColCut *cut = cs -> colCutPtr (i);
215 
216  register const CoinPackedVector
217  &lbs = cut -> lbs (),
218  &ubs = cut -> ubs ();
219 
220  register const int *indices = lbs. getIndices ();
221  register const double *elements = lbs. getElements ();
222 
223  register CouNumber
224  *lb = point_ -> lb_,
225  *ub = point_ -> ub_;
226 
227  // copy lbs
228 
229  for (register int j = lbs. getNumElements (); j--; elements++, indices++)
230  if (*elements > lb [*indices])
231  lb [*indices] = *elements;
232 
233  // copy ubs
234 
235  indices = ubs. getIndices ();
236  elements = ubs. getElements ();
237 
238  for (register int j = ubs. getNumElements (); j--; elements++, indices++)
239  if (*elements < ub [*indices])
240  ub [*indices] = *elements;
241  }
242 }
243 
244 
246 void Domain::push (const DomainPoint &dp, bool copy) {
247 
248  if (point_)
249  domStack_.push (point_);
250  point_ = new DomainPoint (dp);
251 }
252 
253 
255 void Domain::pop () {
256 
257  delete point_;
258  if (!(domStack_.empty ())) {
259  point_ = domStack_.top ();
260  domStack_.pop ();
261  }
262  else point_ = NULL;
263 }
264 
265 /*int main (int argc, char **argv) {
266 
267 CouNumber
268 x1 [] = {1,2,3},
269 l1 [] = {0,-1,-2},
270 u1 [] = {2,5,8},
271 
272 x3 [] = {14,15,16,17,18,19},
273 l3 [] = {-100,-100,-100,-100,-100,-100},
274 u3 [] = {10,10,10,10,10,10},
275 
276 x2 [] = {5001,5002,5003,5006},
277 l2 [] = {4000,3000,2000,1000},
278 u2 [] = {5000,6000,8000,6000};
279 
280 Domain dom;
281 
282 for (int i=80; i--;) {
283 dom.push (3,x1,l1,u1);printf("1: %g %g %g\n", dom.x(1),dom.x(2),dom.x(0));
284 dom.push(5,x3,l3,u3);printf("2: %g %g %g %g %g\n",dom.x(1),dom.x(2),dom.x(3),dom.x(4),dom.x(0));
285 dom.push (4,x2,l2,u2); printf ("3: %g %g %g %g\n", dom.x(1),dom.x(2),dom.x(3),dom.x(0));
286 dom.push (3,x1,l1,u1); printf ("4: %g %g %g\n", dom.x(1),dom.x(2),dom.x(0));
287 dom.push (4,x2,l2,u2); printf ("5: %g %g %g %g\n", dom.x(1),dom.x(2),dom.x(3),dom.x(0));
288 dom.push(5,x3,l3,u3);printf("6: %g %g %g %g %g\n",dom.x(1),dom.x(2),dom.x(3),dom.x(4),dom.x(0));
289 dom.pop ();
290 dom.pop ();
291 dom.pop ();
292 dom.pop ();
293 dom.pop ();
294 dom.pop ();
295 }
296 }*/
std::stack< DomainPoint * > domStack_
stack of saved points
int size() const
return current size
CouNumber * x()
return current variable vector
CouNumber * lb_
lower bound
DomainPoint(int dim, CouNumber *x, CouNumber *lb, CouNumber *ub, bool copy=true)
constructor
Definition: domain.cpp:24
CouNumber * lb()
return current lower bound vector
static char * j
Definition: OSdtoa.cpp:3622
Define a point in the solution space and the bounds around it.
bool copied_
true if data has been copied (so we own it, and have to delete it upon destruction) ...
void pop()
restore previous point
Definition: domain.cpp:255
int dimension_
dimension of point
~Domain()
destructor
Definition: domain.cpp:153
double CouNumber
main number type in Couenne
#define COUENNE_INFINITY
void push(int dim, CouNumber *x, CouNumber *lb, CouNumber *ub, bool copy=true)
save current point and start using another
Definition: domain.cpp:166
DomainPoint * point_
current point
DomainPoint & operator=(const DomainPoint &src)
assignment operator
Definition: domain.cpp:133
CouNumber * ub_
upper bound
CouNumber * ub()
return current upper bound vector
CouNumber * x_
current value of variables
#define EXTRA_STORAGE
Definition: domain.cpp:19
void resize(int newdim)
resize domain point (for extending into higher space)
Definition: domain.cpp:97
void fint fint fint real fint real * x