00001
00002
00003
00004
00005
00006
00007
00008
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
00023
00024
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
00035
00036
00037
00038
00039
00040
00041
00042
00043
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
00061
00062
00064 exprAux::exprAux (const exprAux &e, Domain *d):
00065 exprVar (e.varIndex_, d),
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
00073
00074
00075
00076
00077
00078 lb_ = new exprLowerBound (varIndex_, domain_);
00079 ub_ = new exprUpperBound (varIndex_, domain_);
00080
00081
00082 }
00083
00084
00086 exprAux::~exprAux () {
00087
00088 if (image_) {
00089
00090
00091 delete image_;
00092 }
00093 if (lb_) delete lb_;
00094 if (ub_) delete ub_;
00095 }
00096
00097
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00117 void exprAux::crossBounds () {
00118
00119 expression *l0, *u0;
00120
00121 image_ -> getBounds (l0, u0);
00122
00123
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_";
00137
00138
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
00181
00182 void exprAux::generateCuts (
00183 OsiCuts &cs, const CouenneCutGenerator *cg,
00184 t_chg_bounds *chg, int,
00185 CouNumber, CouNumber) {
00186
00187 static bool warned_large_coeff = false;
00188 int nrc = cs.sizeRowCuts (), ncc = cs.sizeColCuts ();
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 image_ -> generateCuts (this, cs, cg, chg);
00200
00201
00202
00203
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
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
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
00284
00285
00286
00287 if ((image_ -> code () == COU_EXPRMUL) &&
00288
00289 (image_ -> ArgList () [0] -> Index () >= 0) &&
00290 (image_ -> ArgList () [1] -> Index () >= 0) &&
00291
00292 (
00293 ((fabs (lb ()) < COUENNE_EPS) && (fabs (ub ()) < COUENNE_EPS))
00294 ||
00295 (top_level_ &&
00296 ((((fabs (lb ()) < COUENNE_EPS) && ( ub () > COUENNE_INFINITY)) ||
00297 (( lb () < -COUENNE_INFINITY) && (fabs (ub ()) < COUENNE_EPS )))))
00298 )
00299 ) {
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
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 }