source: branches/Couenne/Couenne/src/convex/addEnvelope.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: 2.9 KB
Line 
1/*
2 * File: addEnvelope.cpp
3 * Author: Pietro Belotti, Carnegie Mellon University
4 * Purpose: add generic envelope to convex function based on function and its derivative
5 *
6 * (C) Pietro Belotti, all rights reserved.
7 * This code is distributed under the Common Public License.
8 */
9
10
11#include <OsiRowCut.hpp>
12#include <CouennePrecisions.h>
13#include <CouenneTypes.h>
14#include <CouenneCutGenerator.h>
15
16void CouenneCutGenerator::addEnvelope (OsiCuts &cs, int sign,
17                                       unary_function f,      // function to be linearized
18                                       unary_function fprime, // derivative of f
19                                       int w_ind, int x_ind, 
20                                       CouNumber x, CouNumber l, CouNumber u,
21                                       bool is_global) const {
22  CouNumber opp_slope = - fprime (x);
23
24  // TODO: remove check of !firstcall_ if point is available already
25
26  // if bounds are very close, convexify with a single line
27
28  if (fabs (u - l) < COUENNE_EPS) {
29
30    CouNumber x0 = 0.5 * (u+l), fp0 = fprime (x0);
31    createCut (cs, f(x0) - fp0 * x0, 0, w_ind, 1., x_ind, - fp0);
32    return;
33  }
34
35  // Add tangent in any case
36
37  if (((!firstcall_) || ((x >= l) && (x <= u)))
38      && (fabs (opp_slope) < COUENNE_INFINITY))
39    createCut (cs, f (x) + opp_slope * x, sign, w_ind, 1., 
40               x_ind, opp_slope, -1, 0., is_global);
41
42    //      addTangent (cs, w_ind, x_ind, x, f (x), fprime (x), sign);
43
44  if ((convtype_ == UNIFORM_GRID) || firstcall_) {
45
46    // now add tangent at each sampling point
47
48    CouNumber sample = l, 
49              step   = (u-l) / nSamples_;
50
51    //    printf ("[%.4f %.4f], step = %.4f, %d samples\n",
52    //      l, u, step, nSamples_);
53
54    for (int i = 0; i <= nSamples_; i++) {
55
56      opp_slope = - fprime (sample);
57
58      if ((fabs (opp_slope) < COUENNE_INFINITY) && 
59          (fabs (sample-x) > COUENNE_EPS)) // do not add twice cut at current point
60          createCut (cs, f (sample) + opp_slope * sample, sign, 
61                     w_ind, 1.,
62                     x_ind, opp_slope, 
63                     -1, 0., is_global);
64
65        //      printf ("  Uniform %d: ", i); cut -> print ();
66
67      sample += step;
68    }
69  }
70
71  else if (convtype_ != CURRENT_ONLY) {
72
73    CouNumber sample = x;
74
75    if (fabs (opp_slope) < COUENNE_INFINITY)
76      createCut (cs, f (x) + opp_slope * x, sign, 
77                 w_ind, 1.,
78                 x_ind, opp_slope, 
79                 -1, 0.,
80                 is_global);
81      //      printf ("  Current tangent: "); cut -> print ();
82
83
84    for (int i = 0; i <= nSamples_/2; i++) {
85
86      sample += (x-l) / nSamples_;
87      opp_slope = - fprime (sample);
88
89      if (fabs (opp_slope) < COUENNE_INFINITY)
90        createCut (cs, f (sample) + opp_slope * sample, sign, 
91                   w_ind, 1.,
92                   x_ind, opp_slope, 
93                   -1, 0.,
94                   is_global);
95        //      printf ("  neighbour -%d: ", i); cut -> print ();
96    }
97
98    sample = x;
99
100    for (int i = 0; i <= nSamples_/2; i++) {
101
102      sample += (u-x) / nSamples_;
103      opp_slope = - fprime (sample);
104
105      createCut (cs, f (sample) + opp_slope * sample, sign, 
106                 w_ind, 1.,
107                 x_ind, opp_slope, 
108                 -1, 0.,
109                 is_global);
110        //      printf ("  neighbour  %d: ", i); cut -> print ();
111    }
112  }
113}
Note: See TracBrowser for help on using the repository browser.