00001 /* $Id: exprUnary.cpp 490 2011-01-14 16:07:12Z 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 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 if ((subst -> Type () == AUX) || 00056 (subst -> Type () == VAR)) 00057 argument_ = new exprClone (subst); 00058 else argument_ = subst; 00059 } 00060 00061 return (addAux ? (p -> addAuxiliary (this)) : new exprAux (this, p -> domain ())); 00062 } 00063 00064 00066 void exprUnary::replace (exprVar *x, exprVar *w) { 00067 00068 if (argument_ -> Type () == VAR) { 00069 if (argument_ -> Index () == x -> Index ()) { 00070 delete argument_; 00071 argument_ = new exprClone (w); 00072 } 00073 } else argument_ -> replace (x, w); 00074 } 00075 00076 00078 bool exprUnary::isInteger () { 00079 00080 // only check if argument is, *at this point in the algorithm*, 00081 // constant -- due to branching rules, for instance. If so, check if 00082 // the corresponding evaluated expression is integer. 00083 00084 CouNumber al, au; 00085 argument_ -> getBounds (al, au); 00086 00087 if ((al > -COUENNE_INFINITY) && // Funny: if al=-(au=-1.7e308) returns true... 00088 (au < COUENNE_INFINITY) && 00089 fabs (al - au) < COUENNE_EPS) { // argument is constant 00090 00091 register CouNumber fval = (F ()) (al); 00092 00093 // check if f(lb=ub) is integer 00094 if (fabs (COUENNE_round (fval) - fval) < COUENNE_EPS) 00095 return true; 00096 } 00097 00098 return false; 00099 }