miqcp03.gms : Test modsolstat and solution correctness - multiple QCons and binaries

Description

Modified from QCP04 to include binary variables

Contributor: Toni Lastusilta


Small Model of Type : MIQCP


Category : GAMS Test library


Main file : miqcp03.gms

$TITLE Test modsolstat & solution correctness - multiple QCons & binaries (MIQCP03,SEQ=603)

$ontext
Modified from QCP04 to include binary variables
 
Contributor: Toni Lastusilta
$offtext


$if not set DEMOSIZE      $set DEMOSIZE   0
$if not set GLOBALSIZE    $set GLOBALSIZE 0
$if not %DEMOSIZE% == 0   $set DEMOSIZE   1
$if not %GLOBALSIZE% == 0 $set GLOBALSIZE 1

* set default N based on license and type of solver
$if %DEMOSIZE%%GLOBALSIZE% == 00 $set NN  25
$if %DEMOSIZE%%GLOBALSIZE% == 01 $set NN   6
$if %DEMOSIZE%%GLOBALSIZE% == 10 $set NN  14
$if %DEMOSIZE%%GLOBALSIZE% == 11 $set NN   3

$if not set N       $set N %NN%
$if not set MTYPE   $set MTYPE miqcp
$if not set TESTTOL $set TESTTOL 1e-6
scalar mchecks / 0 /;
$if not set QCPMCHECKS $goto qpmchecks
$if not %QCPMCHECKS% == 0 mchecks = 1;
$goto donemcheck
$label qpmchecks
$if not  %QPMCHECKS% == 0 mchecks = 1;
$label donemcheck

$eolcom //

set i /1*%N%/;
variables x(i), y(i), z;
binary variable b(i);
scalar bigM /100/;
parameter xp(i), yp(i);

xp(i) = uniform(0,1);
yp(i) = uniform(0,1);
* set some inactive bounds to keep the global solvers happy
x.lo(i) = -1.1;  x.up(i) = 1.1;
y.lo(i) = -1.1;  y.up(i) = 1.1;

equation defc, defz, afew;

defc(i).. sqr(x(i)) + sqr(y(i)) =L= 1 + bigM*b(i);
defz..    z =E= sum(i,xp(i)*x(i) + yp(i)*y(i));
afew..    sum(i, b(i)) =l= max(2,card(i)*0.01);

model m /all/;
m.limrow=0; m.limcol=0;
option optcr = 0;
solve m min z using %MTYPE%;

* disable mchecks if no marginals available
if(not m.marginals, mchecks = 0);

scalars
    vtol    /    1e-8 /,
    tol     /    %TESTTOL% /,
    objval;
parameters
    dLdx(i)  'dLangrangian/dx',
    dLdy(i)  'dLangrangian/dy',
    defc_l(i);

scalar nrtests  'number of marginals that will be tested';
nrtests = sum(i$(not b.l(i)), 1);
display nrtests;

abort$(nrtests = 0)                                   'all binaries at 1, so nothing tested';

* capability problems is an OK return
if {(m.solvestat = %solvestat.CapabilityProblems%),
  abort$(m.modelstat <> %modelstat.NoSolutionReturned%)           'wrong modelstat for capability error';
  display 'Solver capability error: further tests suppressed';
else
  abort$(m.modelstat <> %modelstat.Optimal% and m.modelstat <> %modelstat.LocallyOptimal% and m.modelstat <> %modelstat.FeasibleSolution% and m.modelstat <> %modelstat.IntegerSolution%)  'do not have feasible solution';

  objval = sum(i,xp(i)*x.l(i) + yp(i)*y.l(i));
  loop(i,
    if(b.l(i)=0,
      dLdx(i)   = xp(i) - defc.m(i) * 2 * x.l(i);
      dLdy(i)   = yp(i) - defc.m(i) * 2 * y.l(i);
      defc_l(i) = sqr(x.l(i)) + sqr(y.l(i));
    else
      defc_l(i) = 1;
      defc.l(i) = 1;
      defc.m(i) = 0;
      dLdx(i)   = 0;
      dLdy(i)   = 0;
    );
  );
  display defc_l, dLdx, dLdy;
  abort$(abs(z.l-objval) > tol)                       'bad z.l';
  abort$(abs(defz.l) > tol)                           'bad defz.l';

  abort$(smax{i,defc_l(i) - 1} > tol)                 'bad defc';
  abort$(smax{i,abs(defc.l(i)-defc_l(i))} > tol)      'bad defc.l';

  if {mchecks,
    abort$(abs(z.m) > tol)                            'bad z.m';
    abort$(abs(defz.m-1) > tol)                       'bad defz.m';
    abort$(smax{i,defc.m(i)} > tol)                   'bad defc.m';
    abort$(smax{i,abs(dLdx(i))} > tol)                'bad dLdx';
    abort$(smax{i,abs(dLdy(i))} > tol)                'bad dLdy';
  };
  display 'All tests passed';
};