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

Go to the documentation of this file.
00001 /* $Id: impliedBounds-mul.cpp 490 2011-01-14 16:07:12Z 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 Eclipse Public License (EPL)
00009  */
00010 
00011 #include <vector>
00012 
00013 #include "CoinHelperFunctions.hpp"
00014 #include "CouenneExprMul.hpp"
00015 
00016 using namespace Couenne;
00017 
00018 int exprMul::impliedBoundMul (CouNumber wl, 
00019                               CouNumber wu, 
00020                               std::vector <CouNumber> &xlv,
00021                               std::vector <CouNumber> &xuv,
00022                               std::vector <std::pair <int, CouNumber> > &nl,
00023                               std::vector <std::pair <int, CouNumber> > &nu) {
00024   int nImpr = 0;
00025 
00026   // case 1: vectors of order 2
00027 
00028   if (xlv.size () == 2) {
00029 
00030     CouNumber 
00031       xl = xlv [0],  xu = xuv [0],
00032       yl = xlv [1],  yu = xuv [1];
00033 
00034     if (wl >= 0.) {
00035 
00036       // point B in central infeasible area
00037 
00038       if (xu * yu < wl) {
00039         if (xu * yl < wl) {nu.push_back (std::pair <int, CouNumber> (0, wl / yl)); nImpr++;}
00040         if (xl * yu < wl) {nu.push_back (std::pair <int, CouNumber> (1, wl / xl)); nImpr++;}
00041         //resxU = (*xu * *yl < wl) && updateBound (+1, xu, wl / *yl);
00042         //resyU = (*xl * *yu < wl) && updateBound (+1, yu, wl / *xl);
00043       }
00044 
00045       // point C in central infeasible area
00046 
00047       if (xl * yl < wl) {
00048         if (xl * yu < wl) {nl.push_back (std::pair <int, CouNumber> (0, wl / yu)); nImpr++;}
00049         if (xu * yl < wl) {nl.push_back (std::pair <int, CouNumber> (1, wl / xu)); nImpr++;}
00050         //resxL = (xl * yu < wl) && updateBound (-1, xl, wl / yu);
00051         //resyL = (xu * yl < wl) && updateBound (-1, yl, wl / xu);
00052       }
00053     } else if (wl > -COUENNE_INFINITY) {
00054 
00055       // the infeasible set is a hyperbola with two branches
00056 
00057       // upper left
00058       if ((xl*yl < wl) && (yl>0.)) {nl.push_back (std::pair <int, CouNumber> (0, wl / yl)); nImpr++;}
00059       if ((xu*yu < wl) && (yu>0.)) {nu.push_back (std::pair <int, CouNumber> (1, wl / xu)); nImpr++;}
00060       //resxL = (xl * yl < wl) && (yl > 0.) && updateBound (-1, xl, wl / yl); // point C
00061       //resyU = (xu * yu < wl) && (yu > 0.) && updateBound (+1, yu, wl / xu); // point B
00062 
00063       // lower right
00064       if ((xu*yu < wl) && (yu<0.)) {nu.push_back (std::pair <int, CouNumber> (0, wl / yu)); nImpr++;}
00065       if ((xl*yl < wl) && (yl<0.)) {nl.push_back (std::pair <int, CouNumber> (1, wl / xl)); nImpr++;}
00066       //resxU = (xu * yu < wl) && (yu < 0.) && updateBound (+1, xu, wl / yu); // point B
00067       //resyL = (xl * yl < wl) && (yl < 0.) && updateBound (-1, yl, wl / xl); // point C
00068     }
00069 
00070 
00071     // w's upper bound ///////////////////////////////////////////
00072 
00073     if (wu >= 0.) {
00074 
00075       if (wu < COUENNE_INFINITY) {
00076         // the infeasible set is a hyperbola with two branches
00077 
00078         // upper right
00079         if ((xu*yl > wu) && (yl>0.)) {nu.push_back (std::pair <int, CouNumber> (0, wu/yl)); nImpr++;}
00080         if ((xl*yu > wu) && (yu>0.)) {nu.push_back (std::pair <int, CouNumber> (1, wu/xl)); nImpr++;}
00081         //resxU = (xu * yl > wu) && (yl > 0.) && updateBound (+1, xu, wu / yl) || resxU; // point D
00082         //resyU = (xl * yu > wu) && (yu > 0.) && updateBound (+1, yu, wu / xl) || resyU; // point A
00083 
00084         // lower left
00085         if ((xl*yu > wu) && (yu<0.)) {nl.push_back (std::pair <int, CouNumber> (0, wu/yu)); nImpr++;}
00086         if ((xu*yl > wu) && (yl<0.)) {nl.push_back (std::pair <int, CouNumber> (1, wu/xu)); nImpr++;}
00087         //resxL = (xl * yu > wu) && (yu < 0.) && updateBound (-1, xl, wu / yu) || resxL; // point A
00088         //resyL = (xu * yl > wu) && (yl < 0.) && updateBound (-1, yl, wu / xu) || resyL; // point D
00089       }
00090 
00091     } else {
00092 
00093       // point D in central infeasible area
00094 
00095       if (xu * yl > wu) {
00096         if (xu * yu > wu) {nu.push_back (std::pair <int, CouNumber> (0, wu / yu)); nImpr++;}
00097         if (xl * yl > wu) {nl.push_back (std::pair <int, CouNumber> (1, wu / xl)); nImpr++;}
00098         //resxU = (xu * yu > wu) && updateBound (+1, xu, wu / yu) || resxU;
00099         //resyL = (xl * yl > wu) && updateBound (-1, yl, wu / xl) || resyL;
00100       }
00101 
00102       // point A in central infeasible area
00103 
00104       if (xl * yu > wu) {
00105         if (xl * yl > wu) {nl.push_back (std::pair <int, CouNumber> (0, wu / yl)); nImpr++;}
00106         if (xu * yu > wu) {nu.push_back (std::pair <int, CouNumber> (1, wu / xu)); nImpr++;}
00107         //resxL = (xl * yl > wu) && updateBound (-1, xl, wu / yl) || resxL;
00108         //resyU = (xu * yu > wu) && updateBound (+1, yu, wu / xu) || resyU;
00109       }
00110     }
00111   }
00112 
00113   return nImpr;
00114 }

Generated on Thu Nov 10 03:05:42 2011 by  doxygen 1.4.7