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

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

Generated on Thu Aug 5 03:02:56 2010 by  doxygen 1.4.7