cns03.gms : CNS test - holdfixed and singular models

Description

This model is singular if it is square.
The way it is reported depends on
whether holdfixed is turned on or off.


Small Model of Type : CNS


Category : GAMS Test library


Main file : cns03.gms

$title CNS test - holdfixed and singular models (cns03,SEQ=93)

$onText
  This model is singular if it is square.
  The way it is reported depends on
  whether holdfixed is turned on or off.

$offText

maxexecerror = 1;
$if not set TESTTOL $set TESTTOL 1e-6
scalar tol / %TESTTOL% /;
$if not set SLOWOK $set SLOWOK 0
scalar slowOK 'slow solves are OK: just abort.noerror in this case' / %SLOWOK% /;
scalar havesol / 0 /;

variable x1,x2,x3;
equation e1,e2;

e1 .. x1 =e= 5;
e2 .. x1 + x2 +x3 =e= 7;

x1.fx = 5;

model m / all /;

* Case 1: with holdfixed=0, GAMS passes on a square 2x2 model
*         in x2 and x3 - x1 is ignored since it is fixed
m.holdfixed = 0;
solve m using cns;
abort.noError$[slowOK and %solveStat.resourceInterrupt% = m.solvestat] 'Solve too slow';
abort$(m.solvestat <> %solveStat.normalCompletion%) 'bad solvestat', m.solvestat;
if   { (m.modelstat = %modelStat.locallyInfeasible%),
* locally infeasible, should report a row that way
  abort$(m.numinfes < 1)                            'wrong .numinfes';
* this next check may be too ambitious - we'll see how it flies
  abort$(m.numdepnd < 1)                            'wrong .numdepnd';
elseif (m.modelstat = %modelStat.solvedSingular%),
* solved singular, should indicate that one dependency exists
  havesol = 1;
  abort$(m.numdepnd <> 1)                           'wrong .numdepnd';
else
  havesol = 1;
  abort$(m.modelstat <> %modelStat.solved%) 'bad modelstat', m.modelstat;
};
if {havesol,
  abort$(abs(x2.l+x3.l-2) > tol)     'bad x2.l+x3.l';
  abort$(abs(e1.l-5) > tol)          'bad e1.l';
  abort$(abs(e2.l-7) > tol)          'bad e2.l';
};

* The following test is about specific behavior with respect to "holdFixed".
* Since this is reset with asyncronous solves, exit early in the following cases
$ifE %GAMS.solveLink%=%solveLink.asyncGrid%       $exit
$ifE %GAMS.solveLink%=%solveLink.asyncSimulate%   $exit
$ifE %GAMS.solveLink%=%solveLink.aSyncThreads%    $exit
$ifE %GAMS.solveLink%=%solveLink.threadsSimulate% $exit


* Case 2: with holdfixed=1, GAMS reduces the model to something that
*         is not square. It takes out x1 and e1 and is left with 2
*         variables (x2 & x3) and 1 equation.
m.holdfixed = 1;
solve m using cns;
abort.noerror$[slowOK and %solvestat.ResourceInterrupt% = m.solvestat] 'Solve too slow';
abort$(execerror=0) 'previous solve should have given exec errors';
abort$(m.solvestat <> %solveStat.solveProcessingSkipped% or m.modelstat <> %modelStat.noSolutionReturned%)
   'bad return codes', m.solvestat, m.modelstat;
execerror = 0;