exprAbs.cpp
Go to the documentation of this file.
1 /* $Id: exprAbs.cpp 560 2011-04-17 10:01:15Z stefan $
2  *
3  * Name: exprAbs.cpp
4  * Author: Pietro Belotti
5  * Purpose: definition of the absulute value of a function
6  *
7  * (C) Carnegie-Mellon University, 2006-10.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include "CouenneExprAbs.hpp"
12 #include "CouenneExprClone.hpp"
13 #include "CouenneExprMin.hpp"
14 #include "CouenneExprMax.hpp"
15 #include "CouenneExprOpp.hpp"
16 
17 #include "CouenneProblem.hpp"
18 
19 #include "CoinHelperFunctions.hpp"
20 #include "CoinFinite.hpp"
21 
22 using namespace Couenne;
23 
25 
27 
28  // get bounds of the argument
29  expression *lba, *uba;
30 
31  argument_ -> getBounds (lba, uba);
32 
33  // lower bound = max (0, lb, -ub)
34 
35  expression **all = new expression * [6];
36  all [0] = new exprConst (0.); all [1] = new exprConst (0.);
37  all [2] = new exprOpp (uba); all [3] = new exprOpp (new exprClone (uba));
38  all [4] = lba; all [5] = new exprClone (lba);
39 
40  lb = new exprMax (all, 6);
41 
42  // upper bound = max (|lb|, |ub|)
43 
44  ub = new exprMax (new exprAbs (new exprClone (lba)),
45  new exprAbs (new exprClone (uba)));
46 }
47 
48 
50 
52 
53  // get bounds of the argument
54  CouNumber lba, uba;
55 
56  argument_ -> getBounds (lba, uba);
57 
58  if (lba > 0) {
59  lb = lba;
60  ub = uba;
61  } else if (uba < 0) {
62  lb = -uba;
63  ub = -lba;
64  } else {
65  lb = 0.;
66  ub = CoinMax (-lba, uba);
67  }
68 }
69 
70 
72 
74 
75  expression **arglist = new expression * [4];
76  expression *diffarg = argument_ -> differentiate (index);
77 
78  arglist [0] = new exprConst (0.);
79  arglist [1] = new exprClone (diffarg);
80  arglist [2] = new exprOpp (new exprClone (argument_));
81  arglist [3] = new exprOpp (diffarg);
82 
83  return new exprMin (arglist, 4);
84 }
85 
86 
89 
90 bool exprAbs::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum auxSign sign) {
91 
92  int index = argument_ -> Index ();
93 
94  CouNumber *xl = l + index, wl = sign == expression::AUX_GEQ ? -COIN_DBL_MAX : l [wind],
95  *xu = u + index, wu = sign == expression::AUX_LEQ ? COIN_DBL_MAX : u [wind];
96 
97  // for w >= b > 0, we can only improve xlb if it is at least b
98  // xub most -b
99 
100  bool tighter = false;
101 
102  if (wl > 0) {
103  if (*xl > 0) {
104  if (updateBound (-1, xl, argument_ -> isInteger () ? ceil (wl - COUENNE_EPS) : wl)) {
105  tighter = true;
106  chg [index].setLower(t_chg_bounds::CHANGED);
107  }
108  }
109  else if (*xu < 0) {
110  if (updateBound (+1, xu, argument_ -> isInteger () ? floor (-wl + COUENNE_EPS) : -wl)) {
111  tighter = true;
112  chg [index].setUpper(t_chg_bounds::CHANGED);
113  }
114  }
115  }
116 
117  // w <= u (if u < 0 the problem is infeasible)
118 
119  if (wu < COUENNE_INFINITY) {
120  if (updateBound (-1, xl, argument_ -> isInteger () ? ceil (-wu - COUENNE_EPS) : -wu)) {
121  tighter = true;
122  chg [index].setLower(t_chg_bounds::CHANGED);
123  }
124  if (updateBound (+1, xu, argument_ -> isInteger () ? floor (wu + COUENNE_EPS) : wu)) {
125  tighter = true;
126  chg [index].setUpper(t_chg_bounds::CHANGED);
127  }
128  }
129 
130  return tighter;
131 }
132 
133 
136  CouNumber& left, CouNumber& right) const
137 {
138  CouNumber valdep = (*vardep)();
139  CouNumber curr = (*varind)();
140 
141  if (valdep < 0.) { // no way to restore feasibility, set infinite interval
142  left = -COUENNE_INFINITY;
143  right = COUENNE_INFINITY;
144  }
145  else if (curr < -valdep) { // hence curr negative and behind left part of |x|
146  left = curr;
147  right = -valdep;
148  }
149  else if (curr > valdep) { // hence curr positive and after right half-line of |x|
150  left = valdep;
151  right = curr;
152  }
153  else { // between the two half-lines
154  left = -valdep;
155  right = valdep;
156  }
157 
158 }
159 
160 
163 bool exprAbs::isCuttable (CouenneProblem *problem, int index) const {
164 
165  double
166  x = problem -> X (argument_ -> Index ()),
167  y = problem -> X (index);
168 
169  return ((y <= x) || (y <= -x));
170 }
171 
172 
174 //enum convexity exprAbs::convexity () const {
175 
176 // CouNumber lb, ub;
177 // getBounds (lb, ub);
178 // return (((lb >= 0.) || (ub <= 0.)) ? AFFINE : CONVEX);
179 //}
virtual void closestFeasible(expression *varind, expression *vardep, CouNumber &left, CouNumber &right) const
closest feasible points in function in both directions
Definition: exprAbs.cpp:135
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 ...
void setLower(ChangeStatus lower)
expression * argument_
single argument taken by this expression
virtual void getBounds(expression *&, expression *&)
Get lower and upper bound of an expression (if any)
Definition: exprAbs.cpp:26
constant-type operator
bool impliedBound(int, CouNumber *, CouNumber *, t_chg_bounds *, enum auxSign=expression::AUX_EQ)
implied bound processing
Definition: exprAbs.cpp:90
expression * differentiate(int index)
differentiation
Definition: exprAbs.cpp:73
void setUpper(ChangeStatus upper)
virtual bool isCuttable(CouenneProblem *problem, int index) const
can this expression be further linearized or are we on its concave (&quot;bad&quot;) side
Definition: exprAbs.cpp:163
virtual int Index() const
Return index of variable (only valid for exprVar and exprAux)
auxSign
&quot;sign&quot; of the constraint defining an auxiliary.
Class for MINLP problems with symbolic information.
expression clone (points to another expression)
#define COUENNE_EPS
bool isInteger()
is this expression integer?
double CouNumber
main number type in Couenne
#define COUENNE_INFINITY
Expression base class.
void fint fint fint real fint real * x