/home/coin/SVN-release/OS-2.4.0/Couenne/src/convex/operators/conv-exprExp.cpp

Go to the documentation of this file.
00001 /* $Id: conv-exprExp.cpp 490 2011-01-14 16:07:12Z pbelotti $
00002  *
00003  * Name:    conv-exprExp.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: convexification and bounding methods for the exponential operator
00006  *
00007  * (C) Carnegie-Mellon University, 2006-10.
00008  * This file is licensed under the Eclipse Public License (EPL)
00009  */
00010 
00011 #include "CouenneCutGenerator.hpp"
00012 
00013 #include "CouenneTypes.hpp"
00014 #include "CouenneExprExp.hpp"
00015 #include "CouenneExprConst.hpp"
00016 #include "CouenneExprAux.hpp"
00017 #include "CouenneExprPow.hpp"
00018 
00019 #include "CouenneProblem.hpp"
00020 
00021 using namespace Couenne;
00022 
00023 // generate convexification cut for constraint w = this
00024 
00025 void exprExp::generateCuts (expression *aux, //const OsiSolverInterface &si, 
00026                             OsiCuts &cs,  const CouenneCutGenerator *cg,
00027                             t_chg_bounds *chg, int wind, 
00028                             CouNumber lbw, CouNumber ubw) {
00029   CouNumber l, u;
00030   argument_ -> getBounds (l, u);
00031 
00032   int w_ind = aux       -> Index (),
00033       x_ind = argument_ -> Index ();
00034 
00035   bool cL = !chg || (chg [x_ind].lower() != t_chg_bounds::UNCHANGED) || cg -> isFirst ();
00036   bool cR = !chg || (chg [x_ind].upper() != t_chg_bounds::UNCHANGED) || cg -> isFirst ();
00037 
00038   enum auxSign sign = cg -> Problem () -> Var (w_ind) -> sign ();
00039 
00040   if (fabs (u-l) < COUENNE_EPS) {  // bounds very close, convexify with a single line
00041 
00042     CouNumber x0 = 0.5 * (u+l), ex0 = exp (x0);
00043     if (cL || cR)
00044       cg -> createCut (cs, ex0 * (1 - x0), sign, w_ind, 1., x_ind, - ex0);
00045 
00046     return;
00047   }
00048 
00049   CouNumber x = (cg -> isFirst ()) ? 
00050                  0 : powNewton ((*argument_) (), (*aux) (), exp, exp, exp);
00051 
00052   // upper segment
00053 
00054   if ((sign != expression::AUX_GEQ)
00055       && (cL || cR) 
00056       && (u < log (COUENNE_INFINITY) ) 
00057       && (l > -    COUENNE_INFINITY / 1e4)) { // tame lower bound
00058 
00059     CouNumber expl     = exp (l),
00060               oppslope = (expl - exp (u)) / (u - l);
00061 
00062     cg -> createCut (cs, expl + oppslope*l, -1, 
00063                      w_ind, 1., 
00064                      x_ind, oppslope);
00065   }
00066 
00067   // no need to continue if this is an expression of the form y<=e^x
00068   // (the upper segment is needed only)
00069   if (sign == expression::AUX_LEQ)
00070     return;
00071 
00072   // add tangent points: first choose sampling points
00073 
00074   const CouNumber logMC = log (COU_MAX_COEFF);
00075 
00076   // add tangents with finite coefficients
00077   if (l < - logMC) l = - logMC;
00078   if (u >   logMC) u =   logMC;
00079 
00080   // approximate the exponential function from below
00081   cg -> addEnvelope (cs, +1, exp, exp, w_ind, x_ind, x, l, u, chg, true);
00082 }

Generated on Thu Sep 22 03:05:56 2011 by  doxygen 1.4.7