Monday, September 27, 2010

GAMS macro problems

I am working on a model that is using the preprocessor tool described in http://www.mpsge.org/inclib/gams-f.htm. There were a few minor issues related to this tool:

  1. It does not really work very well with the GAMS IDE. You cannot click on the red error messages to bring you to the input line with the error.
  2. It does not handle combined use in equations and parameter assignments in post-solve reporting very well.

The documentation of the new $macro facility in GAMS (http://www.gams.com/docs/release/release.htm, section “The GAMS Macro Facility” ) seems to indicate that it can be used to replace the preprocessor tool: just use $macro and use set.local where needed. Unfortunately that is not completely true. Especially the sentence “The .local feature has been added to ensure local use and eliminates the need for new alias definitions.” is plain wrong.

Here is a simple model to illustrate the problem:

$sysinclude gams-f

set i /i1*i3/;
alias (i,j);

parameter x(i,j);
x(i,j) = normal(0,1);

*-----------------------------------------------------

parameter p(i) 'without macro/preproc';
p(i) =
sum(j, x(i,j));
display p;

*-----------------------------------------------------

y(i) ==
sum(j, x(i,j));

parameter p1(j) 'with preproc';
p1(j) = y(j);
display p1;

*-----------------------------------------------------

$macro y2(i) [sum(j.local, x(i,j))]

parameter p2(j) 'with macro';
p2(j) = y2(j);
display p2;

This shows:

----     26 PARAMETER p  without macro/preproc

i1  0.478,    i2 -3.533,    i3 -0.219

----     49 PARAMETER p1  with preproc

i1  0.478,    i2 -3.533,    i3 -0.219

----     57 PARAMETER p2  with macro

i1 -1.804,    i2 -1.804,    i3 -1.804

The cause can be found in the listing file:

35  ALIAS(FCN000,j);
36  
37  
38  
39  parameter p1(j) 'with preproc';
40  p1(j) =
41  
42  *       #### Preprocessor function replacement for Y ####
43  
44  (
45   sum(FCN000, x(j,FCN000))
46  )
…….
55  parameter p2(j) 'with macro';
56  p2(j) = [sum(j.local, x(j,j))];

Clearly the GAMS-F preprocessor handles this case correctly by introducing an alias. The $macro/.local combination does not do this and gives the wrong results. Instead of this .local hack it is needed to manually introduce an alias and use the aliased set where needed.

It is noted that overuse of these tools can lead to models that appear smaller (fewer equations and variables). However those models may be much denser and much more nonlinear (say in terms of nonlinear nonzero elements). Often larger, sparser and less non-linear models solve easier.