source: branches/Couenne/Couenne/src/convex/operators/conv-exprLog.cpp @ 534

Last change on this file since 534 was 534, checked in by pbelotti, 13 years ago

moved include files to make them doxygenable. Introduced three-way branching, with fixed intervals for now. Added check for small bound interval within all generateCuts()

File size: 1.8 KB
Line 
1/*
2 * Name:    conv-exprLog.cpp
3 * Author:  Pietro Belotti
4 * Purpose: convexification and bounding methods for the logarithm operator
5 *
6 * This file is licensed under the Common Public License (CPL)
7 */
8
9#include <CouenneTypes.h>
10#include <exprLog.h>
11#include <exprInv.h>
12#include <exprPow.h>
13#include <exprConst.h>
14
15#include <CouenneProblem.h>
16#include <CouenneCutGenerator.h>
17
18
19#define LOG_STEP 10
20#define LOG_MININF 1e-50
21
22// generate convexification cut for constraint w = this
23
24void exprLog::generateCuts (exprAux *aux, const OsiSolverInterface &si, 
25                            OsiCuts &cs, const CouenneCutGenerator *cg) {
26
27  expression *le, *ue;
28
29  argument_ -> getBounds (le, ue);
30
31  CouNumber l = (*le) (),
32            u = (*ue) ();
33
34  int w_ind = aux       -> Index ();
35  int x_ind = argument_ -> Index ();
36
37  // if bounds are very close, convexify with a single line
38
39  if ((fabs (u - l) < COUENNE_EPS) && (l > COUENNE_EPS)) {
40
41    CouNumber x0 = 0.5 * (u+l);
42    cg -> createCut (cs, log (x0) - 1, 0, 
43                     w_ind, 1., x_ind, - 1/x0);
44    return;
45  }
46
47  CouNumber x = (cg -> isFirst ()) ? 
48                 1 : powNewton ((*argument_) (), (*aux) (), log, inv, oppInvSqr);
49
50  // fix lower bound
51
52  if (l < LOG_MININF) l = LOG_MININF;
53  else   // lower segment (only put if lower bound is far enough from
54         // zero and upper is finite)
55    if (u < COUENNE_INFINITY - 1) { 
56
57      CouNumber dx   = u-l;
58      CouNumber logu = log (u);
59      CouNumber dw   = logu - log (l);
60
61      cg -> createCut (cs, dx*logu - u*dw, +1, w_ind, dx, x_ind, -dw);
62    }
63
64  // fix bound interval (unless you like infinite coefficients)
65
66  if      (x < l) x = l;
67  else if (x > u) x = u;
68
69  if (u > 1e5 * log (COUENNE_INFINITY) - 1)
70    u = x + (LOG_STEP << cg -> nSamples ());
71
72  // add upper envelope
73
74  cg -> addEnvelope (cs, -1, log, inv, w_ind, x_ind, x, l, u, true);
75
76  delete le;
77  delete ue;
78}
Note: See TracBrowser for help on using the repository browser.