source: trunk/Couenne/src/expression/exprAux.cpp @ 75

Last change on this file since 75 was 75, checked in by pbelotti, 11 years ago

fixed segfault with constant objective. Other minor fixes

File size: 7.8 KB
Line 
1/*
2 * Name:    exprAux.cpp
3 * Author:  Pietro Belotti
4 * Purpose: methods of the class of auxiliary variables
5 *
6 * (C) Carnegie-Mellon University, 2006-08.
7 * This file is licensed under the Common Public License (CPL)
8 */
9
10#include "exprAux.hpp"
11#include "exprBound.hpp"
12#include "exprMax.hpp"
13#include "exprMin.hpp"
14#include "CouenneCutGenerator.hpp"
15#include "CouenneComplObject.hpp"
16#include "CouenneJournalist.hpp"
17
18class CouenneCutGenerator;
19class Domain;
20
21//#define DEBUG
22
23// auxiliary expression Constructor
24exprAux::exprAux (expression *image, int index, int rank, enum intType isInteger, Domain *d): 
25
26  exprVar       (index, d),
27  image_        (image),
28  rank_         (rank),
29  multiplicity_ (1),
30  integer_      (isInteger) {
31
32  // do this later, in standardize()
33  //  image_ -> getBounds (lb_, ub_);
34
35  //  getBounds (lb_, ub_); // !!!!!!!!
36
37  //  image_ -> getBounds (lb_, ub_);
38  // getBounds (lb_, ub_);
39
40  //  lb_ = new exprMax (new exprLowerBound (varIndex_), lb_);
41  //  ub_ = new exprMin (new exprUpperBound (varIndex_), ub_);
42  lb_ = new exprLowerBound (varIndex_, domain_);
43  ub_ = new exprUpperBound (varIndex_, domain_);
44}
45
46
47/// Constructor to be used with standardize ([...], false)
48exprAux::exprAux (expression *image, Domain *d):
49
50  exprVar       (-1, d),
51  image_        (image),
52  lb_           (NULL),
53  ub_           (NULL),
54  rank_         (-1),
55  multiplicity_ (0),
56  integer_      (Unset) {}
57//(image -> isInteger () ? Integer : Continuous)
58
59
60/// Copy constructor
61exprAux::exprAux (const exprAux &e, Domain *d):
62  exprVar       (e.varIndex_, d), // variables ? (*variables) [0] -> domain () : NULL),
63  image_        (e.image_ -> clone (d)),
64  rank_         (e.rank_),
65  multiplicity_ (e.multiplicity_),
66  integer_      (e.integer_) {
67
68  //  image_ -> getBounds (lb_, ub_);
69  // getBounds (lb_, ub_);
70
71  //  lb_ = new exprMax (new exprLowerBound (varIndex_), lb_);
72  //  ub_ = new exprMin (new exprUpperBound (varIndex_), ub_);
73
74  lb_ = new exprLowerBound (varIndex_, domain_);
75  ub_ = new exprUpperBound (varIndex_, domain_);
76
77  //crossBounds ();
78}
79
80
81/// Destructor
82exprAux::~exprAux () {
83  if (image_) {
84    //printf ("deleting %x: ", this);   fflush (stdout); print ();           fflush (stdout);
85    //printf (" [%x] ",        image_); fflush (stdout); image_ -> print (); fflush (stdout);
86    //printf ("\n");
87    delete image_; 
88  }
89  if (lb_)    delete lb_;
90  if (ub_)    delete ub_;
91}
92
93
94/// Get lower and upper bound of an expression (if any)
95//void exprAux::getBounds (expression *&lb, expression *&ub) {
96
97  // this replaces the previous
98  //
99  //    image_ -> getBounds (lb0, ub0);
100  //
101  // which created large expression trees, now useless since all
102  // auxiliaries are standardized.
103
104  //  lb = lb_ -> clone ();//new exprLowerBound (varIndex_);
105  //  ub = ub_ -> clone ();//new exprUpperBound (varIndex_);
106//  lb = new exprLowerBound (varIndex_, domain_);
107//  ub = new exprUpperBound (varIndex_, domain_);
108//}
109
110
111/// set bounds depending on both branching rules and propagated
112/// bounds. To be used after standardization
113void exprAux::crossBounds () {
114
115  expression *l0, *u0;
116
117  image_ -> getBounds (l0, u0);
118
119  //image_ -> getBounds (lb_, ub_);
120
121  lb_ = new exprMax (lb_, l0);
122  ub_ = new exprMin (ub_, u0);
123}
124
125
126/// I/O
127void exprAux::print (std::ostream &out, bool descend) const {
128
129  if (descend) 
130    image_ -> print (out, descend);
131  else {
132    if (integer_) out << "z_"; // TODO: should be isInteger instead of
133                               // integer_. Change all "isInteger()"
134                               // to "isInteger() const"
135    else          out << "w_";
136    out << varIndex_;
137  }
138}
139
140
141/// fill in the set with all indices of variables appearing in the
142/// expression
143int exprAux::DepList (std::set <int> &deplist, 
144                      enum dig_type type) {
145
146  if (type == ORIG_ONLY)   
147    return image_ -> DepList (deplist, type);
148
149  if (deplist.find (varIndex_) == deplist.end ())
150    deplist.insert (varIndex_); 
151  else return 0;
152
153  if (type == STOP_AT_AUX) 
154    return 1;
155
156  return 1 + image_ -> DepList (deplist, type);
157}
158
159
160/// simplify
161expression *exprAux::simplify () {
162
163  if ((image_ -> Type () == AUX) || 
164      (image_ -> Type () == VAR)) {
165
166    --multiplicity_;
167    expression *ret = image_;
168    image_ = NULL;
169    return ret;
170  }
171
172  return NULL;
173}
174
175
176// generate cuts for expression associated with this auxiliary
177
178void exprAux::generateCuts (const OsiSolverInterface &si, 
179                            OsiCuts &cs, const CouenneCutGenerator *cg, 
180                            t_chg_bounds *chg, int,
181                            CouNumber, CouNumber) {
182  //#ifdef DEBUG
183  static bool warned_large_coeff = false;
184  int nrc = cs.sizeRowCuts (), ncc = cs.sizeColCuts ();
185  //#endif
186
187  /*
188  if ((!(cg -> isFirst ())) &&
189      ((l = domain_ -> lb (varIndex_)) > -COUENNE_INFINITY) &&
190      ((u = domain_ -> ub (varIndex_)) <  COUENNE_INFINITY) &&
191      (fabs (u-l) < COUENNE_EPS))
192    cg -> createCut (cs, (l+u)/2., 0, varIndex_, 1.);
193  else
194  */
195  image_ -> generateCuts (this, si, cs, cg, chg);
196
197  // check if cuts have coefficients, rhs too large or too small
198
199  //#ifdef DEBUG
200
201  if (cg -> Jnlst () -> ProduceOutput (Ipopt::J_DETAILED, J_CONVEXIFYING)) {
202    if (cg -> Jnlst () -> ProduceOutput (Ipopt::J_STRONGWARNING, J_CONVEXIFYING) && 
203        (warned_large_coeff)) {
204      for (int jj=nrc; jj < cs.sizeRowCuts (); jj++) {
205
206        OsiRowCut        *cut = cs.rowCutPtr (jj);
207        CoinPackedVector  row = cut -> row ();
208
209        int           n   = cut -> row (). getNumElements();
210        const double *el  = row. getElements ();
211        const int    *ind = row. getIndices ();
212        double        rhs = cut -> rhs ();
213
214        while (n--) {
215          if (fabs (el [n]) > COU_MAX_COEFF)  {
216            printf ("Couenne, warning: coefficient too large %g x%d: ", el [n], ind [n]);
217            cut -> print (); 
218            warned_large_coeff = true;
219            break;
220          }
221
222          if (fabs (rhs) > COU_MAX_COEFF) {
223            printf ("Couenne, warning: rhs too large (%g): ", rhs);
224            cut -> print ();
225            warned_large_coeff = true;
226            break;
227          }
228        }
229      }
230    }
231
232    //  if (!(cg -> isFirst ()))
233    if ((nrc < cs.sizeRowCuts ()) || 
234        (ncc < cs.sizeColCuts ()))
235      {
236        printf ("---------------- ConvCut:  "); 
237        print (std::cout);  printf (" := ");
238        image_ -> print (std::cout); 
239
240        printf (" [%.7e,%.7e] <--- ", 
241                domain_ -> lb (varIndex_), 
242                domain_ -> ub (varIndex_));
243
244        int index;
245        if ((image_ -> Argument ()) && 
246            ((index = image_ -> Argument () -> Index ()) >= 0))
247          printf ("[%.7e,%.7e] ",
248                  domain_ -> lb (index),
249                  domain_ -> ub (index));
250        else if (image_ -> ArgList ())
251          for (int i=0; i<image_ -> nArgs (); i++)
252            if ((index = image_ -> ArgList () [i] -> Index ()) >= 0)
253              printf ("[%.7e,%.7e] ", 
254                      domain_ -> lb (index), 
255                      domain_ -> ub (index));
256        printf ("\n");
257
258        for (int jj = nrc; jj < cs.sizeRowCuts (); jj++) cs.rowCutPtr (jj) -> print ();
259        for (int jj = ncc; jj < cs.sizeColCuts (); jj++) cs.colCutPtr (jj) -> print ();
260      }
261  }
262    //#endif
263
264  //////////////////////////////////////////////////////////////
265
266#if 0
267  draw_cuts (cs, cg, nrc, this, image_);
268#endif
269}
270
271
272/// return proper object to handle expression associated with this
273/// variable (NULL if this is not an auxiliary)
274CouenneObject *exprAux::properObject (CouenneProblem *p, 
275                                      Bonmin::BabSetupBase *base, 
276                                      JnlstPtr jnlst) {
277
278  /*if (image_ -> code () == COU_EXPRMUL) printf ("OK1\n");
279  if (image_ -> ArgList () [0] -> Index () >= 0) printf ("OK2\n");
280  if (image_ -> ArgList () [1] -> Index () >= 0) printf ("OK3\n");
281  if (fabs (lb ()) < COUENNE_EPS) printf ("OK4\n");
282  if (fabs (ub ()) < COUENNE_EPS) printf ("OK5\n");*/
283
284  // todo: this is an expression method
285
286  if ((image_ -> code () == COU_EXPRMUL) &&
287      (image_ -> ArgList () [0] -> Index () >= 0) &&
288      (image_ -> ArgList () [1] -> Index () >= 0) &&
289      (fabs (lb ()) < COUENNE_EPS) &&
290      (fabs (ub ()) < COUENNE_EPS))
291
292    // it's a complementarity constraint object!
293
294    return new CouenneComplObject (p, this, base, jnlst);
295  else return new CouenneObject (p, this, base, jnlst);
296}
Note: See TracBrowser for help on using the repository browser.