00001
00002
00003
00004
00005
00006
00007
00008
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
00027
00028
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
00042
00043
00044
00045
00046
00047
00048
00049
00050
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
00070
00071
00073 exprAux::exprAux (const exprAux &e, Domain *d):
00074 exprVar (e.varIndex_, d),
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
00083
00084
00085
00086
00087
00088 lb_ = new exprLowerBound (varIndex_, domain_);
00089 ub_ = new exprUpperBound (varIndex_, domain_);
00090
00091
00092 }
00093
00094
00096 exprAux::~exprAux () {
00097
00098 if (image_) {
00099
00100
00101 delete image_;
00102 }
00103 if (lb_) delete lb_;
00104 if (ub_) delete ub_;
00105 }
00106
00107
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00127 void exprAux::crossBounds () {
00128
00129 expression *l0, *u0;
00130
00131 image_ -> getBounds (l0, u0);
00132
00133
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_";
00147
00148
00149 else out << "w_";
00150 out << varIndex_;
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
00192
00193 void exprAux::generateCuts (OsiCuts &cs, const CouenneCutGenerator *cg,
00194 t_chg_bounds *chg, int,
00195 CouNumber, CouNumber) {
00196
00197 static bool warned_large_coeff = false;
00198 int nrc = cs.sizeRowCuts (), ncc = cs.sizeColCuts ();
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 image_ -> generateCuts (this, cs, cg, chg);
00210
00211
00212
00213
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
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
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
00300
00301
00302
00303 if ((image_ -> code () == COU_EXPRMUL) &&
00304
00305 (image_ -> ArgList () [0] -> Index () >= 0) &&
00306 (image_ -> ArgList () [1] -> Index () >= 0) &&
00307
00308 (
00309 ((fabs (lb ()) < COUENNE_EPS) && (fabs (ub ()) < COUENNE_EPS))
00310 ||
00311 (top_level_ &&
00312 ((((fabs (lb ()) < COUENNE_EPS) && ( ub () > COUENNE_INFINITY)) ||
00313 (( lb () < -COUENNE_INFINITY) && (fabs (ub ()) < COUENNE_EPS )))))
00314 )
00315 ) {
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
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 }