source: branches/Couenne/Couenne/src/branch/operators/branchExprMul.cpp @ 557

Last change on this file since 557 was 557, checked in by pbelotti, 12 years ago

use a more elaborate structure to check changed bounds. Check bounds of other variables after applying OBBT for one. Remove exit from exprSub::impliedBound. Return changed bounds in exprPow. Added explicit handling of whichWay in CouenneObject?. Added branching rule for expr{Inv,Log} and exprMul (infinite bounds).

File size: 2.2 KB
Line 
1/*
2 * Name:    branchExprMul.cpp
3 * Author:  Pietro Belotti
4 * Purpose: return branch data for multiplications
5 *
6 * (C) Pietro Belotti. This file is licensed under the Common Public License (CPL)
7 */
8
9#include <exprMul.h>
10#include <CouennePrecisions.h>
11#include <CouenneTypes.h>
12#include <CouenneObject.hpp>
13#include <CouenneBranchingObject.hpp>
14#include <projections.h>
15
16
17#define LARGE_BOUND 9.9e12
18#define BOUND_WING 100
19
20/// set up branching object by evaluating many branching points for
21/// each expression's arguments
22CouNumber exprMul::selectBranch (expression *w, 
23                                 const OsiBranchingInformation *info,
24                                 int &ind, 
25                                 double * &brpts, 
26                                 int &way) {
27  int xi = arglist_ [0] -> Index (),
28      yi = arglist_ [1] -> Index ();
29
30  if ((xi < 0) || (yi < 0)) {
31    printf ("arguments of exprMul have negative index\n");
32    exit (-1);
33  }
34
35  CouNumber x0 = expression::Variable (xi),   y0 = expression::Variable (yi), 
36            xl = expression::Lbound   (xi),   yl = expression::Lbound   (yi), 
37            xu = expression::Ubound   (xi),   yu = expression::Ubound   (yi); 
38
39  // First, try to avoid infinite bounds for multiplications, which
40  // make them pretty hard to deal with
41
42  if ((xl < - COUENNE_INFINITY) && 
43      (xu >   COUENNE_INFINITY)) { // first
44
45    ind = xi;
46
47    // branch around current point. If it is also at a crazy value,
48    // reset it close to zero.
49
50    brpts = (double *) malloc (2 * sizeof (double));
51    CouNumber curr = x0;
52
53    if (fabs (curr) >= LARGE_BOUND) curr = 0;
54
55    brpts [0] = curr - BOUND_WING;
56    brpts [1] = curr + BOUND_WING;
57
58    way = THREE_CENTER;
59
60    return COUENNE_INFINITY;
61  }
62
63  if ((yl < - COUENNE_INFINITY) && 
64      (yu >   COUENNE_INFINITY)) { // and second factor
65
66    ind = yi;
67
68    // branch around current point. If it is also at a crazy value,
69    // reset it close to zero.
70
71    brpts = (double *) malloc (2 * sizeof (double));
72    CouNumber curr = y0;
73
74    if (fabs (curr) >= LARGE_BOUND) curr = 0;
75
76    brpts [0] = curr - BOUND_WING;
77    brpts [1] = curr + BOUND_WING;
78
79    way = THREE_CENTER;
80
81    return COUENNE_INFINITY;
82  }
83
84  // there is at least one finite corner of the bounding box
85
86  ind = -1;
87  return 0.;
88}
Note: See TracBrowser for help on using the repository browser.