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

Go to the documentation of this file.
00001 /* $Id: expression.cpp 645 2011-06-14 10:04:49Z pbelotti $
00002  *
00003  * Name:    expression.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: methods of the expression class
00006  *
00007  * (C) Carnegie-Mellon University, 2006-09.
00008  * This file is licensed under the Eclipse Public License (EPL)
00009  */
00010 
00011 #include <iostream>
00012 
00013 #include "CouenneCutGenerator.hpp"
00014 #include "CouenneProblem.hpp"
00015 
00016 #include "CouenneTypes.hpp"
00017 #include "CouenneExpression.hpp"
00018 #include "CouenneExprClone.hpp"
00019 #include "CouenneExprAux.hpp"
00020 #include "CouenneExprOp.hpp"
00021 #include "CouenneExprUnary.hpp"
00022 #include "CouenneExprStore.hpp"
00023 
00024 using namespace Couenne;
00025 
00026 // empty differentiation method
00027 expression *expression::differentiate (int)
00028 {return new exprConst (0.);}
00029 
00030 
00031 // Get lower and upper bound of a generic expression
00032 void expression::getBounds (expression *&lb, expression *&ub) {
00033 
00034   lb = new exprConst (- COIN_DBL_MAX);
00035   ub = new exprConst (  COIN_DBL_MAX);
00036 }
00037 
00038 
00040 void expression::getBounds (CouNumber &lb, CouNumber &ub) {
00041 
00042   expression *le, *ue;
00043   getBounds (le, ue);
00044 
00045   lb = (*le) ();
00046   ub = (*ue) ();
00047 
00048   delete le;
00049   delete ue;
00050 }
00051 
00052 
00053 // generate one cut for a constant
00054 void exprConst::generateCuts (expression *w, //const OsiSolverInterface &si, 
00055                               OsiCuts &cs, const CouenneCutGenerator *cg, 
00056                               t_chg_bounds *chg, int,
00057                               CouNumber, CouNumber) {
00058   if (cg -> isFirst ())
00059     cg -> createCut (cs, value_, 0, w -> Index (), 1.);
00060 }
00061 
00062 
00064 int expression::compare (expression &e1) {
00065 
00066   register int c0 =     code (),
00067                c1 = e1. code ();
00068 
00069   if      (c0 < c1) return -1;
00070   else if (c0 > c1) return  1;
00071 
00072   // same code, check arguments
00073 
00074   if (c0 >= COU_EXPRUNARY) { // both are exprUnary's
00075 
00076     exprUnary *ne0 = dynamic_cast <exprUnary *> (this);
00077     exprUnary *ne1 = dynamic_cast <exprUnary *> (&e1);
00078 
00079     return ne0 -> compare (*ne1);
00080   }
00081 
00082   if (c0 >= COU_EXPROP) { // both are exprOp's
00083 
00084     exprOp *ne0 = dynamic_cast <exprOp *> (this);
00085     exprOp *ne1 = dynamic_cast <exprOp *> (&e1);
00086 
00087     return ne0 -> compare (*ne1);
00088   }
00089 
00090   // expressions are both variables or constants
00091 
00092   {
00093     register int 
00094       i0 =     Index (),
00095       i1 = e1. Index ();
00096 
00097     if (i0 < i1) return -1;
00098     if (i0 > i1) return  1;
00099     if (i0 >= 0) return  0; // same variables
00100   }
00101 
00102   // both are numbers
00103   {
00104     register CouNumber 
00105       v0 =     Value (), 
00106       v1 = e1. Value ();
00107 
00108     if (v0 < v1) return -1;
00109     if (v0 > v1) return  1;
00110   }
00111 
00112   return  0;
00113 }
00114 
00115 
00117 exprCopy::exprCopy (const exprCopy &e, Domain *d) {
00118 
00119   //expression *copy = getOriginal (e.copy_);
00120 
00121   //if ((copy -> Type () == VAR) ||
00122   //    (copy -> Type () == AUX))  
00123 
00124     // if this is a variable, don't copy, just refer to the same
00125     // object (otherwise many useless copies are created)
00126 
00127     //  copy_ = copy;// -> clone (d);
00128   //else copy_ = copy -> clone (d);
00129 
00130   copy_ = e.copy_ -> Original () -> clone (d); // !!! REMOVE " -> Original ()"
00131   //else copy_ = e.copy_ -> clone (d);
00132 
00133   value_ = e.value_;
00134 }
00135 
00136 
00138 int expression::compare (exprCopy &c)
00139 {return compare (const_cast <expression &> (*(c. Original ())));}
00140 
00141 
00143 void exprCopy::replace (exprVar *orig, exprVar *aux) {
00144 
00145   if (!aux) 
00146     aux = orig;
00147 
00148   enum nodeType copyType = copy_ -> Type ();
00149 
00150   if ((copyType == VAR) || 
00151       (copyType == AUX)) {
00152 
00153     if (copy_ -> Index () == orig -> Index ()) {
00154       if (copy_ -> isaCopy ())  // !!! REMOVE
00155         delete copy_;           // !!! REMOVE
00156       copy_ = aux;
00157     }
00158 
00159   } else copy_ -> replace (orig, aux);
00160 
00161   //copy_ -> replace (orig, aux);
00162 
00163   /*if ((copy_ -> Index () == orig -> Index ()) && (copy_ -> Type  () != AUX)) {
00164     delete copy_;
00165     copy_ = new exprClone (aux);
00166     }*/
00167 }
00168 
00169 
00172 int expression::dependsOn (int *ind, int n, enum dig_type type) {
00173 
00174   std::set <int> 
00175     indlist (ind, ind + n), 
00176     deplist;
00177   //intersectn;
00178 
00179   /*printf (":::::: indlist = {");
00180   for (std::set <int>::iterator i=indlist.begin (); i != indlist.end(); ++i)
00181     printf ("%d ", *i);
00182     printf ("} -- deplist = {");*/
00183 
00184   DepList (deplist, type);
00185 
00186   /*for (std::set <int>::iterator i=deplist.begin (); i != deplist.end(); ++i)
00187     printf ("%d ", *i);
00188     printf ("} -- intersection: \n");*/
00189 
00190   for (std::set <int>::iterator 
00191          i = deplist.begin (), 
00192          j = indlist.begin ();
00193        (i != deplist.end ()) && 
00194          (j != indlist.end ());) {
00195 
00196     if (*i == *j) return 1;
00197 
00198     if (*i > *j) ++j;
00199     else         ++i;
00200   }
00201 
00202   return 0;
00203 }
00204 
00205 
00207 void exprCopy::realign (const CouenneProblem *p) {
00208 
00209   if (((copy_ -> Type () == VAR) ||  
00210        (copy_ -> Type () == AUX)) &&
00211       (copy_ -> Original () != p -> Var (copy_ -> Index ()))) {
00212 
00213     /*printf ("exprCopy::realign replaces %x with %x (", 
00214             copy_ -> Original (), p -> Var (copy_ -> Index ())); 
00215     copy_ -> Original () -> print (); printf (" --> ");
00216     p -> Var (copy_ -> Index ()) -> print (); printf (")\n");*/
00217 
00218     expression *trash = copy_;
00219 
00220     copy_ = p -> Var (copy_ -> Index ());
00221     delete trash;
00222   } else copy_ -> realign (p);
00223 }
00224 
00226 void exprCopy::print (std::ostream &out, bool descend) const
00227 {copy_ -> Original () -> print (out, descend);}
00228 //{out << "["; copy_ -> print (out, descend); out << "]<" << copy_ << ">"; } // Must go
00229 
00230 
00232 void exprClone::print (std::ostream &out, bool descend) const
00233 {copy_ -> Original () -> print (out, descend);}
00234 //{out << "{"; copy_ -> print (out, descend); out << "}<" << copy_ << ">"; } // Must go
00235 
00236 
00238 void exprStore::print (std::ostream &out, bool descend) const
00239 {copy_ -> Original () -> print (out, descend);}
00240 //{out << "<"; copy_ -> print (out, descend); out << "><" << copy_ << ">"; }
00241 
00242 
00243 // /// redirect variables to proper variable vector
00244 // void exprClone::realign (const CouenneProblem *p) {
00245 
00246 //   if (((copy_ -> Type () == VAR) ||  
00247 //        (copy_ -> Type () == AUX)) &&
00248 //       (copy_ -> Original () != p -> Var (copy_ -> Index ()))) {
00249 
00250 //     expression *trash = copy_;
00251 
00252 //     copy_ = p -> Var (copy_ -> Index ());
00253 //     printf ("deleting "); trash -> print (); printf ("\n");
00254 //     delete trash;
00255 //   } else {printf ("not deleted "); print (); printf ("\n");}
00256 // }
00257 
00258 
00260 void expression::closestFeasible (expression *varind, expression *vardep,
00261                                   CouNumber& left, CouNumber& right) const
00262 {
00263   assert(isBijective());
00264   CouNumber inv = inverse(vardep);
00265   CouNumber curr = (*varind) ();
00266   if (curr > inv) {
00267     left  = inv;
00268     right = curr;
00269   }
00270   else {
00271     left  = curr;
00272     right = inv;
00273   }
00274 }

Generated on Thu Sep 22 03:05:57 2011 by  doxygen 1.4.7