/home/coin/SVN-release/OS-2.4.0/Couenne/src/expression/operators/exprAbs.cpp

Go to the documentation of this file.
00001 /* $Id: exprAbs.cpp 560 2011-04-17 10:01:15Z stefan $
00002  *
00003  * Name:    exprAbs.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: definition of the absulute value of a function
00006  *
00007  * (C) Carnegie-Mellon University, 2006-10.
00008  * This file is licensed under the Eclipse Public License (EPL)
00009  */
00010 
00011 #include "CouenneExprAbs.hpp"
00012 #include "CouenneExprClone.hpp"
00013 #include "CouenneExprMin.hpp"
00014 #include "CouenneExprMax.hpp"
00015 #include "CouenneExprOpp.hpp"
00016 
00017 #include "CouenneProblem.hpp"
00018 
00019 #include "CoinHelperFunctions.hpp"
00020 #include "CoinFinite.hpp"
00021 
00022 using namespace Couenne;
00023 
00025 
00026 void exprAbs::getBounds (expression *&lb, expression *&ub) {
00027 
00028   // get bounds of the argument
00029   expression *lba, *uba;
00030 
00031   argument_ -> getBounds (lba, uba);
00032 
00033   // lower bound = max (0, lb, -ub)
00034 
00035   expression **all = new expression * [6];
00036   all [0] = new exprConst (0.);  all [1] = new exprConst (0.);
00037   all [2] = new exprOpp (uba);   all [3] = new exprOpp (new exprClone (uba));
00038   all [4] = lba;                 all [5] = new exprClone (lba);
00039 
00040   lb = new exprMax (all, 6);
00041 
00042   // upper bound = max (|lb|, |ub|)
00043 
00044   ub = new exprMax (new exprAbs (new exprClone (lba)), 
00045                     new exprAbs (new exprClone (uba)));
00046 }
00047 
00048 
00050 
00051 void exprAbs::getBounds (CouNumber &lb, CouNumber &ub) {
00052 
00053   // get bounds of the argument
00054   CouNumber lba, uba;
00055 
00056   argument_ -> getBounds (lba, uba);
00057 
00058   if (lba > 0) {
00059     lb = lba;
00060     ub = uba;
00061   } else if (uba < 0) {
00062     lb = -uba;
00063     ub = -lba;
00064   } else {
00065     lb = 0.;
00066     ub = CoinMax (-lba, uba);
00067   }
00068 }
00069 
00070 
00072 
00073 expression *exprAbs::differentiate (int index) {
00074 
00075   expression **arglist = new expression * [4];
00076   expression  *diffarg = argument_ -> differentiate (index);
00077 
00078   arglist [0] = new exprConst (0.);
00079   arglist [1] = new exprClone (diffarg);
00080   arglist [2] = new exprOpp (new exprClone (argument_));
00081   arglist [3] = new exprOpp (diffarg);
00082 
00083   return new exprMin (arglist, 4);
00084 }
00085 
00086 
00089 
00090 bool exprAbs::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum auxSign sign) {
00091 
00092   int index = argument_ -> Index ();
00093 
00094   CouNumber *xl = l + index, wl = sign == expression::AUX_GEQ ? -COIN_DBL_MAX : l [wind],
00095             *xu = u + index, wu = sign == expression::AUX_LEQ ?  COIN_DBL_MAX : u [wind];
00096 
00097   // for w >= b > 0, we can only improve xlb if it is at least  b
00098   //                                     xub             most  -b
00099 
00100   bool tighter = false;
00101 
00102   if (wl > 0) {
00103     if      (*xl > 0) {
00104       if (updateBound (-1, xl, argument_ -> isInteger () ? ceil   (wl - COUENNE_EPS) :  wl)) {
00105         tighter = true; 
00106         chg [index].setLower(t_chg_bounds::CHANGED);
00107       }
00108     }
00109     else if (*xu < 0) {
00110       if (updateBound (+1, xu, argument_ -> isInteger () ? floor (-wl + COUENNE_EPS) : -wl)) {
00111         tighter = true; 
00112         chg [index].setUpper(t_chg_bounds::CHANGED);
00113       }
00114     }
00115   }
00116 
00117   // w <= u (if u < 0 the problem is infeasible)
00118 
00119   if (wu < COUENNE_INFINITY) {
00120     if (updateBound (-1, xl, argument_ -> isInteger () ? ceil (-wu - COUENNE_EPS) : -wu)) {
00121       tighter = true; 
00122       chg [index].setLower(t_chg_bounds::CHANGED);
00123     }
00124     if (updateBound (+1, xu, argument_ -> isInteger () ? floor (wu + COUENNE_EPS) :  wu)) {
00125       tighter = true; 
00126       chg [index].setUpper(t_chg_bounds::CHANGED);
00127     }
00128   }
00129 
00130   return tighter;
00131 }
00132 
00133 
00135 void exprAbs::closestFeasible (expression *varind, expression *vardep,
00136                                CouNumber& left, CouNumber& right) const
00137 {
00138   CouNumber valdep = (*vardep)();
00139   CouNumber curr = (*varind)();
00140 
00141   if (valdep < 0.) { // no way to restore feasibility, set infinite interval
00142     left = -COUENNE_INFINITY;
00143     right = COUENNE_INFINITY;
00144   }
00145   else if (curr < -valdep) { // hence curr negative and behind left part of |x|
00146     left = curr;
00147     right = -valdep;
00148   }
00149   else if (curr > valdep) { // hence curr positive and after right half-line of |x|
00150     left = valdep;
00151     right = curr;
00152   }
00153   else { // between the two half-lines
00154     left = -valdep;
00155     right = valdep;
00156   }
00157 
00158 }
00159 
00160 
00163 bool exprAbs::isCuttable (CouenneProblem *problem, int index) const {
00164 
00165   double 
00166     x = problem -> X (argument_ -> Index ()),
00167     y = problem -> X (index);
00168 
00169   return ((y <= x) || (y <= -x));
00170 }
00171 
00172 
00174 //enum convexity exprAbs::convexity () const {
00175 
00176 //  CouNumber lb, ub;
00177 //  getBounds (lb, ub);
00178 //  return (((lb >= 0.) || (ub <= 0.)) ? AFFINE : CONVEX);
00179 //}

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