/home/coin/SVN-release/OS-2.1.0/Couenne/src/bound_tightening/operators/impliedBounds-mul.cpp

Go to the documentation of this file.
00001 /* $Id: impliedBounds-mul.cpp 141 2009-06-03 04:19:19Z pbelotti $ */
00002 /*
00003  * Name:    impliedBounds-mul.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: inferring bounds on factors of a product
00006  *
00007  * (C) Carnegie-Mellon University, 2006. 
00008  * This file is licensed under the Common Public License (CPL)
00009  */
00010 
00011 #include <vector>
00012 
00013 #include "CoinHelperFunctions.hpp"
00014 #include "exprMul.hpp"
00015 
00016 int exprMul::impliedBoundMul (CouNumber wl, 
00017                               CouNumber wu, 
00018                               std::vector <CouNumber> &xlv,
00019                               std::vector <CouNumber> &xuv,
00020                               std::vector <std::pair <int, CouNumber> > &nl,
00021                               std::vector <std::pair <int, CouNumber> > &nu) {
00022   int nImpr = 0;
00023 
00024   // case 1: vectors of order 2
00025 
00026   if (xlv.size () == 2) {
00027 
00028     CouNumber 
00029       xl = xlv [0],  xu = xuv [0],
00030       yl = xlv [1],  yu = xuv [1];
00031 
00032     if (wl >= 0.) {
00033 
00034       // point B in central infeasible area
00035 
00036       if (xu * yu < wl) {
00037         if (xu * yl < wl) {nu.push_back (std::pair <int, CouNumber> (0, wl / yl)); nImpr++;}
00038         if (xl * yu < wl) {nu.push_back (std::pair <int, CouNumber> (1, wl / xl)); nImpr++;}
00039         //resxU = (*xu * *yl < wl) && updateBound (+1, xu, wl / *yl);
00040         //resyU = (*xl * *yu < wl) && updateBound (+1, yu, wl / *xl);
00041       }
00042 
00043       // point C in central infeasible area
00044 
00045       if (xl * yl < wl) {
00046         if (xl * yu < wl) {nl.push_back (std::pair <int, CouNumber> (0, wl / yu)); nImpr++;}
00047         if (xu * yl < wl) {nl.push_back (std::pair <int, CouNumber> (1, wl / xu)); nImpr++;}
00048         //resxL = (xl * yu < wl) && updateBound (-1, xl, wl / yu);
00049         //resyL = (xu * yl < wl) && updateBound (-1, yl, wl / xu);
00050       }
00051     } else if (wl > -COUENNE_INFINITY) {
00052 
00053       // the infeasible set is a hyperbola with two branches
00054 
00055       // upper left
00056       if ((xl*yl < wl) && (yl>0.)) {nl.push_back (std::pair <int, CouNumber> (0, wl / yl)); nImpr++;}
00057       if ((xu*yu < wl) && (yu>0.)) {nu.push_back (std::pair <int, CouNumber> (1, wl / xu)); nImpr++;}
00058       //resxL = (xl * yl < wl) && (yl > 0.) && updateBound (-1, xl, wl / yl); // point C
00059       //resyU = (xu * yu < wl) && (yu > 0.) && updateBound (+1, yu, wl / xu); // point B
00060 
00061       // lower right
00062       if ((xu*yu < wl) && (yu<0.)) {nu.push_back (std::pair <int, CouNumber> (0, wl / yu)); nImpr++;}
00063       if ((xl*yl < wl) && (yl<0.)) {nl.push_back (std::pair <int, CouNumber> (1, wl / xl)); nImpr++;}
00064       //resxU = (xu * yu < wl) && (yu < 0.) && updateBound (+1, xu, wl / yu); // point B
00065       //resyL = (xl * yl < wl) && (yl < 0.) && updateBound (-1, yl, wl / xl); // point C
00066     }
00067 
00068 
00069     // w's upper bound ///////////////////////////////////////////
00070 
00071     if (wu >= 0.) {
00072 
00073       if (wu < COUENNE_INFINITY) {
00074         // the infeasible set is a hyperbola with two branches
00075 
00076         // upper right
00077         if ((xu*yl > wu) && (yl>0.)) {nu.push_back (std::pair <int, CouNumber> (0, wu/yl)); nImpr++;}
00078         if ((xl*yu > wu) && (yu>0.)) {nu.push_back (std::pair <int, CouNumber> (1, wu/xl)); nImpr++;}
00079         //resxU = (xu * yl > wu) && (yl > 0.) && updateBound (+1, xu, wu / yl) || resxU; // point D
00080         //resyU = (xl * yu > wu) && (yu > 0.) && updateBound (+1, yu, wu / xl) || resyU; // point A
00081 
00082         // lower left
00083         if ((xl*yu > wu) && (yu<0.)) {nl.push_back (std::pair <int, CouNumber> (0, wu/yu)); nImpr++;}
00084         if ((xu*yl > wu) && (yl<0.)) {nl.push_back (std::pair <int, CouNumber> (1, wu/xu)); nImpr++;}
00085         //resxL = (xl * yu > wu) && (yu < 0.) && updateBound (-1, xl, wu / yu) || resxL; // point A
00086         //resyL = (xu * yl > wu) && (yl < 0.) && updateBound (-1, yl, wu / xu) || resyL; // point D
00087       }
00088 
00089     } else {
00090 
00091       // point D in central infeasible area
00092 
00093       if (xu * yl > wu) {
00094         if (xu * yu > wu) {nu.push_back (std::pair <int, CouNumber> (0, wu / yu)); nImpr++;}
00095         if (xl * yl > wu) {nl.push_back (std::pair <int, CouNumber> (1, wu / xl)); nImpr++;}
00096         //resxU = (xu * yu > wu) && updateBound (+1, xu, wu / yu) || resxU;
00097         //resyL = (xl * yl > wu) && updateBound (-1, yl, wu / xl) || resyL;
00098       }
00099 
00100       // point A in central infeasible area
00101 
00102       if (xl * yu > wu) {
00103         if (xl * yl > wu) {nl.push_back (std::pair <int, CouNumber> (0, wu / yl)); nImpr++;}
00104         if (xu * yu > wu) {nu.push_back (std::pair <int, CouNumber> (1, wu / xu)); nImpr++;}
00105         //resxL = (xl * yl > wu) && updateBound (-1, xl, wu / yl) || resxL;
00106         //resyU = (xu * yu > wu) && updateBound (+1, yu, wu / xu) || resyU;
00107       }
00108     }
00109   }
00110 
00111   return nImpr;
00112 }

Generated on Tue Mar 30 03:04:36 2010 by  doxygen 1.4.7