nlcode2.gms : Test limits on nonlinear code length per block

Description

```Test that we can have equation blocks with close to the maximum
number of NL instructions per block, and that we can do this
for two blocks at once.
This puts the total count over the per-block limit, which should not
cause any problems.
If the limits in GAMS/Base are changed, change maxInsPerBlock below.
Could we get maxInsPerBlock from GAMS/Base?

Limit for non-linear instruction code is now 2147483k. It is the same for the
block. We can not test it on all out machines because of memory limitations.
this check requires a license
```

Small Model of Type : GAMS

Category : GAMS Test library

Main file : nlcode2.gms

``````\$title Test limits on nonlinear code length per block (NLCODE2,SEQ=110)

\$ontext
Test that we can have equation blocks with close to the maximum
number of NL instructions per block, and that we can do this
for two blocks at once.
This puts the total count over the per-block limit, which should not
cause any problems.
If the limits in GAMS/Base are changed, change maxInsPerBlock below.
Could we get maxInsPerBlock from GAMS/Base?

Limit for non-linear instruction code is now 2147483k. It is the same for the
block. We can not test it on all out machines because of memory limitations.
\$offtext
* this check requires a license
\$if not set DEMOSIZE      \$set DEMOSIZE   0
\$if not %DEMOSIZE% == 0   \$exit

scalars
ins1, insDelta,
maxInsPerBlock / 16777216 /;

sets   I     / i1 * i2000 /,
II(I) / i1 * i2 /,
J     / j1 * j1000 /;

parameter c(J), b(J);
b(J) = uniform(0.5,1.5);
c(J) = uniform(0,2);

free variable v(I), z;
positive variable x(J);
x.lo(J) = c(J) + 1e-4;

equations f(I), g(I), obj;

* ugly and strange way to write v = sum {.., sqr(x-c)}

f(II).. v(II) =g= sum {J, (x(J)-c(J))**b(J) * (x(J)-c(J))**(2-b(J))};
g(II).. v(II) =g= sum {J, (x(J)-c(J))**b(J) * (x(J)-c(J))**(2-b(J))};

obj..  z =e= sum{II, v(II)} / card(II);

model m / obj, f, g /;

* to get a dump of the NL instructions do this
* option sys3 = 3;

option limrow = 0, limcol = 0;
m.solprint = %SOLPRINT.Summary%;

II(I) = (ord(I) le 1);
solve m using nlp min z;
display m.numnlins;
abort\$(m.solvestat <> %solvestat.NormalCompletion% or (m.modelstat > %modelstat.LocallyOptimal% and m.modelstat <> %modelstat.FeasibleSolution%))  'wrong status codes';
ins1 = m.numnlins;

II(I) = (ord(I) le 2);
solve m using nlp min z;
display m.numnlins;
abort\$(m.solvestat <> %solvestat.NormalCompletion% or (m.modelstat > %modelstat.LocallyOptimal% and m.modelstat <> %modelstat.FeasibleSolution%))  'wrong status codes';
insDelta = m.numnlins - ins1;

* now bump up size enough so the total is greater
* than the amount allowed in one block, but each block is OK
* card(II)*insDelta =~ 1.9 * maxInsPerBlock
II(I) = yes\$(ord(I) <= 1.9 * maxInsPerBlock / insDelta);
solve m using nlp min z;
display m.numnlins;
* just check that we're in the ballpark here
abort\$(m.numnlins gt 1.99 * maxInsPerBlock) 'wrong instruction count';
abort\$(m.numnlins lt 1.85 * maxInsPerBlock) 'wrong instruction count';
abort\$(m.solvestat <> %solvestat.NormalCompletion% or (m.modelstat > %modelstat.LocallyOptimal% and m.modelstat <> %modelstat.FeasibleSolution%))  'wrong status codes';

* now bump up size enough to trigger an error for
* too many NL instructions in an equation block
II(I) = yes\$(ord(I) <= 2.2 * maxInsPerBlock / insDelta);

* we do not have a good way to test for this yet!
\$exit

solve m using nlp min z;
display m.numnlins;

abort\$(m.solvestat <> %solvestat.NormalCompletion% or m.modelstat <> %modelstat.Optimal%)  'wrong status codes';
``````
GAMS Development Corp.
GAMS Software GmbH

General Information and Sales
U.S. (+1) 202 342-0180
Europe: (+49) 221 949-9170