exprSub.cpp
Go to the documentation of this file.
1 /* $Id: exprSub.cpp 1147 2015-05-04 14:01:51Z stefan $
2  *
3  * Name: exprSub.cpp
4  * Author: Pietro Belotti
5  * Purpose: definition of subtractions
6  *
7  * (C) Carnegie-Mellon University, 2006-10.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include "CouenneExprSub.hpp"
12 #include "CouenneExprConst.hpp"
13 #include "CouenneExprOpp.hpp"
14 #include "CouennePrecisions.hpp"
15 
16 #include "CoinFinite.hpp"
17 
18 using namespace Couenne;
19 
20 // simplify subtractions
21 
23 
25 
26  // check for (f(x) - f(x))
27  if (arglist_ [0] -> compare (*(arglist_ [1])) == 0) {
28 
29  // delete arglist_ [0]; arglist_ [0] = NULL;
30  // delete arglist_ [1]; arglist_ [1] = NULL;
31 
32  return new exprConst (0.);
33  }
34 
35  // check for other special cases
36  if ((*arglist_) -> Type () == CONST) { // expr = c1 - f2
37 
38  CouNumber c0 = (*arglist_) -> Value ();
39 
40  if (arglist_ [1] -> Type () == CONST) { // expr = c1 - c2
41 
42  CouNumber c1 = arglist_ [1] -> Value ();
43 
44  // delete arglist_ [0]; arglist_ [0] = NULL;
45  // delete arglist_ [1]; arglist_ [1] = NULL;
46 
47  return new exprConst (c0 - c1);
48  }
49  else if (fabs (c0) == 0.) { // expr = opp (f2)
50 
51  expression *ret = new exprOpp (arglist_ [1]);
52  // delete arglist_ [0];
53  arglist_ [1] = NULL;
54  return ret;
55  }
56  }
57  else // only need to check if f2 == 0
58 
59  if ((arglist_ [1] -> Type () == CONST) &&
60  (fabs (arglist_ [1] -> Value ()) < COUENNE_EPS_SIMPL)) {
61  // expr = f1 - 0 --> return f1
62 
63  expression *ret = arglist_ [0];
64  //delete arglist_ [1];
65  arglist_ [0] = NULL;
66  return ret;
67  }
68 
69  return NULL;
70 }
71 
72 
73 // differentiate product of expressions
74 
76 
77  expression **arglist = new expression * [nargs_];
78 
79  for (int i = 0; i < nargs_; i++)
80  if (arglist_ [i] -> dependsOn (index))
81  arglist [i] = arglist_ [i] -> differentiate (index);
82  else arglist [i] = new exprConst (0.);
83 
84  return new exprSub (arglist, nargs_);
85 }
86 
87 
88 // Get lower and upper bound of an expression (if any)
90 
91  expression **alsl = new expression * [2];
92  expression **alsu = new expression * [2];
93 
94  arglist_ [0] -> getBounds (alsl [0], alsu [0]);
95  arglist_ [1] -> getBounds (alsu [1], alsl [1]);
96 
97  lb = new exprSub (alsl, 2);
98  ub = new exprSub (alsu, 2);
99 }
100 
101 
102 // Get value of lower and upper bound of an expression (if any)
104 
105  CouNumber lba0, uba0, lba1, uba1;
106 
107  arglist_ [0] -> getBounds (lba0, uba0);
108  arglist_ [1] -> getBounds (lba1, uba1);
109 
110  lb = ((lba0 < -COUENNE_INFINITY) || (uba1 > COUENNE_INFINITY)) ?
112  (lba0 - uba1);
113 
114  ub = ((uba0 > COUENNE_INFINITY) || (lba1 < -COUENNE_INFINITY)) ?
116  (uba0 - lba1);
117 }
118 
119 
122 
123 bool exprSub::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum auxSign sign) {
124 
125  // caution, xi or yi might be -1
126  int xi = arglist_ [0] -> Index (),
127  yi = arglist_ [1] -> Index ();
128 
129  if ((xi == -1) && (yi == -1)) // both x and y are constant
130  return false;
131 
132  CouNumber xl, xu, yl, yu,
133  wl = sign == expression::AUX_GEQ ? -COIN_DBL_MAX : l [wind],
134  wu = sign == expression::AUX_LEQ ? COIN_DBL_MAX : u [wind];
135 
136  if (xi==-1) xl = xu = arglist_ [0] -> Value ();
137  else {xl = l [xi]; xu = u [xi];}
138 
139  if (yi==-1) yl = yu = arglist_ [1] -> Value ();
140  else {yl = l [yi]; yu = u [yi];}
141 
142  bool res = false;
143 
144  // w >= l
145 
146  bool
147  xInt = arglist_ [0] -> isInteger (),
148  yInt = arglist_ [1] -> isInteger ();
149 
150  if (wl > -COUENNE_INFINITY) {
151 
152  if ((xi>=0) && (updateBound (-1, l + xi, xInt ? ceil (yl + wl - COUENNE_EPS) : (yl + wl)))) {
153  res = true;
155  }
156 
157  if ((yi>=0) && (updateBound (+1, u + yi, yInt ? floor (xu - wl + COUENNE_EPS) : (xu - wl)))) {
158  res = true;
160  }
161  }
162 
163  // w <= u
164 
165  if (wu < COUENNE_INFINITY) {
166 
167  if ((xi>=0) && (updateBound (+1, u + xi, xInt ? floor (yu + wu + COUENNE_EPS) : (yu + wu)))) {
168  res = true;
170  }
171 
172  if ((yi>=0) && (updateBound (-1, l + yi, yInt ? ceil (xl - wu - COUENNE_EPS) : (xl - wu)))) {
173  res = true;
175  }
176  }
177 
178  return res;
179 }
virtual int dependsOn(int *ind, int n, enum dig_type type=STOP_AT_AUX)
dependence on variable set: return cardinality of subset of the set of indices in first argument whic...
Definition: expression.cpp:172
exprSub(expression **al, int n=2)
Constructor.
bool updateBound(register int sign, register CouNumber *dst, register CouNumber src)
updates maximum violation.
class opposite,
status of lower/upper bound of a variable, to be checked/modified in bound tightening ...
virtual bool isInteger()
is this expression integer?
Definition: exprOp.cpp:188
bool impliedBound(int, CouNumber *, CouNumber *, t_chg_bounds *, enum auxSign=expression::AUX_EQ)
Implied bound processing.
Definition: exprSub.cpp:123
void setLower(ChangeStatus lower)
expression * simplify()
Simplification.
Definition: exprSub.cpp:22
expression * differentiate(int index)
Differentiation.
Definition: exprSub.cpp:75
constant-type operator
void setUpper(ChangeStatus upper)
#define COUENNE_EPS_SIMPL
virtual enum nodeType Type() const
Node type.
virtual int Index() const
Return index of variable (only valid for exprVar and exprAux)
auxSign
&quot;sign&quot; of the constraint defining an auxiliary.
#define COUENNE_EPS
virtual expression * simplify()
simplification
Definition: exprOp.cpp:243
expression ** arglist_
argument list is an array of pointers to other expressions
void getBounds(expression *&, expression *&)
Get lower and upper bound of an expression (if any)
Definition: exprSub.cpp:89
double CouNumber
main number type in Couenne
int nargs_
number of arguments (cardinality of arglist)
#define COUENNE_INFINITY
Expression base class.
virtual CouNumber Value() const
value (empty)
virtual int compare(exprOp &)
compare with other generic exprOp
Definition: exprOp.cpp:71