00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <stdio.h>
00012
00013 #include "CouenneExprInv.hpp"
00014 #include "CouenneExprClone.hpp"
00015 #include "CouenneExprMul.hpp"
00016 #include "CouenneExprOpp.hpp"
00017 #include "CouenneExprDiv.hpp"
00018 #include "CouenneExprPow.hpp"
00019 #include "CouenneProblem.hpp"
00020 #include "CouenneExpression.hpp"
00021
00022 #include "CoinFinite.hpp"
00023
00024 using namespace Couenne;
00025
00026
00027 expression *exprInv::differentiate (int index) {
00028
00029 return new exprOpp (new exprDiv (argument_ -> differentiate (index),
00030 new exprPow (new exprClone (argument_),
00031 new exprConst (2.))));
00032 }
00033
00034
00035
00036 void exprInv::print (std::ostream &out,
00037 bool descend) const {
00038 out << "(1/";
00039 argument_ -> print (out, descend);
00040 out << ")";
00041 }
00042
00043
00044
00047 void invPowImplBounds (int wind, int index,
00048 CouNumber *l, CouNumber *u, CouNumber k,
00049 bool &resL, bool &resU,
00050 enum expression::auxSign sign) {
00051
00052 CouNumber wl = sign == expression::AUX_GEQ ? -COIN_DBL_MAX : l [wind],
00053 wu = sign == expression::AUX_LEQ ? COIN_DBL_MAX : u [wind];
00054
00055
00056
00057 if (wl >= 0.) {
00058 if (wu > COUENNE_EPS) {
00059 if (wu < COUENNE_INFINITY) resL = updateBound (-1, l + index, pow (wu, k));
00060 else resL = updateBound (-1, l + index, 0.);
00061 }
00062 if (wl > COUENNE_EPS) resU = updateBound (+1, u + index, pow (wl, k));
00063 }
00064
00065
00066
00067 if (wu <= -0.) {
00068 if (wl < - COUENNE_EPS) {
00069 if (wl > - COUENNE_INFINITY) resU = updateBound (+1, u + index, pow (wl, k)) || resU;
00070 else resU = updateBound (+1, u + index, 0.) || resU;
00071 }
00072 if (wu < - COUENNE_EPS) resL = updateBound (-1, l + index, pow (wu, k)) || resL;
00073 }
00074 }
00075
00076
00079 bool exprInv::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum auxSign sign) {
00080
00081
00082
00083
00084
00085
00086
00087
00088 int index = argument_ -> Index ();
00089
00090 bool resL, resU = resL = false;
00091
00092 invPowImplBounds (wind, index, l, u, -1., resL, resU, sign);
00093
00094 bool argInt = argument_ -> isInteger ();
00095
00096 if (resL) {
00097 chg [index].setLower(t_chg_bounds::CHANGED);
00098 if (argInt) l [index] = ceil (l [index] - COUENNE_EPS);
00099 }
00100
00101 if (resU) {
00102 chg [index].setUpper(t_chg_bounds::CHANGED);
00103 if (argInt) u [index] = floor (u [index] + COUENNE_EPS);
00104 }
00105
00106 return (resL || resU);
00107 }
00108
00109
00111 CouNumber exprInv::gradientNorm (const double *x) {
00112 int ind = argument_ -> Index ();
00113 CouNumber xx;
00114 if (ind < 0) return 0.;
00115 else {
00116 xx = x [argument_ -> Index ()];
00117 return 1. / (xx*xx);
00118 }
00119 }
00120
00121
00124 bool exprInv::isCuttable (CouenneProblem *problem, int index) const {
00125
00126 int xind = argument_ -> Index ();
00127
00128 double
00129 x = problem -> X (xind),
00130 y = problem -> X (index);
00131
00132 return (((problem -> Lb (xind) >= 0) && (x > 0) && (y*x <= 1)) ||
00133 ((problem -> Ub (xind) <= 0) && (x < 0) && (y*x <= 1)));
00134 }