mcp11.gms : Test marginals for a scaled MCP problem

Description

Start with the simplest MCP model one can imagine:
   f(x) := x-c, x >= 0
   For this model f.lo = c.

Ignoring the degenerate case when c==0, we have:
  A) c > 0: implies
     x = c is the solution, f.l == f.lo, f.m = x.l = c
  B) c < 0: implies
     x = 0 is the solution, f.l == 0, f.m = x.l = 0, x.m = (-c)

For each case A) and B), we consider scaling the variable and the equation,
for a total of 4 cases.

Contributor: Steve Dirkse, May 2016


Small Model of Type : MCP


Category : GAMS Test library


Main file : mcp11.gms

$title Test marginals for a scaled MCP problem (MCP11,SEQ=696)

$onText
Start with the simplest MCP model one can imagine:
   f(x) := x-c, x >= 0
   For this model f.lo = c.

Ignoring the degenerate case when c==0, we have:
  A) c > 0: implies
     x = c is the solution, f.l == f.lo, f.m = x.l = c
  B) c < 0: implies
     x = 0 is the solution, f.l == 0, f.m = x.l = 0, x.m = (-c)

For each case A) and B), we consider scaling the variable and the equation,
for a total of 4 cases.

Contributor: Steve Dirkse, May 2016
$offText

$if not set TESTTOL $set TESTTOL 1e-6
scalars tol / %TESTTOL% /;
scalar c;
positive variable x;
equation f;
f.. x =G= c;
model m / f.x /;

sets
  case / cpos, cneg /
  val  / 'f.F', 'f.m', 'x.L', 'x.m' /
  ;
parameters
  unscaled(case,val) 'results with no scaling'
  scaledX(case,val)  'results with x scaled'
  deltaX(case,val)   'unscaled - scaledX'
  scaledF(case,val)  'results with f scaled'
  deltaF(case,val)   'unscaled - scaledF'
  ;

* case A  c > 0
c = 2;
solve m using mcp;
abort$[abs(f.l-c)  > tol] 'bad f.l==c', f.l, c;
abort$[abs(f.m-c)  > tol] 'bad f.m==c', f.m, c;
abort$[abs(x.l-c)  > tol] 'bad x.l==c', x.l, c;
abort$[abs(x.m-0)  > tol] 'bad x.m==0', x.m;
unscaled('cpos','f.F') = round(f.L - f.lo, 5);
unscaled('cpos','f.m') = round(f.m, 5);
unscaled('cpos','x.L') = round(x.L, 5);
unscaled('cpos','x.m') = round(x.m, 5);

* case B  c < 0
c = -4;
solve m using mcp;
abort$[abs(f.l-0)  > tol] 'bad f.l==0', f.l;
abort$[abs(f.m-0)  > tol] 'bad f.m==0', f.m;
abort$[abs(x.l-0)  > tol] 'bad x.l==0', x.l;
abort$[abs(x.m+c)  > tol] 'bad x.m==-c', x.m, c;
unscaled('cneg','f.F') = round(f.L - f.lo, 5);
unscaled('cneg','f.m') = round(f.m, 5);
unscaled('cneg','x.L') = round(x.L, 5);
unscaled('cneg','x.m') = round(x.m, 5);

m.scaleopt = 1;

* ========== row scaling ==========
f.scale = 10;
* case A  c > 0
c = 2;
solve m using mcp;
scaledF('cpos','f.F') = round(f.L - f.lo, 5);
scaledF('cpos','f.m') = round(f.m, 5);
scaledF('cpos','x.L') = round(x.L, 5);
scaledF('cpos','x.m') = round(x.m, 5);

* case B  c < 0
c = -4;
solve m using mcp;
scaledF('cneg','f.F') = round(f.L - f.lo, 5);
scaledF('cneg','f.m') = round(f.m, 5);
scaledF('cneg','x.L') = round(x.L, 5);
scaledF('cneg','x.m') = round(x.m, 5);
f.scale = 1;

* ========== col scaling ==========
x.scale = 100;
* case A  c > 0
c = 2;
solve m using mcp;
scaledX('cpos','f.F') = round(f.L - f.lo, 5);
scaledX('cpos','f.m') = round(f.m, 5);
scaledX('cpos','x.L') = round(x.L, 5);
scaledX('cpos','x.m') = round(x.m, 5);

* case B  c < 0
c = -4;
solve m using mcp;
scaledX('cneg','f.F') = round(f.L - f.lo, 5);
scaledX('cneg','f.m') = round(f.m, 5);
scaledX('cneg','x.L') = round(x.L, 5);
scaledX('cneg','x.m') = round(x.m, 5);
x.scale = 1;

deltaX(case,val) = unscaled(case,val) - scaledX(case,val);
deltaF(case,val) = unscaled(case,val) - scaledF(case,val);
deltaX(case,val) = round(deltaX(case,val), 5);
deltaF(case,val) = round(deltaF(case,val), 5);

execute_unload 'rrrr';

abort$((card(deltaX) + card(deltaF)) > 0) '** FAIL, check file rrrr.gdx for details **';