conv-exprMul-genCuts.cpp
Go to the documentation of this file.
1 /* $Id: conv-exprMul-genCuts.cpp 1049 2014-01-26 12:59:21Z pbelotti $
2  *
3  * Name: conv-exprMul-genCuts.cpp
4  * Author: Pietro Belotti
5  * Purpose: method to convexify multiplications
6  *
7  * (C) Carnegie-Mellon University, 2006-10.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include "CouenneCutGenerator.hpp"
12 
13 #include "CouenneTypes.hpp"
14 #include "CouenneExprMul.hpp"
15 #include "CouenneProblem.hpp"
16 #include "CouenneExprAux.hpp"
17 
18 using namespace Couenne;
19 
21 
23  OsiCuts &cs, const CouenneCutGenerator *cg,
24  t_chg_bounds *chg, int wind,
25  CouNumber lbw, CouNumber ubw) {
26 
27  expression *xe = arglist_ [0];
28  expression *ye = arglist_ [1];
29 
30  int wi = w -> Index (),
31  xi = xe -> Index (),
32  yi = ye -> Index ();
33 
34  // if expression is x*c or c*y, with c constant from the problem
35  // definition or from the branching rules, the expression is
36  // linear. Add one convexification equality constraint.
37 
38  // check if either operand is constant
39 
40  bool is0const = (xe -> Type () == CONST),
41  is1const = (ye -> Type () == CONST);
42 
43  CouNumber c0=0, c1=0;
44 
45  // is one of the two constant?
46 
47  if (is0const) c0 = xe -> Value ();
48  if (is1const) c1 = ye -> Value ();
49 
50  // compute bounds
51 
52  CouNumber xl, xu, yl, yu, wl, wu;
53 
54  xe -> getBounds (xl, xu);
55  ye -> getBounds (yl, yu);
56  w -> getBounds (wl, wu);
57 
58  if (lbw > wl) wl = lbw;
59  if (ubw < wu) wu = ubw;
60 
61  // check if either operator got constant because of the branching
62  // rules:
63 
64  bool i0s, i1s = i0s = false;
65 
66  // TODO: Fix this!
67 
68  // x...
69 
70  if (!is0const && ((xu-xl) < COUENNE_EPS)) {
71 
72  if (is1const) i0s = (fabs (c1) * (xu-xl) < COUENNE_EPS);
73  else i0s = ((fabs (yu) + fabs (yl)) * (xu-xl) < COUENNE_EPS);
74 
75  if (i0s)
76  c0 = 0.5 * (xl+xu);
77  }
78 
79  // ...and y
80 
81  if (!is1const && ((yu-yl) < COUENNE_EPS)) {
82 
83  if (is0const) i1s = (fabs (c0) * (yu-yl) < COUENNE_EPS);
84  else i1s = ((fabs (xu) + fabs (xl)) * (yu-yl) < COUENNE_EPS);
85 
86  if (i1s)
87  c1 = 0.5 * (yl+yu);
88  }
89 
90  if (i0s) is0const = true;
91  if (i1s) is1const = true;
92 
93  // right now c0 and c1 only have a value if the corresponding
94  // expression is constant
95 
96  if (is0const || is1const) {
97 
98  if (cg -> isFirst () || // if first call or
99  ((xe -> Type () != CONST) && // neither term is a defined constant
100  (ye -> Type () != CONST))) { // (=> implied by branching rule)
101 
102  if (is0const && is1const)
103  // w = c0*c1, which is either because the intervals got very
104  // narrow, or because these are indeed constant (which should
105  // have been dealt with in simplify(), but who knows...)
106  cg -> createCut (cs, c0 * c1, cg -> Problem () -> Var (wi) -> sign (), wi, 1.);
107 
108  else {
109 
110  CouNumber coe;
111  int ind;
112 
113  if (is0const) {coe = c0; ind = yi;} // c*y
114  else {coe = c1; ind = xi;} // x*c
115 
116  cg -> createCut (cs, 0., cg -> Problem () -> Var (wi) -> sign (), wi, 1., ind, -coe);
117  }
118  }
119 
120  return;
121  }
122 
123  enum auxSign sign = cg -> Problem () -> Var (wi) -> sign ();
124 
125  // add different cuts, to cut out current point in bounding box but
126  // out of the hyperbola's belly
127 
128  unifiedProdCuts (cg, cs,
129  xi, (*(arglist_ [0])) (), xl, xu,
130  yi, (*(arglist_ [1])) (), yl, yu,
131  wi, (*w) (), wl, wu,
132  //sign == expression::AUX_LEQ ? -COIN_DBL_MAX : wl,
133  //sign == expression::AUX_GEQ ? COIN_DBL_MAX : wu,
134  chg, sign);
135 }
Cut Generator for linear convexifications.
static Bigint *ULong * xe
Definition: OSdtoa.cpp:1707
void unifiedProdCuts(const CouenneCutGenerator *, OsiCuts &, int, CouNumber, CouNumber, CouNumber, int, CouNumber, CouNumber, CouNumber, int, CouNumber, CouNumber, CouNumber, t_chg_bounds *, enum expression::auxSign)
unified convexification of products and divisions
status of lower/upper bound of a variable, to be checked/modified in bound tightening ...
virtual void generateCuts(expression *w, OsiCuts &cs, const CouenneCutGenerator *cg, t_chg_bounds *=NULL, int=-1, CouNumber=-COUENNE_INFINITY, CouNumber=COUENNE_INFINITY)
generate equality between *this and *w
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
expression ** arglist_
argument list is an array of pointers to other expressions
double CouNumber
main number type in Couenne
Expression base class.
void fint fint fint real fint real real real real real real real real * w
virtual CouNumber Value() const
value (empty)
virtual void getBounds(expression *&, expression *&)
Get lower and upper bound of an expression (if any)