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

Go to the documentation of this file.
00001 /* $Id: conv-exprLog.cpp 490 2011-01-14 16:07:12Z pbelotti $
00002  *
00003  * Name:    conv-exprLog.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: convexification and bounding methods for the logarithm operator
00006  *
00007  * (C) Carnegie-Mellon University, 2006-09.
00008  * This file is licensed under the Eclipse Public License (EPL)
00009  */
00010 
00011 #include "CouenneCutGenerator.hpp"
00012 
00013 #include "CouenneTypes.hpp"
00014 #include "CouenneExprLog.hpp"
00015 #include "CouenneExprPow.hpp"
00016 #include "CouenneExprAux.hpp"
00017 
00018 #include "CouenneProblem.hpp"
00019 
00020 using namespace Couenne;
00021 
00022 #define LOG_STEP 10
00023 #define LOG_MININF 1e-50
00024 
00025 // generate convexification cut for constraint w = this
00026 
00027 void exprLog::generateCuts (expression *aux, //const OsiSolverInterface &si, 
00028                             OsiCuts &cs, const CouenneCutGenerator *cg,
00029                             t_chg_bounds *chg, int wind, 
00030                             CouNumber lbw, CouNumber ubw) {
00031   int 
00032     w_ind = aux       -> Index (), //   dependent variable's index
00033     x_ind = argument_ -> Index (); // independent variable's index
00034 
00035   bool changed = 
00036     !chg || (cg -> isFirst ()) || 
00037     (chg [x_ind].lower() != t_chg_bounds::UNCHANGED) ||
00038     (chg [x_ind].upper() != t_chg_bounds::UNCHANGED);
00039 
00040   CouNumber l, u;
00041   argument_ -> getBounds (l, u);
00042 
00043   enum auxSign sign = cg -> Problem () -> Var (w_ind) -> sign ();
00044 
00045   // if bounds are very close, convexify with a single line
00046   if ((fabs (u - l) < COUENNE_EPS) && (l > COUENNE_EPS)) {
00047 
00048     CouNumber x0 = 0.5 * (u+l);
00049     if (changed) cg -> createCut (cs, log (x0) - 1, sign, w_ind, 1., x_ind, - 1/x0);
00050     return;
00051   }
00052 
00053   // fix lower bound
00054   if (l < LOG_MININF) l = LOG_MININF;
00055   else   // lower segment (if l is far from zero and u finite)
00056     if ((u < COUENNE_INFINITY) && changed && sign != expression::AUX_LEQ) { 
00057 
00058       CouNumber dx   = u-l;
00059       CouNumber logu = log (u);
00060       CouNumber dw   = logu - log (l);
00061 
00062       cg -> createCut (cs, dx*logu - u*dw, +1, w_ind, dx, x_ind, -dw);
00063     }
00064 
00065   // no need to continue if auxiliary is defined as w >= log (x)
00066   if (sign == expression::AUX_GEQ) 
00067     return;
00068 
00069   // pick tangent point closest to current point (x0,y0)
00070   CouNumber x = (cg -> isFirst ()) ? 
00071                  1 : powNewton ((*argument_) (), (*aux) (), log, inv, oppInvSqr);
00072 
00073   // check if outside interval
00074   if      (x < l) x = l;
00075   else if (x > u) x = u;
00076 
00077   // fix bound interval (unless you like infinite coefficients)
00078   if (u > 1e5 * log (COUENNE_INFINITY) - 1)
00079     u = x + (LOG_STEP << cg -> nSamples ());
00080 
00081   // add upper envelope
00082   cg -> addEnvelope (cs, -1, log, inv, w_ind, x_ind, x, l, u, chg, true);
00083 }

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