source: stable/0.2/Couenne/src/expression/exprAux.cpp @ 159

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

created new stable branch 0.2 from trunk (rev. 157)

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