00001
00002
00003
00004
00005
00006
00007
00008
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
00029 expression *lba, *uba;
00030
00031 argument_ -> getBounds (lba, uba);
00032
00033
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
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
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
00098
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
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.) {
00142 left = -COUENNE_INFINITY;
00143 right = COUENNE_INFINITY;
00144 }
00145 else if (curr < -valdep) {
00146 left = curr;
00147 right = -valdep;
00148 }
00149 else if (curr > valdep) {
00150 left = valdep;
00151 right = curr;
00152 }
00153 else {
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
00175
00176
00177
00178
00179