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
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
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
00059
00060
00062 exprAux::exprAux (const exprAux &e, Domain *d):
00063 exprVar (e.varIndex_, d),
00064 image_ (e.image_ -> clone (d)),
00065 rank_ (e.rank_),
00066 multiplicity_ (e.multiplicity_),
00067 integer_ (e.integer_) {
00068
00069
00070
00071
00072
00073
00074
00075 lb_ = new exprLowerBound (varIndex_, domain_);
00076 ub_ = new exprUpperBound (varIndex_, domain_);
00077
00078
00079 }
00080
00081
00083 exprAux::~exprAux () {
00084 if (image_) {
00085
00086
00087
00088 delete image_;
00089 }
00090 if (lb_) delete lb_;
00091 if (ub_) delete ub_;
00092 }
00093
00094
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00114 void exprAux::crossBounds () {
00115
00116 expression *l0, *u0;
00117
00118 image_ -> getBounds (l0, u0);
00119
00120
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_";
00134
00135
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
00178
00179 void exprAux::generateCuts (const OsiSolverInterface &si,
00180 OsiCuts &cs, const CouenneCutGenerator *cg,
00181 t_chg_bounds *chg, int,
00182 CouNumber, CouNumber) {
00183
00184 static bool warned_large_coeff = false;
00185 int nrc = cs.sizeRowCuts (), ncc = cs.sizeColCuts ();
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 image_ -> generateCuts (this, si, cs, cg, chg);
00197
00198
00199
00200
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
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
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
00280
00281
00282
00283
00284
00285
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
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 }