branchExprExp.cpp
Go to the documentation of this file.
1 /* $Id: branchExprExp.cpp 708 2011-06-23 14:04:59Z pbelotti $
2  *
3  * Name: branchExprExp.cpp
4  * Author: Pietro Belotti
5  * Purpose: return branch gain and branch object for exponentials
6  *
7  * (C) Carnegie-Mellon University, 2006-10.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include "CoinHelperFunctions.hpp"
12 
13 #include "CouenneExprExp.hpp"
14 #include "CouenneObject.hpp"
16 #include "CouenneProjections.hpp"
17 #include "CouenneFunTriplets.hpp"
18 
19 using namespace Couenne;
20 
24  const OsiBranchingInformation *info,
25  expression *&var,
26  double * &brpts,
27  double * &brDist, // distance of current LP
28  // point to new convexifications
29  int &way) {
30 
31  // two cases: inside and outside the curve.
32  //
33  // Inside: the distance depends on the projection of the current
34  // point onto the would-be upper envelopes, which forces us to look
35  // at it numerically. If both bounds are infinite, create a ThreeWay
36  // branch.
37  //
38  // Outside: it suffices to project the current point on the line
39  // (i.e. to get the closest point on the line) to get the maxi-min
40  // displacement.
41  //
42  // As for all monotone functions, after choosing *brpts it is
43  // equivalent to choose w's or x's index as ind, as the implied- and
44  // propagated bounds will do the rest.
45 
46  var = argument_;
47 
48  brDist = (double *) realloc (brDist, 2 * sizeof (double));
49  brpts = (double *) realloc (brpts, sizeof (double));
50 
51  int
52  ind = var -> Index (),
53  wi = obj -> Reference () -> Index ();
54 
55  assert ((ind >= 0) && (wi >= 0));
56 
57  CouNumber y0 = info -> solution_ [wi],
58  x0 = info -> solution_ [ind],
59  l = info -> lower_ [ind],
60  u = info -> upper_ [ind];
61 
62  // Outside //////////////////////////////////////////////////////////////////
63 
64  if (y0 < exp (x0)) {
65 
66  // Look for point (x1,y1) on curve y=exp(x) closest to current
67  // (x0,y0), branch at x1
68 
69  *brpts = obj -> midInterval (powNewton (x0, y0, exp, exp, exp), l, u, info);
70 
71  way = TWO_RAND;
72 
73  y0 -= exp (*brpts);
74  x0 -= *brpts;
75 
76  return sqrt (brDist [0] = brDist [1] = sqrt (x0*x0 + y0*y0)); // exact distance
77  }
78 
79  // Inside. Four cases: ///////////////////////////////////////////////////////
80 
81  if ((l < -COUENNE_INFINITY) &&
82  (u > COUENNE_INFINITY)) { // unbounded in both directions
83 
84  /* // TODO: restore when we can do three-way branching
85 #if 0
86  brpts = (double *) realloc (brpts, 2 * sizeof (double));
87  way = THREE_CENTER; // focus on central convexification first
88  brpts [0] = x0; // draw vertical from (x0,y0) south to curve y=exp(x)
89  brpts [1] = log (y0); // horizontal east
90  CouNumber
91  a = y0 - exp (x0), // sides of a triangle with (x0,y0)
92  b = log (y0) - x0; // as one of the vertices
93  // exact distance from central interval, from others it's a and b
94  return (a * cos (atan (a/b)));
95 #endif */
96 
97  // follow South-East diagonal to find point on curve
98  // so that current point is surely cut
99  *brpts = 0.5 * (x0 + log (y0));
100  way = TWO_RAND;
101 
102  return CoinMin (brDist [0] = log (y0) - x0,
103  brDist [1] = y0 - exp (x0));
104  }
105 
106  // 2,3) at least one of them is finite
107 
108  if (l < - COUENNE_INFINITY) { // 2) unbounded from below --> break vertically
109 
110  *brpts = obj -> midInterval (x0, l, u, info);
111 
112  way = TWO_RIGHT;
113  return CoinMin (brDist [0] = y0 - exp (x0),
114  brDist [1] = projectSeg (x0, y0, *brpts, exp (*brpts), u, exp (u), -1));
115  }
116 
117  if (u > COUENNE_INFINITY) { // 3) unbounded from above -- break horizontally
118 
119  *brpts = obj -> midInterval (log (y0), l, u, info);
120 
121  way = TWO_LEFT;
122  return CoinMin (brDist [0] = projectSeg (x0, y0, l, exp (l), *brpts, exp (*brpts), -1),
123  brDist [1] = log (y0) - x0);
124 
125  }
126 
127  // 4) both are finite
128 
129  simpletriplet ft (exp, exp, exp, log);
130  *brpts = obj -> getBrPoint (&ft, x0, l, u, info); // select based on strategy
131 
132  way = TWO_RAND;
133 
134  // exact distance
135  return CoinMin (brDist [0] = projectSeg (x0, y0, l, exp (l), *brpts, exp (*brpts), -1),
136  brDist [1] = projectSeg (x0, y0, *brpts, exp (*brpts), u, exp (u), -1));
137 }
void fint fint fint real fint real real real real real real real real real fint real fint fint fint real fint fint fint fint * info
OsiObject for auxiliary variables $w=f(x)$.
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
virtual CouNumber selectBranch(const CouenneObject *obj, const OsiBranchingInformation *info, expression *&var, double *&brpts, double *&brDist, int &way)
Set up branching object by evaluating many branching points for each expression&#39;s arguments...
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)
CouNumber projectSeg(CouNumber x0, CouNumber y0, CouNumber x1, CouNumber y1, CouNumber x2, CouNumber y2, int sign, CouNumber *xp=NULL, CouNumber *yp=NULL)
Compute projection of point (x0, y0) on the segment defined by two points (x1,y1), (x2, y2) – sign provided by parameter sign.
Definition: projections.cpp:78
double CouNumber
main number type in Couenne
#define COUENNE_INFINITY
Expression base class.