00001 /* $Id: exprUnary.cpp 230 2009-07-18 11:42:59Z pbelotti $ 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 Common Public License (CPL) 00009 */ 00010 00011 #include "CouenneProblem.hpp" 00012 #include "CouenneTypes.hpp" 00013 #include "exprUnary.hpp" 00014 #include "exprVar.hpp" 00015 #include "exprClone.hpp" 00016 00017 // print unary expression 00018 void exprUnary::print (std::ostream &out, 00019 bool descend) const { 00020 00021 if (printPos () == PRE) out << printOp (); 00022 out << "("; 00023 argument_ -> print (out, descend); 00024 out << ")"; 00025 if (printPos () == POST) out << printOp (); 00026 } 00027 00028 00030 int exprUnary::compare (exprUnary &e1) { 00031 00032 int c0 = code (), 00033 c1 = e1. code (); 00034 00035 if (c0 < c1) return -1; 00036 else if (c0 > c1) return 1; 00037 else // have to compare arguments 00038 return argument_ -> compare (*(e1.argument_)); 00039 } 00040 00041 00042 // Create standard formulation of this expression, by: 00043 // 00044 // - creating auxiliary w variables and corresponding expressions 00045 // - returning linear counterpart as new constraint (to replace 00046 // current one) 00047 exprAux *exprUnary::standardize (CouenneProblem *p, bool addAux) { 00048 00049 exprAux *subst; 00050 00051 if ((subst = argument_ -> standardize (p))) { 00052 if ((subst -> Type () == AUX) || 00053 (subst -> Type () == VAR)) 00054 argument_ = new exprClone (subst); 00055 else argument_ = subst; 00056 } 00057 00058 return (addAux ? (p -> addAuxiliary (this)) : new exprAux (this, p -> domain ())); 00059 } 00060 00061 00063 void exprUnary::replace (exprVar *x, exprVar *w) { 00064 00065 if (argument_ -> Type () == VAR) { 00066 if (argument_ -> Index () == x -> Index ()) { 00067 delete argument_; 00068 argument_ = new exprClone (w); 00069 } 00070 } else argument_ -> replace (x, w); 00071 } 00072 00073 00075 bool exprUnary::isInteger () { 00076 00077 // only check if argument is, *at this point in the algorithm*, 00078 // constant -- due to branching rules, for instance. If so, check if 00079 // the corresponding evaluated expression is integer. 00080 00081 CouNumber al, au; 00082 argument_ -> getBounds (al, au); 00083 00084 if ((al > -COUENNE_INFINITY) && // Funny: if al=-(au=-1.7e308) returns true... 00085 (au < COUENNE_INFINITY) && 00086 fabs (al - au) < COUENNE_EPS) { // argument is constant 00087 00088 register CouNumber fval = (F ()) (al); 00089 00090 // check if f(lb=ub) is integer 00091 if (fabs (COUENNE_round (fval) - fval) < COUENNE_EPS) 00092 return true; 00093 } 00094 00095 return false; 00096 }