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

Go to the documentation of this file.
00001 /* $Id: expression.cpp 217 2009-07-08 17:02:07Z 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 Common Public License (CPL)
00009  */
00010 
00011 #include "CouenneCutGenerator.hpp"
00012 #include "CouenneProblem.hpp"
00013 
00014 #include "CouenneTypes.hpp"
00015 #include "expression.hpp"
00016 #include "exprClone.hpp"
00017 #include "exprAux.hpp"
00018 #include "exprOp.hpp"
00019 #include "exprUnary.hpp"
00020 #include "exprStore.hpp"
00021 
00022 
00023 // empty differentiation method
00024 expression *expression::differentiate (int)
00025 {return new exprConst (0.);}
00026 
00027 
00028 // Get lower and upper bound of a generic expression
00029 void expression::getBounds (expression *&lb, expression *&ub) {
00030 
00031   lb = new exprConst (- COIN_DBL_MAX);
00032   ub = new exprConst (  COIN_DBL_MAX);
00033 }
00034 
00035 
00037 void expression::getBounds (CouNumber &lb, CouNumber &ub) {
00038 
00039   expression *le, *ue;
00040   getBounds (le, ue);
00041 
00042   lb = (*le) ();
00043   ub = (*ue) ();
00044 
00045   delete le;
00046   delete ue;
00047 }
00048 
00049 
00050 // generate one cut for a constant
00051 void exprConst::generateCuts (expression *w, //const OsiSolverInterface &si, 
00052                               OsiCuts &cs, const CouenneCutGenerator *cg, 
00053                               t_chg_bounds *chg, int,
00054                               CouNumber, CouNumber) {
00055   if (cg -> isFirst ())
00056     cg -> createCut (cs, value_, 0, w -> Index (), 1.);
00057 }
00058 
00059 
00061 int expression::compare (expression &e1) {
00062 
00063   register int c0 =     code (),
00064                c1 = e1. code ();
00065 
00066   if      (c0 < c1) return -1;
00067   else if (c0 > c1) return  1;
00068 
00069   // same code, check arguments
00070 
00071   if (c0 >= COU_EXPRUNARY) { // both are exprUnary's
00072 
00073     exprUnary *ne0 = dynamic_cast <exprUnary *> (this);
00074     exprUnary *ne1 = dynamic_cast <exprUnary *> (&e1);
00075 
00076     return ne0 -> compare (*ne1);
00077   }
00078 
00079   if (c0 >= COU_EXPROP) { // both are exprOp's
00080 
00081     exprOp *ne0 = dynamic_cast <exprOp *> (this);
00082     exprOp *ne1 = dynamic_cast <exprOp *> (&e1);
00083 
00084     return ne0 -> compare (*ne1);
00085   }
00086 
00087   // expressions are both variables or constants
00088 
00089   {
00090     register int 
00091       i0 =     Index (),
00092       i1 = e1. Index ();
00093 
00094     if (i0 < i1) return -1;
00095     if (i0 > i1) return  1;
00096     if (i0 >= 0) return  0; // same variables
00097   }
00098 
00099   // both are numbers
00100   {
00101     register CouNumber 
00102       v0 =     Value (), 
00103       v1 = e1. Value ();
00104 
00105     if (v0 < v1) return -1;
00106     if (v0 > v1) return  1;
00107   }
00108 
00109   return  0;
00110 }
00111 
00112 
00114 exprCopy::exprCopy (const exprCopy &e, Domain *d) {
00115 
00116   //expression *copy = getOriginal (e.copy_);
00117 
00118   //if ((copy -> Type () == VAR) ||
00119   //    (copy -> Type () == AUX))  
00120 
00121     // if this is a variable, don't copy, just refer to the same
00122     // object (otherwise many useless copies are created)
00123 
00124     //  copy_ = copy;// -> clone (d);
00125   //else copy_ = copy -> clone (d);
00126 
00127   copy_ = e.copy_ -> Original () -> clone (d); // !!! REMOVE " -> Original ()"
00128   //else copy_ = e.copy_ -> clone (d);
00129 
00130   value_ = e.value_;
00131 }
00132 
00133 
00135 int expression::compare (exprCopy &c)
00136 {return compare (const_cast <expression &> (*(c. Original ())));}
00137 
00138 
00140 void exprCopy::replace (exprVar *orig, exprVar *aux) {
00141 
00142   if (!aux) 
00143     aux = orig;
00144 
00145   enum nodeType copyType = copy_ -> Type ();
00146 
00147   if ((copyType == VAR) || 
00148       (copyType == AUX)) {
00149 
00150     if (copy_ -> Index () == orig -> Index ()) {
00151       if (copy_ -> isaCopy ())  // !!! REMOVE
00152         delete copy_;           // !!! REMOVE
00153       copy_ = aux;
00154     }
00155 
00156   } else copy_ -> replace (orig, aux);
00157 
00158   //copy_ -> replace (orig, aux);
00159 
00160   /*if ((copy_ -> Index () == orig -> Index ()) && (copy_ -> Type  () != AUX)) {
00161     delete copy_;
00162     copy_ = new exprClone (aux);
00163     }*/
00164 }
00165 
00166 
00169 int expression::dependsOn (int *ind, int n, enum dig_type type) {
00170 
00171   std::set <int> 
00172     indlist (ind, ind + n), 
00173     deplist,
00174     intersectn;
00175 
00176   /*printf (":::::: indlist = {");
00177   for (std::set <int>::iterator i=indlist.begin (); i != indlist.end(); ++i)
00178     printf ("%d ", *i);
00179     printf ("} -- deplist = {");*/
00180 
00181   DepList (deplist, type);
00182 
00183   /*for (std::set <int>::iterator i=deplist.begin (); i != deplist.end(); ++i)
00184     printf ("%d ", *i);
00185     printf ("} -- intersection = {");*/
00186 
00187   std::set_intersection (indlist .begin (), indlist .end (), 
00188                          deplist .begin (), deplist .end (),
00189                          std::inserter (intersectn, intersectn.begin ()));
00190 
00191   /*for (std::set <int>::iterator i=intersectn.begin (); i != intersectn.end(); ++i)
00192     printf ("%d ", *i);
00193     printf ("}\n");*/
00194 
00195   return intersectn.size();
00196 }
00197 
00198 
00200 void exprCopy::realign (const CouenneProblem *p) {
00201 
00202   if (((copy_ -> Type () == VAR) ||  
00203        (copy_ -> Type () == AUX)) &&
00204       (copy_ -> Original () != p -> Var (copy_ -> Index ()))) {
00205 
00206     /*printf ("exprCopy::realign replaces %x with %x (", 
00207             copy_ -> Original (), p -> Var (copy_ -> Index ())); 
00208     copy_ -> Original () -> print (); printf (" - ");
00209     p -> Var (copy_ -> Index ()) -> print (); printf ("\n");*/
00210 
00211     expression *trash = copy_;
00212 
00213     copy_ = p -> Var (copy_ -> Index ());
00214     delete trash;
00215   }
00216 }
00217 
00218 
00219 // /// redirect variables to proper variable vector
00220 // void exprClone::realign (const CouenneProblem *p) {
00221 
00222 //   if (((copy_ -> Type () == VAR) ||  
00223 //        (copy_ -> Type () == AUX)) &&
00224 //       (copy_ -> Original () != p -> Var (copy_ -> Index ()))) {
00225 
00226 //     expression *trash = copy_;
00227 
00228 //     copy_ = p -> Var (copy_ -> Index ());
00229 //     printf ("deleting "); trash -> print (); printf ("\n");
00230 //     delete trash;
00231 //   } else {printf ("not deleted "); print (); printf ("\n");}
00232 // }
00233 
00234 
00236 void expression::closestFeasible (expression *varind, expression *vardep,
00237                                   CouNumber& left, CouNumber& right) const
00238 {
00239   assert(isBijective());
00240   CouNumber inv = inverse(vardep);
00241   CouNumber curr = (*varind) ();
00242   if (curr > inv) {
00243     left  = inv;
00244     right = curr;
00245   }
00246   else {
00247     left  = curr;
00248     right = inv;
00249   }
00250 }

Generated on Tue Mar 30 03:04:37 2010 by  doxygen 1.4.7