/home/coin/SVN-release/OS-2.4.2/Couenne/src/expression/exprOp.cpp

Go to the documentation of this file.
00001 /* $Id: exprOp.cpp 506 2011-02-15 14:36:48Z stefan $
00002  *
00003  * Name:    exprOp.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: methods for multivariate function class
00006  *
00007  * (C) Carnegie-Mellon University, 2006-08.
00008  * This file is licensed under the Eclipse Public License (EPL)
00009  */
00010 
00011 #include "CouenneExpression.hpp"
00012 #include "CouenneExprAux.hpp"
00013 #include "CouenneExprClone.hpp"
00014 #include "CouenneExprOp.hpp"
00015 #include "CouenneExprGroup.hpp"
00016 #include "CouenneExprQuad.hpp"
00017 
00018 #include <cstdio>
00019 
00020 using namespace Couenne;
00021 
00022 namespace Couenne {
00023 class CouenneProblem;
00024 class Domain;
00025 }
00026 
00027 // General N-ary function destructor
00028 exprOp::~exprOp () {
00029 
00030   if (arglist_) {
00031     for (expression **alist = arglist_; nargs_--; alist++)
00032       if (*alist) delete (*alist);
00033     delete [] arglist_;
00034   }
00035 }
00036 
00037 
00038 // print expression
00039 
00040 void exprOp::print (std::ostream &out, 
00041                     bool descend) const {
00042   
00043   if (printPos () == PRE)
00044     out << printOp ();
00045 
00046   if (nargs_ > 1)
00047     {out << "("; fflush (stdout);}
00048   for (int i=0; i<nargs_; i++) {
00049     if (arglist_ [i])
00050       arglist_ [i] -> print (out, descend); 
00051     fflush (stdout);
00052     if (i < nargs_ - 1) {
00053       if (printPos () == INSIDE) out << printOp ();
00054       else                       out << ",";
00055     }
00056     if (!((i + 1) % MAX_ARG_LINE))
00057       out << std::endl;
00058     fflush (stdout);
00059   }
00060   if (nargs_ > 1) {
00061     out << ")";
00062     fflush (stdout);
00063   }
00064 }
00065 
00066 
00068 
00069 int exprOp::compare (exprOp &e1) {
00070 
00071   int c0 =     code (),
00072       c1 = e1. code ();
00073 
00074   if (c0 < c1) return -1;
00075   if (c0 > c1) return  1;
00076 
00077   // have to compare arguments one by one
00078   if (nargs_ < e1.nargs_) return -1;
00079   if (nargs_ > e1.nargs_) return  1;
00080 
00081   // not an exprGroup, compare arguments
00082   for (register int i = nargs_; i--;) {
00083 
00084     int res = arglist_ [i] -> compare (*(e1. ArgList () [i]));
00085     if (res) return res;
00086   }
00087 
00088   // last chance, this might be an exprGroup or derived
00089   if ((c0 == COU_EXPRGROUP) ||
00090       (c0 == COU_EXPRQUAD)) {
00091 
00092     exprGroup *ne0 = dynamic_cast <exprGroup *> (this),
00093               *ne1 = dynamic_cast <exprGroup *> (&e1);
00094 
00095     int cg = ne0 -> compare (*ne1);
00096 
00097     if (cg) return cg; // exprGroup
00098 
00099     // last chance, the two are quadratic forms
00100 
00101     if (c0 == COU_EXPRQUAD) {
00102 
00103       exprQuad *ne0 = dynamic_cast <exprQuad *> (this),
00104                *ne1 = dynamic_cast <exprQuad *> (&e1);
00105 
00106       return ne0 -> compare (*ne1);
00107     }
00108   }
00109 
00110   return 0;
00111 }
00112 
00113 
00115 
00116 int exprOp::rank () {
00117 
00118   int maxrank = -1;
00119 
00120   for (expression **al = arglist_ + nargs_; 
00121        al-- > arglist_;) {
00122     int r = (*al) -> rank ();
00123     if (r > maxrank) maxrank = r;
00124   }
00125 
00126   return (maxrank);
00127 }
00128 
00129 
00130 // Create standard formulation of this expression, by:
00131 //
00132 // - creating auxiliary w variables and corresponding expressions
00133 // - returning linear counterpart as new constraint (to replace 
00134 //   current one)
00135 //
00136 // For the base exprOp class we only do the first part (for argument
00137 // list components only), and the calling class (Sum, Sub, Mul, Pow,
00138 // and the like) will do the part for its own object
00139 
00140 exprAux *exprOp::standardize (CouenneProblem *p, bool addAux) {
00141 
00142   exprVar *subst;
00143 
00144   for (int i = nargs_; i--;)
00145     if ((subst = arglist_ [i] -> standardize (p))) {
00146       if ((subst -> Type () == VAR) ||
00147           (subst -> Type () == AUX))
00148         arglist_ [i]    = new exprClone (subst);
00149       else arglist_ [i] = subst;
00150     }
00151   return NULL;
00152 }
00153 
00154 
00156 void exprOp::replace (exprVar *x, exprVar *w) {
00157 
00158   expression **al = arglist_;
00159   int index = x -> Index ();
00160 
00161   for (register int i = nargs_; i--; al++)
00162 
00163     switch ((*al) -> Type ()) {
00164 
00165     case AUX:
00166     case VAR:
00167       if ((*al) -> Index () == index) {
00168         delete *al;
00169         *al = new exprClone (w);
00170       }
00171       break;
00172 
00173     case UNARY:
00174     case N_ARY:
00175       (*al) -> replace (x, w);
00176       break;
00177 
00178     default:
00179       break;
00180     }
00181 }
00182 
00183 
00185 bool exprOp::isInteger () {
00186 
00187   for (int i = nargs_; i--;)
00188 
00189     if (!(arglist_ [i] -> isInteger ())) { 
00190 
00191       // this argument is not integer: check if constant and integer
00192 
00193       CouNumber lb, ub;
00194       arglist_ [i] -> getBounds (lb, ub);
00195 
00196       if ((fabs (lb - ub) > COUENNE_EPS) ||
00197           !::isInteger (lb))
00198         return false;
00199     }
00200 
00201   return true;
00202 }
00203 
00204 
00207 int exprOp::DepList (std::set <int> &deplist, 
00208                      enum dig_type type) {
00209   int tot = 0;
00210 
00211   //printf ("  exprop::deplist of %x: ", Original ()); print (); printf ("\n");
00212 
00213   for (int i = nargs_; i--;) {
00214 
00215     /*printf ("  ");
00216     arglist_ [i] -> print (); printf (": {");
00217     for (std::set <int>::iterator j=deplist.begin(); j != deplist.end(); ++j)
00218       printf ("%d ", *j);
00219       printf ("} -> {");*/
00220 
00221     tot += arglist_ [i] -> DepList (deplist, type);
00222 
00223     /*for (std::set <int>::iterator j=deplist.begin(); j != deplist.end(); ++j)
00224       printf ("%d ", *j);
00225       printf ("}\n");*/
00226   }
00227 
00228   return tot;
00229 }
00230 
00232 void exprOp::realign (const CouenneProblem *p) {
00233 
00234   for (int i=0; i<nargs_; i++)
00235     arglist_ [i] -> realign (p);
00236 }

Generated on Wed Nov 30 03:04:02 2011 by  doxygen 1.4.7