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