conv-exprExp.cpp
Go to the documentation of this file.
1 /* $Id: conv-exprExp.cpp 490 2011-01-14 16:07:12Z pbelotti $
2  *
3  * Name: conv-exprExp.cpp
4  * Author: Pietro Belotti
5  * Purpose: convexification and bounding methods for the exponential operator
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 "CouenneExprExp.hpp"
15 #include "CouenneExprConst.hpp"
16 #include "CouenneExprAux.hpp"
17 #include "CouenneExprPow.hpp"
18 
19 #include "CouenneProblem.hpp"
20 
21 using namespace Couenne;
22 
23 // generate convexification cut for constraint w = this
24 
25 void exprExp::generateCuts (expression *aux, //const OsiSolverInterface &si,
26  OsiCuts &cs, const CouenneCutGenerator *cg,
27  t_chg_bounds *chg, int wind,
28  CouNumber lbw, CouNumber ubw) {
29  CouNumber l, u;
30  argument_ -> getBounds (l, u);
31 
32  int w_ind = aux -> Index (),
33  x_ind = argument_ -> Index ();
34 
35  bool cL = !chg || (chg [x_ind].lower() != t_chg_bounds::UNCHANGED) || cg -> isFirst ();
36  bool cR = !chg || (chg [x_ind].upper() != t_chg_bounds::UNCHANGED) || cg -> isFirst ();
37 
38  enum auxSign sign = cg -> Problem () -> Var (w_ind) -> sign ();
39 
40  if (fabs (u-l) < COUENNE_EPS) { // bounds very close, convexify with a single line
41 
42  CouNumber x0 = 0.5 * (u+l), ex0 = exp (x0);
43  if (cL || cR)
44  cg -> createCut (cs, ex0 * (1 - x0), sign, w_ind, 1., x_ind, - ex0);
45 
46  return;
47  }
48 
49  CouNumber x = (cg -> isFirst ()) ?
50  0 : powNewton ((*argument_) (), (*aux) (), exp, exp, exp);
51 
52  // upper segment
53 
54  if ((sign != expression::AUX_GEQ)
55  && (cL || cR)
56  && (u < log (COUENNE_INFINITY) )
57  && (l > - COUENNE_INFINITY / 1e4)) { // tame lower bound
58 
59  CouNumber expl = exp (l),
60  oppslope = (expl - exp (u)) / (u - l);
61 
62  cg -> createCut (cs, expl + oppslope*l, -1,
63  w_ind, 1.,
64  x_ind, oppslope);
65  }
66 
67  // no need to continue if this is an expression of the form y<=e^x
68  // (the upper segment is needed only)
69  if (sign == expression::AUX_LEQ)
70  return;
71 
72  // add tangent points: first choose sampling points
73 
74  const CouNumber logMC = log (COU_MAX_COEFF);
75 
76  // add tangents with finite coefficients
77  if (l < - logMC) l = - logMC;
78  if (u > logMC) u = logMC;
79 
80  // approximate the exponential function from below
81  cg -> addEnvelope (cs, +1, exp, exp, w_ind, x_ind, x, l, u, chg, true);
82 }
Cut Generator for linear convexifications.
void generateCuts(expression *w, OsiCuts &cs, const CouenneCutGenerator *cg, t_chg_bounds *=NULL, int=-1, CouNumber=-COUENNE_INFINITY, CouNumber=COUENNE_INFINITY)
Generate convexification cuts for this expression.
CouExpr & log(CouExpr &e)
CouNumber powNewton(CouNumber xc, CouNumber yc, unary_function f, unary_function fp, unary_function fpp)
find proper tangent point to add deepest tangent cut
Definition: powNewton.cpp:29
status of lower/upper bound of a variable, to be checked/modified in bound tightening ...
const char & lower() const
const char & upper() const
expression * argument_
single argument taken by this expression
ULong * x0
Definition: OSdtoa.cpp:1776
CouExpr & exp(CouExpr &e)
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 COU_MAX_COEFF
#define COUENNE_EPS
double CouNumber
main number type in Couenne
#define COUENNE_INFINITY
void getBounds(expression *&, expression *&)
Get lower and upper bound of an expression (if any)
Definition: exprExp.cpp:29
Expression base class.
void fint fint fint real fint real * x