00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <math.h>
00012
00013 #include "CouenneExprLog.hpp"
00014 #include "CouenneExprConst.hpp"
00015 #include "CouenneExprClone.hpp"
00016 #include "CouenneExprMax.hpp"
00017 #include "CouenneExprMin.hpp"
00018 #include "CouenneExprDiv.hpp"
00019 #include "CouenneProblem.hpp"
00020
00021 #include "CoinHelperFunctions.hpp"
00022 #include "CoinFinite.hpp"
00023
00024 using namespace Couenne;
00025
00027
00028 void exprLog::getBounds (expression *&lb, expression *&ub) {
00029
00030 expression *lba, *uba;
00031 argument_ -> getBounds (lba, uba);
00032
00033
00034
00035
00036
00037 expression **all = new expression * [4];
00038
00039 all [0] = new exprClone (lba); all [1] = new exprLog (lba);
00040 all [2] = new exprConst (0); all [3] = new exprConst (- COUENNE_INFINITY);
00041 lb = new exprMax (all, 4);
00042
00043 expression **alu = new expression * [4],
00044 **alum = new expression * [4];
00045
00046 alum [0] = new exprConst (COUENNE_INFINITY);
00047 alum [1] = new exprConst (COUENNE_INFINITY);
00048 alum [2] = new exprClone (uba);
00049 alum [3] = new exprLog (uba);
00050
00051 alu [0] = new exprClone (uba); alu [1] = new exprMin (alum, 4);
00052 alu [2] = new exprConst (0.); alu [3] = new exprConst (- COUENNE_INFINITY);
00053 ub = new exprMax (alu, 4);
00054 }
00055
00056
00058
00059 void exprLog::getBounds (CouNumber &lb, CouNumber &ub) {
00060
00061 CouNumber lba, uba;
00062 argument_ -> getBounds (lba, uba);
00063
00064 lb = log (CoinMax (1e-50, lba));
00065 ub = log (CoinMax (1e-50, uba));
00066 }
00067
00068
00070 expression *exprLog::differentiate (int index) {
00071 return new exprDiv (argument_ -> differentiate (index),
00072 new exprClone (argument_));
00073 }
00074
00075
00078 bool exprLog::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum auxSign sign) {
00079
00080 int ind = argument_ -> Index ();
00081
00082 bool
00083 res = false,
00084 isint = argument_ -> isInteger();
00085
00086 CouNumber
00087 wl = sign == expression::AUX_GEQ ? -COIN_DBL_MAX : l [wind],
00088 wu = sign == expression::AUX_LEQ ? COIN_DBL_MAX : u [wind];
00089
00090 if (updateBound (-1, l+ind, isint ? ceil (exp (wl) - COUENNE_EPS) : exp (wl))) {
00091 res = true;
00092 chg [ind].setLower (t_chg_bounds::CHANGED);
00093 }
00094
00095 if (updateBound ( 1, u+ind, isint? floor (exp (wu) + COUENNE_EPS) : exp (wu))) {
00096 res = true;
00097 chg [ind].setUpper (t_chg_bounds::CHANGED);
00098 }
00099
00100 return res;
00101 }
00102
00103
00105 CouNumber exprLog::gradientNorm (const double *x) {
00106 return (argument_ -> Index () < 0) ? 0. :
00107 1. / (CoinMax (1. / COUENNE_INFINITY, x [argument_ -> Index ()]));
00108 }
00109
00110
00113 bool exprLog::isCuttable (CouenneProblem *problem, int index) const {
00114
00115 double
00116 x = problem -> X (argument_ -> Index ()),
00117 y = problem -> X (index);
00118
00119 return ((x == 0.) || (y > log (x)));
00120 }