1 /* $Id$
2  *
3  * Name:    exprOpp.cpp
4  * Author:  Pietro Belotti
5  * Purpose: definition of the opposite -f(x) of a function
6  *
7  * (C) Carnegie-Mellon University, 2006-10.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include "CouenneExprOpp.hpp"
12 #include "CouenneExprConst.hpp"
13 #include "CouenneConfig.h"
14 #include "CoinHelperFunctions.hpp"
15 #include "CoinFinite.hpp"
16 
17 using namespace Couenne;
18 
19 // find bounds of -x given bounds on x
getBounds(expression * & lb,expression * & ub)20 void exprOpp::getBounds (expression *&lb, expression *&ub) {
21 
22   expression *lba, *uba;
23   argument_ -> getBounds (lba, uba);
24 
25   lb = new exprOpp (uba);
26   ub = new exprOpp (lba);
27 }
28 
29 
30 // find bounds of -x given bounds on x
getBounds(CouNumber & lb,CouNumber & ub)31 void exprOpp::getBounds (CouNumber &lb, CouNumber &ub) {
32 
33   CouNumber lba, uba;
34   argument_ -> getBounds (lba, uba);
35 
36   lb = -uba;
37   ub = -lba;
38 }
39 
40 
41 // differentiation
differentiate(int index)42 inline expression *exprOpp::differentiate (int index)
43 {return new exprOpp (argument_ -> differentiate (index));}
44 
45 
46 /// implied bound processing for expression w = -x, upon change in
47 /// lower- and/or upper bound of w, whose index is wind
impliedBound(int wind,CouNumber * l,CouNumber * u,t_chg_bounds * chg,enum auxSign sign)48 bool exprOpp::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum auxSign sign) {
49 
50   int ind = argument_ -> Index ();
51 
52   bool
53     res    = false,
54     argInt = argument_ -> isInteger ();
55 
56   CouNumber
57     wl = sign == expression::AUX_GEQ ? -COIN_DBL_MAX : l [wind],
58     wu = sign == expression::AUX_LEQ ?  COIN_DBL_MAX : u [wind];
59 
60   if (updateBound (-1, l + ind, argInt ? ceil  (- wu - COUENNE_EPS) : - wu)) {
61     res = true;
62     chg [ind].setLower(t_chg_bounds::CHANGED);
63   }
64 
65   if (updateBound ( 1, u + ind, argInt ? floor (- wl + COUENNE_EPS) : - wl)) {
66     res = true;
67     chg [ind].setUpper(t_chg_bounds::CHANGED);
68   }
69 
70   return res;
71 }
72 
73 
74 /// simplification
75 
simplify()76 expression *exprOpp::simplify () {
77 
78   expression *subst = exprUnary::simplify (); // simplify what's inside first
79 
80   if (subst)
81     return subst;
82 
83   // check if this is a -(-f(x))
84   if (argument_ -> code () == COU_EXPROPP) {
85     // leak. don't clone, use exprClone
86     expression *ret = argument_ -> Argument (); // -> clone ();
87     *(argument_ -> ArgPtr ()) = NULL; // unlink two levels below, will
88 				      // delete only exprOp and its
89 				      // argument
90     //delete argument_;
91     //argument_ = NULL;
92     return ret;
93   }
94 
95   // check if this is a -(const)
96   if (argument_ -> Type () == CONST) {
97     expression *ret = new exprConst (- argument_ -> Value ());
98     //delete argument_;
99     //argument_ = NULL;
100     return ret;
101   }
102 
103   return NULL;
104 }
105 
106 // print
print(std::ostream & out,bool descend) const107 void exprOpp::print (std::ostream &out,
108 		       bool descend) const {
109 
110   //if (printPos () == PRE)  out << printOp ();
111   out << "(-";
112   argument_ -> print (out, descend);
113   out << ")";
114   //if (printPos () == POST) out << printOp ();
115 }
116