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

Go to the documentation of this file.
00001 /* $Id: exprAux.cpp 592 2011-06-01 10:40:25Z pbelotti $
00002  *
00003  * Name:    exprAux.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: methods of the class of auxiliary variables
00006  *
00007  * (C) Carnegie-Mellon University, 2006-10.
00008  * This file is licensed under the Eclipse Public License (EPL)
00009  */
00010 
00011 #include "CouenneExprAux.hpp"
00012 #include "CouenneExprBound.hpp"
00013 #include "CouenneExprMax.hpp"
00014 #include "CouenneExprMin.hpp"
00015 #include "CouenneCutGenerator.hpp"
00016 #include "CouenneComplObject.hpp"
00017 #include "CouenneJournalist.hpp"
00018 
00019 using namespace Couenne;
00020 
00021 namespace Couenne {
00022 class CouenneCutGenerator;
00023 class Domain;
00024 }
00025 
00026 //#define DEBUG
00027 
00028 // auxiliary expression Constructor
00029 exprAux::exprAux (expression *image, int index, int rank, 
00030                   enum intType isInteger, Domain *d,
00031                   enum auxSign sign): 
00032 
00033   exprVar       (index, d),
00034   image_        (image),
00035   rank_         (rank),
00036   multiplicity_ (1),
00037   integer_      (isInteger),
00038   top_level_    (false),
00039   sign_         (sign) {
00040 
00041   // do this later, in standardize()
00042   //  image_ -> getBounds (lb_, ub_);
00043 
00044   //  getBounds (lb_, ub_); // !!!!!!!!
00045 
00046   //  image_ -> getBounds (lb_, ub_);
00047   // getBounds (lb_, ub_);
00048 
00049   //  lb_ = new exprMax (new exprLowerBound (varIndex_), lb_);
00050   //  ub_ = new exprMin (new exprUpperBound (varIndex_), ub_);
00051   lb_ = new exprLowerBound (varIndex_, domain_);
00052   ub_ = new exprUpperBound (varIndex_, domain_);
00053 }
00054 
00055 
00057 exprAux::exprAux (expression *image, Domain *d,
00058                   enum auxSign sign):
00059 
00060   exprVar       (-1, d),
00061   image_        (image),
00062   lb_           (NULL),
00063   ub_           (NULL),
00064   rank_         (-1),
00065   multiplicity_ (0),
00066   integer_      (Unset),
00067   top_level_    (false),
00068   sign_         (sign) {}
00069 //(image -> isInteger () ? Integer : Continuous)
00070 
00071 
00073 exprAux::exprAux (const exprAux &e, Domain *d):
00074   exprVar       (e.varIndex_, d), // variables ? (*variables) [0] -> domain () : NULL),
00075   image_        (e.image_ -> clone (d)),
00076   rank_         (e.rank_),
00077   multiplicity_ (e.multiplicity_),
00078   integer_      (e.integer_),
00079   top_level_    (e.top_level_),
00080   sign_         (e.sign_) {
00081 
00082   //  image_ -> getBounds (lb_, ub_);
00083   // getBounds (lb_, ub_);
00084 
00085   //  lb_ = new exprMax (new exprLowerBound (varIndex_), lb_);
00086   //  ub_ = new exprMin (new exprUpperBound (varIndex_), ub_);
00087 
00088   lb_ = new exprLowerBound (varIndex_, domain_);
00089   ub_ = new exprUpperBound (varIndex_, domain_);
00090 
00091   //crossBounds ();
00092 }
00093 
00094 
00096 exprAux::~exprAux () {
00097   //printf ("deleting %x: ", this);   fflush (stdout); print ();           fflush (stdout);
00098   if (image_) {
00099     //printf (" [%x] ",        image_); fflush (stdout); image_ -> print (); fflush (stdout);
00100     //printf ("\n");
00101     delete image_; 
00102   }
00103   if (lb_) delete lb_;
00104   if (ub_) delete ub_;
00105 }
00106 
00107 
00109 //void exprAux::getBounds (expression *&lb, expression *&ub) {
00110 
00111   // this replaces the previous 
00112   //
00113   //    image_ -> getBounds (lb0, ub0);
00114   //
00115   // which created large expression trees, now useless since all
00116   // auxiliaries are standardized.
00117 
00118   //  lb = lb_ -> clone ();//new exprLowerBound (varIndex_);
00119   //  ub = ub_ -> clone ();//new exprUpperBound (varIndex_);
00120 //  lb = new exprLowerBound (varIndex_, domain_);
00121 //  ub = new exprUpperBound (varIndex_, domain_);
00122 //}
00123 
00124 
00127 void exprAux::crossBounds () {
00128 
00129   expression *l0, *u0;
00130 
00131   image_ -> getBounds (l0, u0);
00132 
00133   //image_ -> getBounds (lb_, ub_);
00134 
00135   if (sign_ != expression::AUX_LEQ) lb_ = new exprMax (lb_, l0);
00136   if (sign_ != expression::AUX_GEQ) ub_ = new exprMin (ub_, u0);
00137 }
00138 
00139 
00141 void exprAux::print (std::ostream &out, bool descend) const {
00142 
00143   if (descend) 
00144     image_ -> print (out, descend);
00145   else {
00146     if (integer_) out << "z_"; // TODO: should be isInteger instead of
00147                                // integer_. Change all "isInteger()"
00148                                // to "isInteger() const"
00149     else          out << "w_";
00150     out << varIndex_;// << "<" << this << ">";
00151   }
00152 }
00153 
00154 
00157 int exprAux::DepList (std::set <int> &deplist, 
00158                       enum dig_type type) {
00159 
00160   if (type == ORIG_ONLY)   
00161     return image_ -> DepList (deplist, type);
00162 
00163   if (deplist.find (varIndex_) == deplist.end ())
00164     deplist.insert (varIndex_); 
00165   else return 0;
00166 
00167   if (type == STOP_AT_AUX) 
00168     return 1;
00169 
00170   return 1 + image_ -> DepList (deplist, type);
00171 }
00172 
00173 
00175 expression *exprAux::simplify () {
00176 
00177   if (((image_ -> Type () == AUX) || 
00178        (image_ -> Type () == VAR)) &&
00179       sign_ == expression::AUX_EQ) {
00180 
00181     --multiplicity_;
00182     expression *ret = image_;
00183     image_ = NULL;
00184     return ret;
00185   }
00186 
00187   return NULL;
00188 }
00189 
00190 
00191 // generate cuts for expression associated with this auxiliary
00192 
00193 void exprAux::generateCuts (OsiCuts &cs, const CouenneCutGenerator *cg, 
00194                             t_chg_bounds *chg, int,
00195                             CouNumber, CouNumber) {
00196   //#ifdef DEBUG
00197   static bool warned_large_coeff = false;
00198   int nrc = cs.sizeRowCuts (), ncc = cs.sizeColCuts ();
00199   //#endif
00200 
00201   /*
00202   if ((!(cg -> isFirst ())) && 
00203       ((l = domain_ -> lb (varIndex_)) > -COUENNE_INFINITY) &&
00204       ((u = domain_ -> ub (varIndex_)) <  COUENNE_INFINITY) &&
00205       (fabs (u-l) < COUENNE_EPS))
00206     cg -> createCut (cs, (l+u)/2., 0, varIndex_, 1.);
00207   else 
00208   */
00209   image_ -> generateCuts (this, /*si,*/ cs, cg, chg);
00210 
00211   // check if cuts have coefficients, rhs too large or too small
00212 
00213   //#ifdef DEBUG
00214 
00215   if (cg -> Jnlst () -> ProduceOutput (Ipopt::J_DETAILED, J_CONVEXIFYING)) {
00216     if (cg -> Jnlst () -> ProduceOutput (Ipopt::J_STRONGWARNING, J_CONVEXIFYING) && 
00217         (warned_large_coeff)) {
00218       for (int jj=nrc; jj < cs.sizeRowCuts (); jj++) {
00219 
00220         OsiRowCut        *cut = cs.rowCutPtr (jj);
00221         CoinPackedVector  row = cut -> row ();
00222 
00223         int           n   = cut -> row (). getNumElements();
00224         const double *el  = row. getElements ();
00225         const int    *ind = row. getIndices ();
00226         double        rhs = cut -> rhs ();
00227 
00228         while (n--) {
00229           if (fabs (el [n]) > COU_MAX_COEFF)  {
00230             printf ("Couenne, warning: coefficient too large %g x%d: ", el [n], ind [n]);
00231             cut -> print (); 
00232             warned_large_coeff = true;
00233             break;
00234           }
00235 
00236           if (fabs (rhs) > COU_MAX_COEFF) {
00237             printf ("Couenne, warning: rhs too large (%g): ", rhs);
00238             cut -> print ();
00239             warned_large_coeff = true;
00240             break;
00241           }
00242         }
00243       }
00244     }
00245 
00246     //  if (!(cg -> isFirst ())) 
00247     if ((nrc < cs.sizeRowCuts ()) || 
00248         (ncc < cs.sizeColCuts ()))
00249       {
00250         printf ("---------------- ConvCut:  "); 
00251         print (std::cout);  
00252         printf (" %c= ", 
00253                 sign () == expression::AUX_EQ  ? ':' : 
00254                 sign () == expression::AUX_LEQ ? '<' : '>');
00255         image_ -> print (std::cout); 
00256 
00257         printf (" %g [%g,%g]. ", 
00258                 domain_ -> x  (varIndex_), 
00259                 domain_ -> lb (varIndex_), 
00260                 domain_ -> ub (varIndex_));
00261 
00262         int index;
00263         if ((image_ -> Argument ()) && 
00264             ((index = image_ -> Argument () -> Index ()) >= 0))
00265           printf ("%g [%g,%g] ",
00266                   domain_ -> x  (index),
00267                   domain_ -> lb (index),
00268                   domain_ -> ub (index));
00269         else if (image_ -> ArgList ())
00270           for (int i=0; i<image_ -> nArgs (); i++)
00271             if ((index = image_ -> ArgList () [i] -> Index ()) >= 0)
00272               printf ("%g [%g,%g] ", 
00273                       domain_ -> x  (index),
00274                       domain_ -> lb (index), 
00275                       domain_ -> ub (index));
00276         printf ("\n");
00277 
00278         for (int jj = nrc; jj < cs.sizeRowCuts (); jj++) cs.rowCutPtr (jj) -> print ();
00279         for (int jj = ncc; jj < cs.sizeColCuts (); jj++) cs.colCutPtr (jj) -> print ();
00280       }
00281   }
00282     //#endif
00283 
00285 
00286 #if 0
00287   draw_cuts (cs, cg, nrc, this, image_);
00288 #endif
00289 }
00290 
00291 
00294 CouenneObject *exprAux::properObject (CouenneCutGenerator *c,
00295                                       CouenneProblem *p, 
00296                                       Bonmin::BabSetupBase *base, 
00297                                       JnlstPtr jnlst) {
00298 
00299   // todo: this is an expression method
00300 
00301   // create Complementary objects for variable if: 
00302 
00303   if ((image_ -> code () == COU_EXPRMUL) &&          // it's a product x3 = x1 x2
00304 
00305       (image_ -> ArgList () [0] -> Index () >= 0) && // first  operand is a variable
00306       (image_ -> ArgList () [1] -> Index () >= 0) && // second operand is a variable
00307 
00308       (  
00309        ((fabs (lb ()) <  COUENNE_EPS)      && (fabs (ub ()) < COUENNE_EPS)) // it's defined as x1 x2 = 0
00310        ||                                                                   // OR
00311        (top_level_  &&                                                      // x3 is the lhs of a constraint
00312         ((((fabs (lb ()) <  COUENNE_EPS)      && (      ub ()  > COUENNE_INFINITY)) || // and (x1 x2 >= 0
00313           ((      lb ()  < -COUENNE_INFINITY) && (fabs (ub ()) < COUENNE_EPS )))))     // or   x1 x2 <= 0)
00314          )
00315       ) {
00316 
00317     // it's a complementarity constraint object!
00318 
00319     // generalizing: now a complementarity constraint object is any
00320     // constraint of the form
00321     //
00322     // x_i * x_j >= 0 or
00323     // x_i * x_j <= 0 or
00324     // x_i * x_j  = 0
00325     //
00326     // In fact, for all these cases branching is as straightforward as
00327     // the old one, which was defined on equality only.
00328     //
00329     // Define the "sign" of the object as 
00330     //
00331     // -1: <=
00332     // +1: >=
00333     //  0:  =
00334 
00335     return new CouenneComplObject (c, p, this, base, jnlst,
00336                                    lb () < -1 ? -1 : 
00337                                    ub () >  1 ?  1 : 0);
00338   }
00339   else
00340     return new CouenneObject (c, p, this, base, jnlst);
00341 }

Generated on Thu Nov 10 03:05:44 2011 by  doxygen 1.4.7