00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "OsiRowCut.hpp"
00013 #include "CouennePrecisions.hpp"
00014 #include "CouenneTypes.hpp"
00015 #include "CouenneCutGenerator.hpp"
00016 #include "funtriplets.hpp"
00017
00018
00019 void CouenneCutGenerator::addEnvelope (OsiCuts &cs, int sign,
00020 unary_function f,
00021 unary_function fprime,
00022 int w_ind, int x_ind,
00023 CouNumber x, CouNumber l, CouNumber u,
00024 t_chg_bounds *chg,
00025 bool is_global) const {
00026
00027 simpletriplet st (f, fprime, fprime);
00028 addEnvelope (cs, sign, &st, w_ind, x_ind, x, l, u, chg, is_global);
00029 }
00030
00031
00032 void CouenneCutGenerator::addEnvelope (OsiCuts &cs, int sign,
00033 funtriplet *ft,
00034 int w_ind, int x_ind,
00035 CouNumber x, CouNumber l, CouNumber u,
00036 t_chg_bounds *chg,
00037 bool is_global) const {
00038 CouNumber opp_slope = - ft -> Fp (x);
00039
00040
00041
00042
00043
00044 bool cLeft = !chg || (chg [x_ind].lower() != t_chg_bounds::UNCHANGED) || firstcall_;
00045 bool cRight = !chg || (chg [x_ind].upper() != t_chg_bounds::UNCHANGED) || firstcall_;
00046
00047 if (fabs (u - l) < COUENNE_EPS) {
00048
00049 CouNumber x0 = 0.5 * (u+l), fp0 = ft -> Fp (x0);
00050 if (cLeft || cRight)
00051 createCut (cs, ft -> F(x0) - fp0 * x0, 0, w_ind, 1., x_ind, - fp0);
00052 return;
00053 }
00054
00055
00056
00057 if (((!firstcall_) || ((x >= l) && (x <= u)))
00058 && (fabs (opp_slope) < COUENNE_INFINITY))
00059 createCut (cs, ft -> F (x) + opp_slope * x, sign, w_ind, 1.,
00060 x_ind, opp_slope, -1, 0., is_global);
00061
00062
00063
00064 if ((convtype_ == UNIFORM_GRID) || firstcall_) {
00065
00066 if (cLeft || cRight) {
00067
00068
00069 CouNumber sample = l,
00070 step = (u-l) / nSamples_;
00071
00072
00073
00074
00075 for (int i = 0; i <= nSamples_; i++) {
00076
00077 opp_slope = - ft -> Fp (sample);
00078
00079 if ((fabs (opp_slope) < COUENNE_INFINITY) &&
00080 (fabs (sample-x) > COUENNE_EPS))
00081 createCut (cs, ft -> F (sample) + opp_slope * sample, sign,
00082 w_ind, 1.,
00083 x_ind, opp_slope,
00084 -1, 0., is_global);
00085
00086
00087
00088 sample += step;
00089 }
00090 }
00091 }
00092 else if (convtype_ != CURRENT_ONLY) {
00093
00094 CouNumber sample = x;
00095
00096 if (fabs (opp_slope) < COUENNE_INFINITY)
00097 createCut (cs, ft -> F (x) + opp_slope * x, sign,
00098 w_ind, 1.,
00099 x_ind, opp_slope,
00100 -1, 0.,
00101 is_global);
00102
00103
00104 for (int i = 0; i <= nSamples_/2; i++) {
00105
00106 sample += (x-l) / nSamples_;
00107 opp_slope = - ft -> Fp (sample);
00108
00109 if (fabs (opp_slope) < COUENNE_INFINITY)
00110 createCut (cs, ft -> F (sample) + opp_slope * sample, sign,
00111 w_ind, 1.,
00112 x_ind, opp_slope,
00113 -1, 0.,
00114 is_global);
00115
00116 }
00117
00118 sample = x;
00119
00120 for (int i = 0; i <= nSamples_/2; i++) {
00121
00122 sample += (u-x) / nSamples_;
00123 opp_slope = - ft -> Fp (sample);
00124
00125 createCut (cs, ft -> F(sample) + opp_slope * sample, sign,
00126 w_ind, 1.,
00127 x_ind, opp_slope,
00128 -1, 0.,
00129 is_global);
00130
00131 }
00132 }
00133 }