/home/coin/SVN-release/OS-2.4.1/Couenne/src/convex/operators/conv-exprDiv.cpp

Go to the documentation of this file.
00001 /* $Id: conv-exprDiv.cpp 732 2011-07-03 20:06:50Z pbelotti $
00002  *
00003  * Name:    conv-exprDiv.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: standardization and convexification methods for divisions
00006  *
00007  * (C) Carnegie-Mellon University, 2006-11.
00008  * This file is licensed under the Eclipse Public License (EPL)
00009  */
00010 
00011 #include "CouenneCutGenerator.hpp"
00012 
00013 #include "CouenneTypes.hpp"
00014 #include "CouenneExpression.hpp"
00015 #include "CouenneExprAux.hpp"
00016 #include "CouenneExprOp.hpp"
00017 #include "CouenneExprDiv.hpp"
00018 #include "CouenneExprMul.hpp"
00019 #include "CouenneProblem.hpp"
00020 
00021 using namespace Couenne;
00022 
00023 // Create standard formulation of this expression
00024 exprAux *exprDiv::standardize (CouenneProblem *p, bool addAux) {
00025 
00026   exprOp::standardize (p);
00027   return (addAux ? (p -> addAuxiliary (this)) : new exprAux (this, p -> domain ()));
00028 }
00029 
00030 
00031 // generate convexification cut for constraint w = x/y
00032 void exprDiv::generateCuts (expression *w, //const OsiSolverInterface &si, 
00033                             OsiCuts &cs, const CouenneCutGenerator *cg,
00034                             t_chg_bounds *chg, int wind, 
00035                             CouNumber lbw, CouNumber ubw) {
00036   // compute y bounds
00037 
00038   CouNumber yl, yu;
00039   arglist_ [1] -> getBounds (yl, yu);
00040 
00041   int xi = arglist_ [0] -> Index (),
00042       yi = arglist_ [1] -> Index (),
00043       wi = w            -> Index ();
00044 
00045   bool cLW,  cRW,  cLY,  cRY = 
00046        cLW = cRW = cLY = true;
00047 
00048   if (!(cg -> isFirst ()) && chg) {
00049     cLW = (chg [wi].lower() != t_chg_bounds::UNCHANGED);
00050     cRW = (chg [wi].upper() != t_chg_bounds::UNCHANGED);
00051     cLY = (chg [yi].lower() != t_chg_bounds::UNCHANGED);
00052     cRY = (chg [yi].upper() != t_chg_bounds::UNCHANGED);
00053   }
00054 
00055   // no convexification for terms x/y where y=0 is internal to the
00056   // bounding box
00057 
00058   if ((yl < -0.) && 
00059       (yu >  0.)) return;   
00060 
00061   CouNumber k;
00062 
00063   enum auxSign sign = cg -> Problem () -> Var (wi) -> sign ();
00064 
00065   // special case #1: y is almost constant (nonzero) --> y = k. We
00066   // only need a single plane w >/</= x/k.
00067   if ((fabs (yl-yu) < COUENNE_EPS) && 
00068       ((fabs (k = ((yl+yu) / 2)) > COUENNE_EPS))) {
00069     if (cLY || cRY)
00070       cg -> createCut (cs, 0., sign, wi, 1., xi, -1./k);
00071     return;
00072   }
00073 
00074   CouNumber wl, wu;
00075   w -> getBounds (wl, wu);
00076 
00077   if (lbw > wl) wl = lbw;
00078   if (ubw < wu) wu = ubw;
00079 
00080   // special case #2: w is almost constant (nonzero) --> w = x/y = k. We
00081   // only need a single plane x >/</= y*k.
00082 
00083   if ((fabs (wl-wu) < COUENNE_EPS) &&
00084       ((k = fabs (wl+wu) / 2) > COUENNE_EPS) &&
00085       // extra condition: either y's bounds are both pos or both neg,
00086       // or this is an equality
00087       ((sign==expression::AUX_EQ) || (yl > 0.) || (yu < 0.))) { 
00088 
00089     if (cLW || cRW) {
00090       if (sign==expression::AUX_EQ || (yl > 0.)) cg -> createCut (cs, 0., sign, yi,  k, xi, -1.);
00091       else                                       cg -> createCut (cs, 0., sign, yi, -k, xi,  1.);
00092     }
00093 
00094     return;
00095   }
00096 
00097   CouNumber xl, xu;
00098   arglist_ [0] -> getBounds (xl, xu);
00099 
00100   if ((fabs (xl-xu) < COUENNE_EPS) &&
00101       (fabs (yl-yu) < COUENNE_EPS) &&
00102       (fabs (wl-wu) < COUENNE_EPS))
00103     return; // not much to do here...
00104 
00105   // same as product, just a change in coordinates
00106 
00107   //CouNumber *x = w -> domain () -> x ();
00108   CouNumber *x = cg -> Problem () -> X ();
00109 
00110   bool 
00111     ineqFullOrthantF = (((sign == expression::AUX_LEQ) && (yl >  0.)) || ((sign == expression::AUX_GEQ) && (yu < -0.))),
00112     ineqFullOrthantB = (((sign == expression::AUX_LEQ) && (yu < -0.)) || ((sign == expression::AUX_GEQ) && (yl >  0.)));
00113 
00114   unifiedProdCuts (cg, cs,
00115                    wi, x [wi], wl, wu,
00116                    yi, x [yi], yl, yu,
00117                    xi, x [xi], 
00118                    ineqFullOrthantF ? -COIN_DBL_MAX : xl, 
00119                    ineqFullOrthantB ?  COIN_DBL_MAX : xu, 
00120                    chg, 
00121                    ineqFullOrthantF ? expression::AUX_GEQ :
00122                    ineqFullOrthantB ? expression::AUX_LEQ : 
00123                                       expression::AUX_EQ);
00124 }

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