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