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

Go to the documentation of this file.
00001 /* $Id: exprAux.cpp 156 2009-06-16 20:24:38Z 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-08. 
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 
00033   // do this later, in standardize()
00034   //  image_ -> getBounds (lb_, ub_);
00035 
00036   //  getBounds (lb_, ub_); // !!!!!!!!
00037 
00038   //  image_ -> getBounds (lb_, ub_);
00039   // getBounds (lb_, ub_);
00040 
00041   //  lb_ = new exprMax (new exprLowerBound (varIndex_), lb_);
00042   //  ub_ = new exprMin (new exprUpperBound (varIndex_), ub_);
00043   lb_ = new exprLowerBound (varIndex_, domain_);
00044   ub_ = new exprUpperBound (varIndex_, domain_);
00045 }
00046 
00047 
00049 exprAux::exprAux (expression *image, Domain *d):
00050 
00051   exprVar       (-1, d),
00052   image_        (image),
00053   lb_           (NULL),
00054   ub_           (NULL),
00055   rank_         (-1),
00056   multiplicity_ (0),
00057   integer_      (Unset) {}
00058 //(image -> isInteger () ? Integer : Continuous)
00059 
00060 
00062 exprAux::exprAux (const exprAux &e, Domain *d):
00063   exprVar       (e.varIndex_, d), // variables ? (*variables) [0] -> domain () : NULL),
00064   image_        (e.image_ -> clone (d)),
00065   rank_         (e.rank_),
00066   multiplicity_ (e.multiplicity_),
00067   integer_      (e.integer_) {
00068 
00069   //  image_ -> getBounds (lb_, ub_);
00070   // getBounds (lb_, ub_);
00071 
00072   //  lb_ = new exprMax (new exprLowerBound (varIndex_), lb_);
00073   //  ub_ = new exprMin (new exprUpperBound (varIndex_), ub_);
00074 
00075   lb_ = new exprLowerBound (varIndex_, domain_);
00076   ub_ = new exprUpperBound (varIndex_, domain_);
00077 
00078   //crossBounds ();
00079 }
00080 
00081 
00083 exprAux::~exprAux () {
00084   if (image_) {
00085     //printf ("deleting %x: ", this);   fflush (stdout); print ();           fflush (stdout);
00086     //printf (" [%x] ",        image_); fflush (stdout); image_ -> print (); fflush (stdout);
00087     //printf ("\n");
00088     delete image_; 
00089   }
00090   if (lb_)    delete lb_;
00091   if (ub_)    delete ub_;
00092 }
00093 
00094 
00096 //void exprAux::getBounds (expression *&lb, expression *&ub) {
00097 
00098   // this replaces the previous 
00099   //
00100   //    image_ -> getBounds (lb0, ub0);
00101   //
00102   // which created large expression trees, now useless since all
00103   // auxiliaries are standardized.
00104 
00105   //  lb = lb_ -> clone ();//new exprLowerBound (varIndex_);
00106   //  ub = ub_ -> clone ();//new exprUpperBound (varIndex_);
00107 //  lb = new exprLowerBound (varIndex_, domain_);
00108 //  ub = new exprUpperBound (varIndex_, domain_);
00109 //}
00110 
00111 
00114 void exprAux::crossBounds () {
00115 
00116   expression *l0, *u0;
00117 
00118   image_ -> getBounds (l0, u0);
00119 
00120   //image_ -> getBounds (lb_, ub_);
00121 
00122   lb_ = new exprMax (lb_, l0);
00123   ub_ = new exprMin (ub_, u0);
00124 }
00125 
00126 
00128 void exprAux::print (std::ostream &out, bool descend) const {
00129 
00130   if (descend) 
00131     image_ -> print (out, descend);
00132   else {
00133     if (integer_) out << "z_"; // TODO: should be isInteger instead of
00134                                // integer_. Change all "isInteger()"
00135                                // to "isInteger() const"
00136     else          out << "w_";
00137     out << varIndex_;
00138   }
00139 }
00140 
00141 
00144 int exprAux::DepList (std::set <int> &deplist, 
00145                       enum dig_type type) {
00146 
00147   if (type == ORIG_ONLY)   
00148     return image_ -> DepList (deplist, type);
00149 
00150   if (deplist.find (varIndex_) == deplist.end ())
00151     deplist.insert (varIndex_); 
00152   else return 0;
00153 
00154   if (type == STOP_AT_AUX) 
00155     return 1;
00156 
00157   return 1 + image_ -> DepList (deplist, type);
00158 }
00159 
00160 
00162 expression *exprAux::simplify () {
00163 
00164   if ((image_ -> Type () == AUX) || 
00165       (image_ -> Type () == VAR)) {
00166 
00167     --multiplicity_;
00168     expression *ret = image_;
00169     image_ = NULL;
00170     return ret;
00171   }
00172 
00173   return NULL;
00174 }
00175 
00176 
00177 // generate cuts for expression associated with this auxiliary
00178 
00179 void exprAux::generateCuts (const OsiSolverInterface &si, 
00180                             OsiCuts &cs, const CouenneCutGenerator *cg, 
00181                             t_chg_bounds *chg, int,
00182                             CouNumber, CouNumber) {
00183   //#ifdef DEBUG
00184   static bool warned_large_coeff = false;
00185   int nrc = cs.sizeRowCuts (), ncc = cs.sizeColCuts ();
00186   //#endif
00187 
00188   /*
00189   if ((!(cg -> isFirst ())) && 
00190       ((l = domain_ -> lb (varIndex_)) > -COUENNE_INFINITY) &&
00191       ((u = domain_ -> ub (varIndex_)) <  COUENNE_INFINITY) &&
00192       (fabs (u-l) < COUENNE_EPS))
00193     cg -> createCut (cs, (l+u)/2., 0, varIndex_, 1.);
00194   else 
00195   */
00196   image_ -> generateCuts (this, si, cs, cg, chg);
00197 
00198   // check if cuts have coefficients, rhs too large or too small
00199 
00200   //#ifdef DEBUG
00201 
00202   if (cg -> Jnlst () -> ProduceOutput (Ipopt::J_DETAILED, J_CONVEXIFYING)) {
00203     if (cg -> Jnlst () -> ProduceOutput (Ipopt::J_STRONGWARNING, J_CONVEXIFYING) && 
00204         (warned_large_coeff)) {
00205       for (int jj=nrc; jj < cs.sizeRowCuts (); jj++) {
00206 
00207         OsiRowCut        *cut = cs.rowCutPtr (jj);
00208         CoinPackedVector  row = cut -> row ();
00209 
00210         int           n   = cut -> row (). getNumElements();
00211         const double *el  = row. getElements ();
00212         const int    *ind = row. getIndices ();
00213         double        rhs = cut -> rhs ();
00214 
00215         while (n--) {
00216           if (fabs (el [n]) > COU_MAX_COEFF)  {
00217             printf ("Couenne, warning: coefficient too large %g x%d: ", el [n], ind [n]);
00218             cut -> print (); 
00219             warned_large_coeff = true;
00220             break;
00221           }
00222 
00223           if (fabs (rhs) > COU_MAX_COEFF) {
00224             printf ("Couenne, warning: rhs too large (%g): ", rhs);
00225             cut -> print ();
00226             warned_large_coeff = true;
00227             break;
00228           }
00229         }
00230       }
00231     }
00232 
00233     //  if (!(cg -> isFirst ())) 
00234     if ((nrc < cs.sizeRowCuts ()) || 
00235         (ncc < cs.sizeColCuts ()))
00236       {
00237         printf ("---------------- ConvCut:  "); 
00238         print (std::cout);  printf (" := ");
00239         image_ -> print (std::cout); 
00240 
00241         printf (" [%.7e,%.7e] <--- ", 
00242                 domain_ -> lb (varIndex_), 
00243                 domain_ -> ub (varIndex_));
00244 
00245         int index;
00246         if ((image_ -> Argument ()) && 
00247             ((index = image_ -> Argument () -> Index ()) >= 0))
00248           printf ("[%.7e,%.7e] ",
00249                   domain_ -> lb (index),
00250                   domain_ -> ub (index));
00251         else if (image_ -> ArgList ())
00252           for (int i=0; i<image_ -> nArgs (); i++)
00253             if ((index = image_ -> ArgList () [i] -> Index ()) >= 0)
00254               printf ("[%.7e,%.7e] ", 
00255                       domain_ -> lb (index), 
00256                       domain_ -> ub (index));
00257         printf ("\n");
00258 
00259         for (int jj = nrc; jj < cs.sizeRowCuts (); jj++) cs.rowCutPtr (jj) -> print ();
00260         for (int jj = ncc; jj < cs.sizeColCuts (); jj++) cs.colCutPtr (jj) -> print ();
00261       }
00262   }
00263     //#endif
00264 
00266 
00267 #if 0
00268   draw_cuts (cs, cg, nrc, this, image_);
00269 #endif
00270 }
00271 
00272 
00275 CouenneObject exprAux::properObject (CouenneProblem *p, 
00276                                      Bonmin::BabSetupBase *base, 
00277                                      JnlstPtr jnlst) {
00278 
00279   /*if (image_ -> code () == COU_EXPRMUL) printf ("OK1\n");
00280   if (image_ -> ArgList () [0] -> Index () >= 0) printf ("OK2\n"); 
00281   if (image_ -> ArgList () [1] -> Index () >= 0) printf ("OK3\n");
00282   if (fabs (lb ()) < COUENNE_EPS) printf ("OK4\n");
00283   if (fabs (ub ()) < COUENNE_EPS) printf ("OK5\n");*/
00284 
00285   // todo: this is an expression method
00286 
00287   if ((image_ -> code () == COU_EXPRMUL) &&
00288       (image_ -> ArgList () [0] -> Index () >= 0) &&
00289       (image_ -> ArgList () [1] -> Index () >= 0) &&
00290       (fabs (lb ()) < COUENNE_EPS) &&
00291       (fabs (ub ()) < COUENNE_EPS)) {
00292 
00293     // it's a complementarity constraint object!
00294 
00295     CouenneComplObject obj (p, this, base, jnlst);
00296     return obj;
00297   }
00298   else {
00299     CouenneObject obj (p, this, base, jnlst);
00300     return obj;
00301   }
00302 }

Generated on Mon Aug 3 03:02:20 2009 by  doxygen 1.4.7