branchExprTrilinear.cpp
Go to the documentation of this file.
1 /* $Id: branchExprTrilinear.cpp 490 2011-01-14 16:07:12Z pbelotti $
2  *
3  * Name: branchExprTrilinear.cpp
4  * Author: Pietro Belotti
5  * Purpose: return branch data for trilinear terms
6  *
7  * This file is licensed under the Eclipse Public License (EPL)
8  */
9 
10 #include "CouennePrecisions.hpp"
11 #include "CouenneTypes.hpp"
12 #include "CouenneObject.hpp"
13 
14 #include "CouenneExprTrilinear.hpp"
15 #include "CouenneFunTriplets.hpp"
16 #include "CouenneProjections.hpp"
17 
18 using namespace Couenne;
19 
23  const OsiBranchingInformation *info,
24  expression *&var,
25  double * &brpts,
26  double * &brDist, // distance of current LP point
27  // to new convexifications
28  int &way) {
29 
30  if (brDist) {free (brDist); brDist = NULL;} // clear it, computeMulBrDist will fill it
31 
32  int
33  xi = arglist_ [0] -> Index (),
34  yi = arglist_ [1] -> Index (),
35  zi = arglist_ [2] -> Index ();
36 
37  assert ((xi >= 0) && (yi >= 0) && (zi >= 0));
38 
39  CouNumber
40  xl = info -> lower_ [xi], yl = info -> lower_ [yi], zl = info -> lower_ [zi],
41  xu = info -> upper_ [xi], yu = info -> upper_ [yi], zu = info -> upper_ [zi];
42 
43  brpts = (double *) realloc (brpts, sizeof (double));
44  brDist = (double *) realloc (brDist, 2 * sizeof (double));
45 
46  // case 0: term is fixed
47 
48  if ((fabs (xu - xl) < COUENNE_EPS) &&
49  (fabs (xu - xl) < COUENNE_EPS) &&
50  (fabs (xu - xl) < COUENNE_EPS)) {
51 
52  var = NULL;
53  return 0.;
54  }
55 
56  // a very simple branching scheme:
57  //
58  // if any bound interval is (-inf,+inf), break it by branching at zero
59  // otherwise, if any bound interval is [a,+inf) or (-inf,b],
60  // break it by branching at zero (if interval includes zero) or
61  // at 2a-1 (resp. 2b+1)
62  // otherwise, branch on the largest bound, in the middle
63 
64  if ((xl < -COUENNE_INFINITY) && (xu > COUENNE_INFINITY)) {*brpts = 0.; brDist [0] = brDist [1] = 1.; var = arglist_ [0]; return 1.;}
65  if ((yl < -COUENNE_INFINITY) && (yu > COUENNE_INFINITY)) {*brpts = 0.; brDist [0] = brDist [1] = 1.; var = arglist_ [1]; return 1.;}
66  if ((zl < -COUENNE_INFINITY) && (zu > COUENNE_INFINITY)) {*brpts = 0.; brDist [0] = brDist [1] = 1.; var = arglist_ [2]; return 1.;}
67 
68 
69 #define SETBNDS(l,u,ind) { \
70 \
71  if (l < -COUENNE_INFINITY) {\
72  if (u > 1.) {*brpts = 0.; brDist [0] = brDist [1] = 1.; var = arglist_ [ind]; return 1.;}\
73  else {*brpts = 2*-fabs (u) - 1.; brDist [0] = brDist [1] = 1.; var = arglist_ [ind]; return 1.;}\
74  }\
75 \
76  if (u > COUENNE_INFINITY) {\
77  if (l < -1.) {*brpts = 0.; brDist [0] = brDist [1] = 1.; var = arglist_ [ind]; return 1.;}\
78  else {*brpts = 2*fabs (u) + 1.; brDist [0] = brDist [1] = 1.; var = arglist_ [ind]; return 1.;}\
79  }\
80 }
81 
82  SETBNDS (xl, xu, 0);
83  SETBNDS (xl, xu, 1);
84  SETBNDS (xl, xu, 2);
85 
86  // bounds all finite, choose largest bound interval width
87  if ((xu - xl > yu - yl) && (xu - xl > zu - zl)) {*brpts = .5 * (xl + xu); brDist [0] = brDist [1] = 1.; var = arglist_ [0]; return 1.;}
88  else if ((yu - yl > zu - zl)) {*brpts = .5 * (yl + yu); brDist [0] = brDist [1] = 1.; var = arglist_ [1]; return 1.;}
89  else {*brpts = .5 * (zl + zu); brDist [0] = brDist [1] = 1.; var = arglist_ [2]; return 1.;}
90 }
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)$.
#define SETBNDS(l, u, ind)
virtual int Index() const
Return index of variable (only valid for exprVar and exprAux)
#define COUENNE_EPS
expression ** arglist_
argument list is an array of pointers to other expressions
double CouNumber
main number type in Couenne
#define COUENNE_INFINITY
Expression base class.
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 ...