zerofunc.gms : Match unmatched vars with zero functions in VI

Description

If the feasible set is defined in terms of variables that don't appear
in the VI function F, we should not need to mention these variables
explicitly in a match.  Any unmatched variable will be treated as
matched to the zero function.  The optimization analogy is variables
that appear in the constraints but not in the objective.  We
test/define the proper behavior in this model.

Contributor: Steven Dirkse, February 2009


Small Model of Type : VI


Category : GAMS EMP library


Main file : zerofunc.gms

$title Match unmatched vars with zero functions in VI (ZEROFUNC,SEQ=18)

$onText

If the feasible set is defined in terms of variables that don't appear
in the VI function F, we should not need to mention these variables
explicitly in a match.  Any unmatched variable will be treated as
matched to the zero function.  The optimization analogy is variables
that appear in the constraints but not in the objective.  We
test/define the proper behavior in this model.

Contributor: Steven Dirkse, February 2009

$offText


$onText
First we define an NLP in two variables, then write down the MCP version,
then write down the VI version.

     General case                       Specific case
NLP: min f(x)                           1/3 y^3
    s.t. g(x) >= 0                      y >= sqr(z)
        L <= x <= U                     y, z free

MCP: take derivatives of Lagrangian function wrt x,u
     dfdx - u * dgdx  perpto x          y^2 - u*1  perpto y free
                                        0   + u*2z perpto z free
     g(x)             perpto u >= 0     y - sqr(z) perpto u >= 0

VI:  F(x) := dfdx,                      F_y := y^2
                                        F_z := 0
 X = {x:g(x) >= 0, L <= x <= U }        y >= sqr(z), y, z in bounds

All of this to show/test that it is not necessary to include the pair
F_z.z in the model statement, and that since z is not mentioned
explicitly in a match, it is matched with the zero function.
$offText

free variables y, z;
free variable obj;
equation objDef, gCons;

objDef..  obj =E= power(y,3) / 3;
gCons..   y   =G= sqr(z);

model mNLP / objDef, gCons /;
solve mNLP min obj using nlp;


positive variable u 'explicit multiplier for MCP';
u.l = gCons.m;
equations
  dLdy, dLdz,
  dLdu;

dLdy..  sqr(y)     - u     =N= 0;
dLdz..  0          - u*2*z =N= 0;
dLdu..  y - sqr(z)         =N= 0;

model mMCP / dLdy.y, dLdz.z, dLdu.u /;
solve mMCP using mcp;
abort$[mMCP.iterusd > 0] 'should have started at MCP solution!';

equations
  F_y 'dfdy'
  F_z 'dfdz'
  ;
F_y.. sqr(y) =N= 0;
F_z.. 0 =N= 0;

model mVI / F_y, gCons /;
model mVI0 / F_z, F_y, gCons /;

$onText
N.B.: we test 4 equivalent ways to specify the same VI.  The VI statement
always contains the matching pair "F_y y" and "gCons", the equation defining
the constraint set. Each variant specifies the matching between the "z"
variable and the zero mapping differently. 
  1) z appears right after the "vi" keyword: it is in the VI and perpendicular
     to 0 (null) functions.
  2) z is matched with F_z := 0.
  3) z is matched with "0", representing zero functions.
  4) a variant of (3), where the order of the pair "0 z" and "F_y y" has been
     swapped.

Cases 3 and 4 use EMP info file syntax introduced with GAMS 25.1.

For this trivial case of a single VI these differences are not
important, but when combining VI models and max/min models as
different agents in an equilibrium model the differences do matter.
$offText

file myinfo / '%emp.info%' /;

* case 1)
putclose myinfo  'vi  z   F_y y  gCons' /;
solve mVI using emp;
abort$[mVI.modelStat <> %modelStat.locallyOptimal%] 'VI should solve OK';
abort$[mVI.solveStat <> %solveStat.normalCompletion%] 'VI should solve OK';
abort$[mVI.iterusd > 0] 'should have started at VI solution!';

* case 2)
putclose myinfo  'vi  F_z z  F_y y  gCons' /;
solve mVI0 using emp;
abort$[mVI0.modelStat <> %modelStat.locallyOptimal%] 'VI should solve OK';
abort$[mVI0.solveStat <> %solveStat.normalCompletion%] 'VI should solve OK';
abort$[mVI0.iterusd > 0] 'should have started at VI solution!';

* case 3)
putclose myinfo  'vi  0 z  F_y y  gCons' /;
solve mVI using emp;
abort$[mVI.modelStat <> %modelStat.locallyOptimal%] 'VI should solve OK';
abort$[mVI.solveStat <> %solveStat.normalCompletion%] 'VI should solve OK';
abort$[mVI.iterusd > 0] 'should have started at VI solution!';

* case 4)
putclose myinfo  'vi  F_y y  0 z  gCons' /;
solve mVI using emp;
abort$[mVI.modelStat <> %modelStat.locallyOptimal%] 'VI should solve OK';
abort$[mVI.solveStat <> %solveStat.normalCompletion%] 'VI should solve OK';
abort$[mVI.iterusd > 0] 'should have started at VI solution!';