impliedBounds-mul.cpp
Go to the documentation of this file.
1 /* $Id: impliedBounds-mul.cpp 490 2011-01-14 16:07:12Z pbelotti $ */
2 /*
3  * Name: impliedBounds-mul.cpp
4  * Author: Pietro Belotti
5  * Purpose: inferring bounds on factors of a product
6  *
7  * (C) Carnegie-Mellon University, 2006.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include <vector>
12 
13 #include "CoinHelperFunctions.hpp"
14 #include "CouenneExprMul.hpp"
15 
16 using namespace Couenne;
17 
19  CouNumber wu,
20  std::vector <CouNumber> &xlv,
21  std::vector <CouNumber> &xuv,
22  std::vector <std::pair <int, CouNumber> > &nl,
23  std::vector <std::pair <int, CouNumber> > &nu) {
24  int nImpr = 0;
25 
26  // case 1: vectors of order 2
27 
28  if (xlv.size () == 2) {
29 
30  CouNumber
31  xl = xlv [0], xu = xuv [0],
32  yl = xlv [1], yu = xuv [1];
33 
34  if (wl >= 0.) {
35 
36  // point B in central infeasible area
37 
38  if (xu * yu < wl) {
39  if (xu * yl < wl) {nu.push_back (std::pair <int, CouNumber> (0, wl / yl)); nImpr++;}
40  if (xl * yu < wl) {nu.push_back (std::pair <int, CouNumber> (1, wl / xl)); nImpr++;}
41  //resxU = (*xu * *yl < wl) && updateBound (+1, xu, wl / *yl);
42  //resyU = (*xl * *yu < wl) && updateBound (+1, yu, wl / *xl);
43  }
44 
45  // point C in central infeasible area
46 
47  if (xl * yl < wl) {
48  if (xl * yu < wl) {nl.push_back (std::pair <int, CouNumber> (0, wl / yu)); nImpr++;}
49  if (xu * yl < wl) {nl.push_back (std::pair <int, CouNumber> (1, wl / xu)); nImpr++;}
50  //resxL = (xl * yu < wl) && updateBound (-1, xl, wl / yu);
51  //resyL = (xu * yl < wl) && updateBound (-1, yl, wl / xu);
52  }
53  } else if (wl > -COUENNE_INFINITY) {
54 
55  // the infeasible set is a hyperbola with two branches
56 
57  // upper left
58  if ((xl*yl < wl) && (yl>0.)) {nl.push_back (std::pair <int, CouNumber> (0, wl / yl)); nImpr++;}
59  if ((xu*yu < wl) && (yu>0.)) {nu.push_back (std::pair <int, CouNumber> (1, wl / xu)); nImpr++;}
60  //resxL = (xl * yl < wl) && (yl > 0.) && updateBound (-1, xl, wl / yl); // point C
61  //resyU = (xu * yu < wl) && (yu > 0.) && updateBound (+1, yu, wl / xu); // point B
62 
63  // lower right
64  if ((xu*yu < wl) && (yu<0.)) {nu.push_back (std::pair <int, CouNumber> (0, wl / yu)); nImpr++;}
65  if ((xl*yl < wl) && (yl<0.)) {nl.push_back (std::pair <int, CouNumber> (1, wl / xl)); nImpr++;}
66  //resxU = (xu * yu < wl) && (yu < 0.) && updateBound (+1, xu, wl / yu); // point B
67  //resyL = (xl * yl < wl) && (yl < 0.) && updateBound (-1, yl, wl / xl); // point C
68  }
69 
70 
71  // w's upper bound ///////////////////////////////////////////
72 
73  if (wu >= 0.) {
74 
75  if (wu < COUENNE_INFINITY) {
76  // the infeasible set is a hyperbola with two branches
77 
78  // upper right
79  if ((xu*yl > wu) && (yl>0.)) {nu.push_back (std::pair <int, CouNumber> (0, wu/yl)); nImpr++;}
80  if ((xl*yu > wu) && (yu>0.)) {nu.push_back (std::pair <int, CouNumber> (1, wu/xl)); nImpr++;}
81  //resxU = (xu * yl > wu) && (yl > 0.) && updateBound (+1, xu, wu / yl) || resxU; // point D
82  //resyU = (xl * yu > wu) && (yu > 0.) && updateBound (+1, yu, wu / xl) || resyU; // point A
83 
84  // lower left
85  if ((xl*yu > wu) && (yu<0.)) {nl.push_back (std::pair <int, CouNumber> (0, wu/yu)); nImpr++;}
86  if ((xu*yl > wu) && (yl<0.)) {nl.push_back (std::pair <int, CouNumber> (1, wu/xu)); nImpr++;}
87  //resxL = (xl * yu > wu) && (yu < 0.) && updateBound (-1, xl, wu / yu) || resxL; // point A
88  //resyL = (xu * yl > wu) && (yl < 0.) && updateBound (-1, yl, wu / xu) || resyL; // point D
89  }
90 
91  } else {
92 
93  // point D in central infeasible area
94 
95  if (xu * yl > wu) {
96  if (xu * yu > wu) {nu.push_back (std::pair <int, CouNumber> (0, wu / yu)); nImpr++;}
97  if (xl * yl > wu) {nl.push_back (std::pair <int, CouNumber> (1, wu / xl)); nImpr++;}
98  //resxU = (xu * yu > wu) && updateBound (+1, xu, wu / yu) || resxU;
99  //resyL = (xl * yl > wu) && updateBound (-1, yl, wu / xl) || resyL;
100  }
101 
102  // point A in central infeasible area
103 
104  if (xl * yu > wu) {
105  if (xl * yl > wu) {nl.push_back (std::pair <int, CouNumber> (0, wu / yl)); nImpr++;}
106  if (xu * yu > wu) {nu.push_back (std::pair <int, CouNumber> (1, wu / xu)); nImpr++;}
107  //resxL = (xl * yl > wu) && updateBound (-1, xl, wu / yl) || resxL;
108  //resyU = (xu * yu > wu) && updateBound (+1, yu, wu / xu) || resyU;
109  }
110  }
111  }
112 
113  return nImpr;
114 }
double CouNumber
main number type in Couenne
#define COUENNE_INFINITY
fint nu
int impliedBoundMul(CouNumber wl, CouNumber wu, std::vector< CouNumber > &xl, std::vector< CouNumber > &xu, std::vector< std::pair< int, CouNumber > > &nl, std::vector< std::pair< int, CouNumber > > &nu)
inferring bounds on factors of a product