00001 /* $Id: exprUnary.cpp 851 2012-06-07 10:51:58Z stefan $ 00002 * 00003 * Name: exprUnary.cpp 00004 * Author: Pietro Belotti 00005 * Purpose: methods of the unary expression class 00006 * 00007 * (C) Carnegie-Mellon University, 2006-2009. 00008 * This file is licensed under the Eclipse Public License (EPL) 00009 */ 00010 00011 #include "CouenneProblem.hpp" 00012 #include "CouenneTypes.hpp" 00013 #include "CouenneExprUnary.hpp" 00014 #include "CouenneExprVar.hpp" 00015 #include "CouenneExprAux.hpp" 00016 #include "CouenneExprClone.hpp" 00017 00018 using namespace Couenne; 00019 00020 // print unary expression 00021 void exprUnary::print (std::ostream &out, 00022 bool descend) const { 00023 00024 if (printPos () == PRE) out << printOp (); 00025 out << "("; 00026 argument_ -> print (out, descend); 00027 out << ")"; 00028 if (printPos () == POST) out << printOp (); 00029 } 00030 00031 00033 int exprUnary::compare (exprUnary &e1) { 00034 00035 int c0 = code (), 00036 c1 = e1. code (); 00037 00038 if (c0 < c1) return -1; 00039 else if (c0 > c1) return 1; 00040 else // have to compare arguments 00041 return argument_ -> compare (*(e1.argument_)); 00042 } 00043 00044 00045 // Create standard formulation of this expression, by: 00046 // 00047 // - creating auxiliary w variables and corresponding expressions 00048 // - returning linear counterpart as new constraint (to replace 00049 // current one) 00050 exprAux *exprUnary::standardize (CouenneProblem *p, bool addAux) { 00051 00052 exprAux *subst; 00053 00054 if ((subst = argument_ -> standardize (p))) { 00055 00056 if ((subst -> Type () == AUX) || 00057 (subst -> Type () == VAR)) 00058 argument_ = new exprClone (subst); 00059 else argument_ = subst; 00060 } 00061 00062 return (addAux ? (p -> addAuxiliary (this)) : new exprAux (this, p -> domain ())); 00063 } 00064 00065 00067 void exprUnary::replace (exprVar *x, exprVar *w) { 00068 00069 if (argument_ -> Type () == VAR) { 00070 if (argument_ -> Index () == x -> Index ()) { 00071 delete argument_; 00072 argument_ = new exprClone (w); 00073 } 00074 } else argument_ -> replace (x, w); 00075 } 00076 00077 00079 bool exprUnary::isInteger () { 00080 00081 // only check if argument is, *at this point in the algorithm*, 00082 // constant -- due to branching rules, for instance. If so, check if 00083 // the corresponding evaluated expression is integer. 00084 00085 CouNumber al, au; 00086 argument_ -> getBounds (al, au); 00087 00088 if ((al > -COUENNE_INFINITY) && // Funny: if al=-(au=-1.7e308) returns true... 00089 (au < COUENNE_INFINITY) && 00090 fabs (al - au) < COUENNE_EPS) { // argument is constant 00091 00092 register CouNumber fval = (F ()) (al); 00093 00094 // check if f(lb=ub) is integer 00095 if (fabs (COUENNE_round (fval) - fval) < COUENNE_EPS) 00096 return true; 00097 } 00098 00099 return false; 00100 }