00001
00002
00003
00004
00005
00006
00007
00008
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
00024 expression *lba, *uba;
00025
00026 argument_ -> getBounds (lba, uba);
00027
00028
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
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
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
00093
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
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.) {
00137 left = -COUENNE_INFINITY;
00138 right = COUENNE_INFINITY;
00139 }
00140 else if (curr < -valdep) {
00141 left = curr;
00142 right = -valdep;
00143 }
00144 else if (curr > valdep) {
00145 left = valdep;
00146 right = curr;
00147 }
00148 else {
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
00170
00171
00172
00173
00174