1 /* $Id$
2  *
3  * Name:    domain.hpp
4  * Author:  Pietro Belotti
5  * Purpose: class 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 #ifndef COUENNE_DOMAIN_HPP
12 #define COUENNE_DOMAIN_HPP
13 
14 #include <stdlib.h>
15 #include <stack>
16 
17 #include "CouenneTypes.hpp"
18 
19 namespace Osi {
20 
21   class OsiSolverInterface;
22   class OsiCuts;
23 }
24 
25 
26 namespace Couenne {
27 
28 /// Define a point in the solution space and the bounds around it.
29 
30 class DomainPoint {
31 
32   friend class Domain;
33 
34 protected:
35 
36   int dimension_; ///< dimension of point
37 
38   CouNumber *x_;  ///< current value of variables
39   CouNumber *lb_; ///< lower bound
40   CouNumber *ub_; ///< upper bound
41 
42   bool copied_;   ///< true if data has been copied (so we own it, and
43 		  ///  have to delete it upon destruction)
44 
45   bool isNlp_;    ///< true if this point comes from an NLP solver
46 		  ///  (and is thus nlp feasible)
47 public:
48 
49   /// constructor
50   DomainPoint (int dim,
51 	       CouNumber *x,
52 	       CouNumber *lb,
53 	       CouNumber *ub,
54 	       bool copy = true);
55 
56   /// constructor
57   DomainPoint (int dim = 0,
58 	       const CouNumber *x   = NULL,
59 	       const CouNumber *lb  = NULL,
60 	       const CouNumber *ub  = NULL,
61 	       bool copy = true);
62 
63   /// destructor
~DomainPoint()64   ~DomainPoint () {
65     if (copied_) {
66       if (x_)  free (x_);
67       if (lb_) free (lb_);
68       if (ub_) free (ub_);
69     }
70   }
71 
72   /// copy constructor
73   DomainPoint (const DomainPoint &src);
74 
75   /// resize domain point (for extending into higher space)
76   void resize (int newdim);
77 
78   /// return current size
size() const79   int size () const {return dimension_;}
80 
81   /// return dimension_
Dimension()82   inline int Dimension () {return dimension_;}
83 
x(register int index)84   inline CouNumber &x  (register int index) {return x_  [index];} ///< return current variable
lb(register int index)85   inline CouNumber &lb (register int index) {return lb_ [index];} ///< return current lower bound
ub(register int index)86   inline CouNumber &ub (register int index) {return ub_ [index];} ///< return current upper bound
87 
x()88   inline CouNumber *x  () {return x_ ;} ///< return current variable vector
lb()89   inline CouNumber *lb () {return lb_;} ///< return current lower bound vector
ub()90   inline CouNumber *ub () {return ub_;} ///< return current upper bound vector
91 
92   /// assignment operator
93   DomainPoint &operator= (const DomainPoint &src);
94 
95   /// true if this point is the nlp solution
isNlp()96   bool &isNlp ()
97   {return isNlp_;}
98 };
99 
100 
101 /// Define a dynamic point+bounds, with a way to save and restore
102 /// previous points+bounds through a LIFO structure
103 
104 class Domain {
105 
106 protected:
107 
108   DomainPoint *point_;                  ///< current point
109   std::stack <DomainPoint *> domStack_; ///< stack of saved points
110 
111 public:
112 
113   /// basic constructor
Domain()114   Domain (): point_ (NULL) {}
115 
116   /// copy constructor
Domain(const Domain & src)117   Domain (const Domain &src) {
118     point_ = new DomainPoint (*(src.point_));
119     // TODO -- not important, discard previous points when copying problem
120     /*for (std::stack <DomainPoint *>::iterator i = src.domStack_.begin ();
121 	 i != src.domStack_.end (); ++i)
122 	 domStack_.push (new DomainPoint (**i));*/
123   }
124 
125   /// destructor
126   ~Domain ();
127 
128   /// save current point and start using another
129   void push (int dim,
130 	     CouNumber *x,
131 	     CouNumber *lb,
132 	     CouNumber *ub,
133 	     bool copy = true);
134 
135   /// save current point and start using another
136   void push (int dim,
137 	     const CouNumber *x,
138 	     const CouNumber *lb,
139 	     const CouNumber *ub,
140 	     bool copy = true);
141 
142   /// save current point and start using another -- retrieve
143   /// information from solver interface and from previous column cuts
144   void push (const OsiSolverInterface *si,
145 	     OsiCuts *cs = NULL,
146 	     bool copy = true);
147 
148   /// save current point and start using another
149   void push (const DomainPoint &dp, bool copy = true);
150 
151   /// restore previous point
152   void pop ();
153 
current()154   inline DomainPoint *current ()   {return point_;}                          ///< return current point
155 
x(register int index)156   inline CouNumber &x  (register int index) {return point_ -> x  (index);}   ///< current variable
lb(register int index)157   inline CouNumber &lb (register int index) {return point_ -> lb (index);}   ///< current lower bound
ub(register int index)158   inline CouNumber &ub (register int index) {return point_ -> ub (index);}   ///< current upper bound
159 
x()160   inline CouNumber *x  () {return point_ -> x  ();}   ///< return current variable vector
lb()161   inline CouNumber *lb () {return point_ -> lb ();}   ///< return current lower bound vector
ub()162   inline CouNumber *ub () {return point_ -> ub ();}   ///< return current upper bound vector
163 };
164 
165 }
166 
167 #endif
168