1 /* $Id$
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 
addPowEnvelope(const CouenneCutGenerator * cg,OsiCuts & cs,int wi,int xi,CouNumber x,CouNumber y,CouNumber k,CouNumber l,CouNumber u,int sign,bool signpower)26 void Couenne::addPowEnvelope (const CouenneCutGenerator *cg, OsiCuts &cs,
27 			      int wi, int xi,
28 			      CouNumber x, CouNumber y,
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 }
85