conv-exprPow-envelope.cpp
Go to the documentation of this file.
1 /* $Id: conv-exprPow-envelope.cpp 940 2013-01-13 19:49:02Z pbelotti $
2  *
3  * Name: conv-exprPow-envelope.cpp
4  * Author: Pietro Belotti
5  * Purpose: methods of the expression class
6  *
7  * (C) Carnegie-Mellon University, 2006-11.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include <math.h>
12 
13 #include "CouenneCutGenerator.hpp"
14 
15 #include "CouenneTypes.hpp"
16 #include "CouenneRootQ.hpp"
17 #include "CouenneExprPow.hpp"
18 #include "CouennePrecisions.hpp"
19 #include "CouenneProblem.hpp"
20 #include "CouenneFunTriplets.hpp"
21 
22 using namespace Couenne;
23 
24 // adds convex (upper/lower) envelope to a power function
25 
26 void Couenne::addPowEnvelope (const CouenneCutGenerator *cg, OsiCuts &cs,
27  int wi, int xi,
29  CouNumber k,
30  CouNumber l, CouNumber u,
31  int sign, bool signpower) {
32 
33  // set x to get a deeper cut (so that we get a tangent which is
34  // orthogonal with line through current- and tangent point)
35 
36  powertriplet pt (k, signpower);
37 
38  if (!(cg -> isFirst ()))
39  x = powNewton (x, y, &pt);
40 
41  if (x<l) x=l;
42  else if (x>u) x=u;
43 
44  // limit the bounds for the envelope
45 
46  CouNumber powThres = (k<=1) ? COU_MAX_COEFF: pow (COU_MAX_COEFF, 1./k);
47  //step = (1 + log (1. + (double) (cg -> nSamples ()))) * powThres / COU_MAX_COEFF;
48 
49  // If the bounds are too large, the linearization cuts might have
50  // large coefficients. To prevent that, Couenne used to set very
51  // small fictitious bounds, resulting in
52  //
53  // 1) still valid cuts, but
54  //
55  // 2) a very abrupt change in their coefficients;
56  //
57  // 3) cuts that may result in an LP solution far away from x (this
58  // behavior recalls that of bundle methods for NDO);
59  //
60  // 4) a non-exact linearization at the bounds (in theory, necessary
61  // for convergence...).
62  //
63  // New values for l and u, if necessary, are therefore set to the
64  // maximum bounds if l and/or u are beyond them.
65  //
66  // Thanks to Sergey for pointing this out.
67 
68  if (l < - powThres + 1) {
69  l = - powThres + 1; // keeps bounds reasonably large
70  //l = x - step;
71  if (u > powThres - 1) {
72  u = powThres - 1;
73  //u = x + step;
74  }
75  } else
76  if (u > powThres - 1) {
77  u = powThres - 1;
78  //u = x + step;
79  }
80 
81  // convex envelope
82  cg -> addEnvelope (cs, sign, &pt,
83  wi, xi, x, l, u);
84 }
Cut Generator for linear convexifications.
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
void addPowEnvelope(const CouenneCutGenerator *, OsiCuts &, int, int, CouNumber, CouNumber, CouNumber, CouNumber, CouNumber, int, bool=false)
add upper/lower envelope to power in convex/concave areas
#define COU_MAX_COEFF
void fint fint * k
double CouNumber
main number type in Couenne
void fint fint fint real fint real * x