sos2a.gms : Test of SOS2 variables
Do linear interpolation of the points
ord(I), f(I)
(using SOS2 vars w(I)) to define a function f(x).
By bounding w(I) below we can take out a little interval from the
domain of f. We minimize the distance between f(x) and Fbar,
with full domain and with the restriction.
Contributor: Steve Dirkse
Small Model of Type: MIP
$TITLE 'Test of SOS2 variables' (SOS2A,SEQ=345)
$ontext
Do linear interpolation of the points
ord(I), f(I)
(using SOS2 vars w(I)) to define a function f(x).
By bounding w(I) below we can take out a little interval from the
domain of f. We minimize the distance between f(x) and Fbar,
with full domain and with the restriction.
Contributor: Steve Dirkse
$offtext
$if not set TESTTOL $set TESTTOL 1e-6
scalar mchecks / 0 /;
$if not %MIPMCHECKS% == 0 mchecks = 1;
scalar Fbar / 1.3 /;
set I / 1 * 3 /;
parameter f(I) /
1 1
2 2
3 3
/;
scalar wLo 'lower bound on w(1)' / -1 /;
sos2 variables w(I);
positive variables fplus, fminus;
* the optimization forces
* fplus = min(0,fx-Fbar)
* fminus = min(0,Fbar-fx)
variables
obj,
x,
fx;
w.lo(I) = 0;
equations
wsum,
xdef,
fxdef,
objdef,
defwLo,
gapplus,
gapminus;
wsum.. 1 =e= sum {I, w(I)};
xdef.. x =e= sum {I, w(I)*ord(I)};
fxdef.. fx =e= sum {I, w(I)*f(I)};
gapplus.. fplus =g= fx - Fbar;
gapminus.. fminus =g= Fbar - fx;
defwLo.. w('1') =g= wLo;
objdef.. obj =e= fplus + fminus;
model m / all /;
m.optcr = 0;
scalars
tol / %TESTTOL% /,
obj1 'objective of first solve' / 0 /
obj1_m / 0 /
obj2 'objective of second solve' / .1 /
obj2_m / 0 /
fplus1 / 0 /
fminus1 / 0 /
fplus1_m / 1 /
fminus1_m / 1 /
fplus2 / 0 /
fminus2 / .1 /
fplus2_m / 1 /
fminus2_m / 0 /
fx1_L / 1.3 /
fx2_L / 1.2 /
fx1_m / 0 /
fx2_m / 0 /
x1_L / 1.3 /
x2_L / 1.2 /
x1_m / 0 /
x2_m / 0 /
defw1_m / 0 /
defw2_m / 1 /
;
parameters
w1_L(I) /
1 .7
2 .3
3 0
/
w1_m(I) /
1 0
2 0
3 0
/
w2_L(I) /
1 .8
2 .2
3 0
/
w2_m(I) /
1 0
2 0
3 -1
/
;
solve m using MIP minimizing obj;
if {(m.solvestat = 6),
abort$(m.modelstat <> 14) 'bad modelstat';
else
abort$( m.solvestat <> 1 or m.modelstat <> 1) 'wrong status codes';
abort$( abs(m.objval - obj1) > tol) 'Wrong m.objval';
abort$( abs(obj.l - obj1) > tol) 'Wrong obj.l';
abort$( smax(I,abs(w.l(I) - w1_L(I))) > tol) 'Wrong w.l';
abort$( abs(fplus.l - fplus1) > tol) 'Wrong fplus.l';
abort$( abs(fminus.l - fminus1) > tol) 'Wrong fminus.l';
abort$( abs(fx.l - fx1_L) > tol) 'Wrong fx.l';
abort$( abs(x.l - x1_L) > tol) 'Wrong x.l';
if {mchecks,
* we will do a sampling check for uniqueness of the duals
* it is not likely that all of these are unique
abort$( abs(obj.m - obj1_m) > tol) 'Wrong obj.m';
abort$( smax(I,abs(w.m(I) - w1_m(I))) > tol) 'Wrong w.m';
abort$( abs(defwLo.m - defw1_m) > tol) 'Wrong defwLo.m';
abort$( abs(fplus.m - fplus1_m) > tol) 'Wrong fplus.m';
abort$( abs(fminus.m - fminus1_m) > tol) 'Wrong fminus.m';
abort$( abs(fx.m - fx1_m) > tol) 'Wrong fx.m';
abort$( abs(x.m - x1_m) > tol) 'Wrong x.m';
};
};
wLo = .8;
solve m using MIP minimizing obj;
if {(m.solvestat = 6),
abort$(m.modelstat <> 14) 'bad modelstat';
else
abort$( m.solvestat <> 1 or m.modelstat <> 1) 'wrong status codes';
abort$( abs(m.objval - obj2) > tol) 'Wrong m.objval';
abort$( abs(obj.l - obj2) > tol) 'Wrong obj.l';
abort$( smax(I,abs(w.l(I) - w2_L(I))) > tol) 'Wrong w.l';
abort$( abs(fplus.l - fplus2) > tol) 'Wrong fplus.l';
abort$( abs(fminus.l - fminus2) > tol) 'Wrong fminus.l';
abort$( abs(fx.l - fx2_L) > tol) 'Wrong fx.l';
abort$( abs(x.l - x2_L) > tol) 'Wrong x.l';
if {mchecks,
* we will do a sampling check for uniqueness of the duals
* it is not likely that all of these are unique
abort$( abs(obj.m - obj2_m) > tol) 'Wrong obj.m';
abort$( smax(I,abs(w.m(I) - w2_m(I))) > tol) 'Wrong w.m';
abort$( abs(defwLo.m - defw2_m) > tol) 'Wrong defwLo.m';
abort$( abs(fplus.m - fplus2_m) > tol) 'Wrong fplus.m';
abort$( abs(fminus.m - fminus2_m) > tol) 'Wrong fminus.m';
abort$( abs(fx.m - fx2_m) > tol) 'Wrong fx.m';
abort$( abs(x.m - x2_m) > tol) 'Wrong x.m';
};
};