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

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

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