00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "exprExp.hpp"
00012 #include "exprClone.hpp"
00013 #include "exprMul.hpp"
00014 #include "CouenneProblem.hpp"
00015
00016
00017 expression *exprExp::differentiate (int index) {
00018
00019 return new exprMul (new exprExp (new exprClone (argument_)),
00020 argument_ -> differentiate (index));
00021 }
00022
00023
00024
00025 void exprExp::getBounds (expression *&lb, expression *&ub) {
00026
00027 expression *lba, *uba;
00028 argument_ -> getBounds (lba, uba);
00029
00030 lb = new exprExp (lba);
00031 ub = new exprExp (uba);
00032 }
00033
00034
00035
00036 void exprExp::getBounds (CouNumber &lb, CouNumber&ub) {
00037
00038 CouNumber lba, uba;
00039 argument_ -> getBounds (lba, uba);
00040
00041 lb = exp (lba);
00042 ub = exp (uba);
00043 }
00044
00045
00048 bool exprExp::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg) {
00049
00050 bool resU, resL = resU = false;
00051 int ind = argument_ -> Index ();
00052
00053 CouNumber b;
00054
00055 if ((b = l [wind]) >= COUENNE_EPS)
00056 resL = updateBound (-1, l + ind, argument_->isInteger () ? ceil (log (b)-COUENNE_EPS) : log (b));
00057
00058 if ((b = u [wind]) < COUENNE_INFINITY / 1e5)
00059 resU = updateBound ( 1, u + ind, argument_->isInteger () ? floor (log (b)+COUENNE_EPS) : log (b));
00060 else if (b < - COUENNE_EPS) {
00061
00062 resU = updateBound ( 1, u + ind, -1.) || true;
00063 resL = updateBound (-1, l + ind, 1.) || true;
00064 }
00065
00066 if (resL) chg [ind].setLower(t_chg_bounds::CHANGED);
00067 if (resU) chg [ind].setUpper(t_chg_bounds::CHANGED);
00068
00069 return (resL || resU);
00070 }
00071
00072
00075 bool exprExp::isCuttable (CouenneProblem *problem, int index) const {
00076
00077 double
00078 x = problem -> X (argument_ -> Index ()),
00079 y = problem -> X (index);
00080
00081 return (y <= exp (x));
00082 }