13 # define M_PI 3.14159265358979323846
16 # define M_PI_2 1.57079632679489661923
21 #include "OsiSolverInterface.hpp"
34 int addHexagon (
const CouenneCutGenerator *,
43 int trigEnvelope (
const CouenneCutGenerator *, OsiCuts &,
44 expression *, expression *,
enum cou_trig);
111 arg -> getBounds (lb, ub);
117 xi = arg -> Index (),
125 else {
f =
cos (x0); fp = -
sin (x0);}
127 return cg -> createCut (cs,
f - fp*x0, cg -> Problem () -> Var (wi) -> sign (), wi, 1., xi, -fp);
132 bool skip_up =
false,
162 sinrx0 =
sin (rx0), zero;
165 up = (rx0 <
M_PI) ? +1 : -1,
166 left = (x0 < x1) ? +1 : -1;
169 zero = (
up>0) ? 0. :
M_PI;
173 if (
up>0) {s0 = &skip_up; s1 = &skip_dn;}
174 else {s0 = &skip_dn; s1 = &skip_up;}
184 ncuts += cg -> addTangent (cs, wi, xi, x0,
sin (rx0),
cos (rx0), -
up);
190 if ((left * (rx1 -
M_PI * ((left -
up) / 2 + 1)) <= 0) ||
192 (rx0, extr0, extr0 +
M_PI_2))) <= 0)) {
193 if (!*s1 && (sign != -
up))
194 *s1 = ((ncuts += cg -> addSegment (cs, wi, xi, x0,
sin (rx0),
x1,
sin (rx1),
up)) > 0);
197 ncuts += cg -> addSegment (cs, wi, xi, x0,
sin (rx0), base+tpt,
sin (tpt),
up);
204 if (left * (rx1 - (4*left -
up + 2) *
M_PI_2) < 0) {
206 if (
up * (
sin (rx1) - sinrx0 - cosrx0 * (rx1-rx0)) < 0) {
209 ncuts += cg -> addTangent (cs, wi, xi, x0, sinrx0, cosrx0, -
up);
213 if (left * (rx1 - tpt) < 0) {
214 if (!*s0 && (sign !=
up) )
224 ncuts += cg -> addSegment (cs, wi, xi, x0,
sin (rx0), base + tpt,
sin (tpt), -
up);
228 if ((left * (rx1 - (zero +
M_PI)) < 0) ||
230 (2 + 2*left -
up) * M_PI_2))) < 0)) {
231 if (!*s1 && (sign != -
up))
232 *s1 = ((ncuts += cg -> addSegment (cs, wi, xi, x0,
sin (rx0), x1,
sin (rx1),
up)) > 0);
235 ncuts += cg -> addSegment (cs, wi, xi, x0,
sin (rx0), base + tpt,
sin (tpt),
up);
247 int addHexagon (
const CouenneCutGenerator *cg,
255 arg -> getBounds (lb, ub);
258 x_ind = arg -> Index (),
259 w_ind = aux -> Index ();
261 enum auxSign sign = cg -> Problem () -> Var (w_ind) -> sign ();
268 else {
f =
cos (x0); fp = -
sin (x0);}
270 return cg -> createCut (cs,
f - fp*x0, sign, w_ind, 1., x_ind, -fp);
Cut Generator for linear convexifications.
int trigEnvelope(const CouenneCutGenerator *, OsiCuts &, expression *, expression *, enum cou_trig)
convex cuts for sine or cosine
status of lower/upper bound of a variable, to be checked/modified in bound tightening ...
void generateCuts(expression *w, OsiCuts &cs, const CouenneCutGenerator *cg, t_chg_bounds *=NULL, int=-1, CouNumber=-COUENNE_INFINITY, CouNumber=COUENNE_INFINITY)
generate equality between *this and *w
void fint fint fint real fint real real real real * f
virtual expression * Image() const
return pointer to corresponding expression (for auxiliary variables only)
void generateCuts(expression *w, OsiCuts &cs, const CouenneCutGenerator *cg, t_chg_bounds *=NULL, int=-1, CouNumber=-COUENNE_INFINITY, CouNumber=COUENNE_INFINITY)
generate equality between *this and *w
auxSign
"sign" of the constraint defining an auxiliary.
int bayEnvelope(const CouenneCutGenerator *, OsiCuts &, int, int, CouNumber, CouNumber, CouNumber, bool &, bool &)
restrict to quarter of the interval [0,2pi]
cou_trig
specify which trigonometric function is dealt with in trigEnvelope
virtual expression * Argument() const
return argument
CouNumber modulo(register CouNumber a, register CouNumber b)
normalize angle within [0,b] (typically, pi or 2pi)
double CouNumber
main number type in Couenne
CouNumber trigNewton(CouNumber a, CouNumber l, CouNumber u)
common convexification method used by both cos and sin
CouExpr & cos(CouExpr &e)
int addSegment(OsiCuts &, int, int, CouNumber, CouNumber, CouNumber, CouNumber, int) const
Add half-plane through (x1,y1) and (x2,y2) – resp.
void fint fint fint real fint real real real real real real real real * w
CouExpr & sin(CouExpr &e)