/home/coin/SVN-release/OS-2.4.1/Couenne/src/expression/operators/exprSub.cpp

Go to the documentation of this file.
00001 /* $Id: exprSub.cpp 560 2011-04-17 10:01:15Z stefan $
00002  *
00003  * Name:    exprSub.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: definition of subtractions
00006  *
00007  * (C) Carnegie-Mellon University, 2006-10.
00008  * This file is licensed under the Eclipse Public License (EPL)
00009  */
00010 
00011 #include "CouenneExprSub.hpp"
00012 #include "CouenneExprConst.hpp"
00013 #include "CouenneExprOpp.hpp"
00014 #include "CouennePrecisions.hpp"
00015 
00016 #include "CoinFinite.hpp"
00017 
00018 using namespace Couenne;
00019 
00020 // simplify subtractions
00021 
00022 expression *exprSub::simplify () {
00023 
00024   exprOp:: simplify ();
00025 
00026   // check for (f(x) - f(x))
00027   if (arglist_ [0] -> compare (*(arglist_ [1])) == 0) {
00028 
00029     delete arglist_ [0]; arglist_ [0] = NULL;
00030     delete arglist_ [1]; arglist_ [1] = NULL;
00031 
00032     return new exprConst (0.);
00033   }
00034 
00035   // check for other special cases
00036   if ((*arglist_) -> Type () == CONST) { // expr = c1 - f2 
00037 
00038     CouNumber c0 = (*arglist_) -> Value ();
00039 
00040     if (arglist_ [1] -> Type () == CONST) { // expr = c1 - c2
00041 
00042       CouNumber c1 = arglist_ [1] -> Value ();
00043 
00044       delete arglist_ [0]; arglist_ [0] = NULL;
00045       delete arglist_ [1]; arglist_ [1] = NULL;
00046 
00047       return new exprConst (c0 - c1);
00048     }
00049     else if (fabs (c0) < COUENNE_EPS_SIMPL) { // expr = opp (f2)
00050 
00051       expression *ret = new exprOpp (arglist_ [1]);
00052       delete arglist_ [0];
00053       arglist_ [0] = arglist_ [1] = NULL;
00054       return ret;
00055     }
00056   }
00057   else // only need to check if f2 == 0
00058 
00059     if ((arglist_ [1] -> Type () == CONST) &&
00060         (fabs (arglist_ [1] -> Value ()) < COUENNE_EPS_SIMPL)) {
00061       // expr = f1 - 0 --> return f1
00062 
00063       expression *ret = arglist_ [0];
00064       delete arglist_ [1];
00065       arglist_ [0] = arglist_ [1] = NULL;
00066       return ret;
00067     }
00068 
00069   return NULL;
00070 }
00071 
00072 
00073 // differentiate product of expressions
00074 
00075 expression *exprSub::differentiate (int index) {
00076 
00077   expression **arglist = new expression * [nargs_];
00078 
00079   for (int i = 0; i < nargs_; i++)
00080     if (arglist_ [i] -> dependsOn (index))
00081          arglist [i] = arglist_ [i] -> differentiate (index);
00082     else arglist [i] = new exprConst (0.);
00083 
00084   return new exprSub (arglist, nargs_);
00085 }
00086 
00087 
00088 // Get lower and upper bound of an expression (if any)
00089 void exprSub::getBounds (expression *&lb, expression *&ub) {
00090 
00091   expression **alsl = new expression * [2];
00092   expression **alsu = new expression * [2];
00093 
00094   arglist_ [0] -> getBounds (alsl [0], alsu [0]);
00095   arglist_ [1] -> getBounds (alsu [1], alsl [1]);
00096 
00097   lb = new exprSub (alsl, 2);
00098   ub = new exprSub (alsu, 2);
00099 }
00100 
00101 
00102 // Get value of lower and upper bound of an expression (if any)
00103 void exprSub::getBounds (CouNumber &lb, CouNumber &ub) {
00104 
00105   CouNumber lba0, uba0, lba1, uba1;
00106 
00107   arglist_ [0] -> getBounds (lba0, uba0);
00108   arglist_ [1] -> getBounds (lba1, uba1);
00109 
00110   lb = ((lba0 < -COUENNE_INFINITY) || (uba1 >  COUENNE_INFINITY)) ?
00111     -COUENNE_INFINITY :
00112     (lba0 - uba1);
00113 
00114   ub = ((uba0 >  COUENNE_INFINITY) || (lba1 < -COUENNE_INFINITY)) ?
00115     COUENNE_INFINITY :
00116     (uba0 - lba1);
00117 }
00118 
00119 
00122 
00123 bool exprSub::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum auxSign sign) {
00124 
00125   // caution, xi or yi might be -1
00126   int xi = arglist_ [0] -> Index (),
00127       yi = arglist_ [1] -> Index ();
00128 
00129   if ((xi == -1) && (yi == -1)) // both x and y are constant
00130     return false;
00131 
00132   CouNumber xl, xu, yl, yu, 
00133     wl = sign == expression::AUX_GEQ ? -COIN_DBL_MAX : l [wind], 
00134     wu = sign == expression::AUX_LEQ ?  COIN_DBL_MAX : u [wind];
00135 
00136   if (xi==-1) xl =         xu = arglist_ [0] -> Value ();
00137   else       {xl = l [xi]; xu = u [xi];}
00138 
00139   if (yi==-1) yl =         yu = arglist_ [1] -> Value ();
00140   else       {yl = l [yi]; yu = u [yi];}
00141 
00142   bool res = false;
00143 
00144   // w >= l
00145 
00146   bool 
00147     xInt = arglist_ [0] -> isInteger (),
00148     yInt = arglist_ [1] -> isInteger ();
00149 
00150   if (wl > -COUENNE_INFINITY) {
00151 
00152     if ((xi>=0) && (updateBound (-1, l + xi, xInt ? ceil  (yl + wl - COUENNE_EPS) : (yl + wl)))) {
00153       res = true;
00154       chg [xi].setLower(t_chg_bounds::CHANGED);
00155     }
00156 
00157     if ((yi>=0) && (updateBound (+1, u + yi, yInt ? floor (xu - wl + COUENNE_EPS) : (xu - wl)))) {
00158       res = true;
00159       chg [yi].setUpper(t_chg_bounds::CHANGED);
00160     }
00161   }
00162 
00163   // w <= u
00164 
00165   if (wu < COUENNE_INFINITY) {
00166 
00167     if ((xi>=0) && (updateBound (+1, u + xi, xInt ? floor (yu + wu + COUENNE_EPS) : (yu + wu)))) {
00168       res = true;
00169       chg [xi].setUpper(t_chg_bounds::CHANGED);
00170     }
00171 
00172     if ((yi>=0) && (updateBound (-1, l + yi, yInt ? ceil (xl - wu - COUENNE_EPS) : (xl - wu)))) {
00173       res = true;
00174       chg [yi].setLower(t_chg_bounds::CHANGED);
00175     }
00176   }
00177 
00178   return res;
00179 }

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