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

Go to the documentation of this file.
00001 /* $Id: exprAbs.cpp 141 2009-06-03 04:19:19Z pbelotti $ */
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. 
00008  * This file is licensed under the Common Public License (CPL)
00009  */
00010 
00011 #include "exprAbs.hpp"
00012 #include "exprClone.hpp"
00013 #include "exprMin.hpp"
00014 #include "exprMax.hpp"
00015 #include "exprOpp.hpp"
00016 
00017 #include "CouenneProblem.hpp"
00018 
00020 
00021 void exprAbs::getBounds (expression *&lb, expression *&ub) {
00022 
00023   // get bounds of the argument
00024   expression *lba, *uba;
00025 
00026   argument_ -> getBounds (lba, uba);
00027 
00028   // lower bound = max (0, lb, -ub)
00029 
00030   expression **all = new expression * [6];
00031   all [0] = new exprConst (0.);  all [1] = new exprConst (0.);
00032   all [2] = new exprOpp (uba);   all [3] = new exprOpp (new exprClone (uba));
00033   all [4] = lba;                 all [5] = new exprClone (lba);
00034 
00035   lb = new exprMax (all, 6);
00036 
00037   // upper bound = max (|lb|, |ub|)
00038 
00039   ub = new exprMax (new exprAbs (new exprClone (lba)), 
00040                     new exprAbs (new exprClone (uba)));
00041 }
00042 
00043 
00045 
00046 void exprAbs::getBounds (CouNumber &lb, CouNumber &ub) {
00047 
00048   // get bounds of the argument
00049   CouNumber lba, uba;
00050 
00051   argument_ -> getBounds (lba, uba);
00052 
00053   if (lba > 0) {
00054     lb = lba;
00055     ub = uba;
00056   } else if (uba < 0) {
00057     lb = -uba;
00058     ub = -lba;
00059   } else {
00060     lb = 0;
00061     ub = CoinMax (-lb, ub);
00062   }
00063 }
00064 
00065 
00067 
00068 expression *exprAbs::differentiate (int index) {
00069 
00070   expression **arglist = new expression * [4];
00071   expression  *diffarg = argument_ -> differentiate (index);
00072 
00073   arglist [0] = new exprConst (0.);
00074   arglist [1] = new exprClone (diffarg);
00075   arglist [2] = new exprOpp (new exprClone (argument_));
00076   arglist [3] = new exprOpp (diffarg);
00077 
00078   return new exprMin (arglist, 4);
00079 }
00080 
00081 
00084 
00085 bool exprAbs::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg) {
00086 
00087   int index = argument_ -> Index ();
00088 
00089   CouNumber *xl = l + index, wl = l [wind],
00090             *xu = u + index, wu = u [wind];
00091 
00092   // for w >= b > 0, we can only improve xlb if it is at least  b
00093   //                                     xub             most  -b
00094 
00095   bool tighter = false;
00096 
00097   if (wl > 0) {
00098     if      (*xl > 0) {
00099       if (updateBound (-1, xl, argument_ -> isInteger () ? ceil   (wl - COUENNE_EPS) :  wl)) {
00100         tighter = true; 
00101         chg [index].setLower(t_chg_bounds::CHANGED);
00102       }
00103     }
00104     else if (*xu < 0) {
00105       if (updateBound (+1, xu, argument_ -> isInteger () ? floor (-wl + COUENNE_EPS) : -wl)) {
00106         tighter = true; 
00107         chg [index].setUpper(t_chg_bounds::CHANGED);
00108       }
00109     }
00110   }
00111 
00112   // w <= u (if u < 0 the problem is infeasible)
00113 
00114   if (wu < COUENNE_INFINITY) {
00115     if (updateBound (-1, xl, argument_ -> isInteger () ? ceil (-wu - COUENNE_EPS) : -wu)) {
00116       tighter = true; 
00117       chg [index].setLower(t_chg_bounds::CHANGED);
00118     }
00119     if (updateBound (+1, xu, argument_ -> isInteger () ? floor (wu + COUENNE_EPS) :  wu)) {
00120       tighter = true; 
00121       chg [index].setUpper(t_chg_bounds::CHANGED);
00122     }
00123   }
00124 
00125   return tighter;
00126 }
00127 
00128 
00130 void exprAbs::closestFeasible (expression *varind, expression *vardep,
00131                                CouNumber& left, CouNumber& right) const
00132 {
00133   CouNumber valdep = (*vardep)();
00134   CouNumber curr = (*varind)();
00135 
00136   if (valdep < 0.) { // no way to restore feasibility, set infinite interval
00137     left = -COUENNE_INFINITY;
00138     right = COUENNE_INFINITY;
00139   }
00140   else if (curr < -valdep) { // hence curr negative and behind left part of |x|
00141     left = curr;
00142     right = -valdep;
00143   }
00144   else if (curr > valdep) { // hence curr positive and after right half-line of |x|
00145     left = valdep;
00146     right = curr;
00147   }
00148   else { // between the two half-lines
00149     left = -valdep;
00150     right = valdep;
00151   }
00152 
00153 }
00154 
00155 
00158 bool exprAbs::isCuttable (CouenneProblem *problem, int index) const {
00159 
00160   double 
00161     x = problem -> X (argument_ -> Index ()),
00162     y = problem -> X (index);
00163 
00164   return ((y <= x) || (y <= -x));
00165 }
00166 
00167 
00169 //enum convexity exprAbs::convexity () const {
00170 
00171 //  CouNumber lb, ub;
00172 //  getBounds (lb, ub);
00173 //  return (((lb >= 0.) || (ub <= 0.)) ? AFFINE : CONVEX);
00174 //}

Generated on Mon Aug 3 03:02:20 2009 by  doxygen 1.4.7