Tuesday, June 3, 2008

Loops over different data sets

See http://groups.google.com/group/sci.op-research/browse_thread/thread/78456e35ddfc7141. This is actually a question that is often asked. The answer is really dependent on the situation. In this case the single case digests the input during compile time (using $include). This can not be coded directly by placing a loop around it (a loop is runtime). In this case it would probably the easiest the implement the single case as a complete GAMS file passing on the name of the input file and the output file as command line parameters. I.e.

* %input% is input file name (XLS file)
* %output% is output gdx file

$if not set input $set input E:\simuldata1\datag1.xls
$if not set output $set output E:\simuldata\data1.xls

Set s1 /
$call =xls2gms "i=%input%" o=E:\work\dataif1.inc R=datag1!a2:a12
$include E:\work\dataif1.inc
/;

Parameter p(s1) /
$call =xls2gms "i=%input%" o=E:\work\data21.inc R=datag1!j2:k12
$include E:\work\data2l.inc
/;

......

Execute_Unload "data2.gdx" V1
Execute 'GDXXRW.EXE data2.gdx sq=0 o=%output% var=V1 rng=sheet2!e2 rdim=1';


Note: the $if statements allow the model to be run outside the loop as well.

Now generate the loop in a separate GAMS file:

set i /1*100/;

file f /x.cmd/;

loop(i,
put f,"gams singlecase "
"--input=E:\simuldata" i.tl:0 "\datag" i.tl:0 ".xls "
"--output=E:\simuldata\data" i.tl:0 ".xls "
"O=E:\simuldata\singlecase" i.tl:0 ".lst"/;
);
putclose f;

execute "x.cmd";

This will generate a batch file:

gams singlecase --input=E:\simuldata1\datag1.xls --output=E:\simuldata\data1.xls O=E:\simuldata\singlecase1.lst
gams singlecase --input=E:\simuldata2\datag2.xls --output=E:\simuldata\data2.xls O=E:\simuldata\singlecase2.lst
gams singlecase --input=E:\simuldata3\datag3.xls --output=E:\simuldata\data3.xls O=E:\simuldata\singlecase3.lst
gams singlecase --input=E:\simuldata4\datag4.xls --output=E:\simuldata\data4.xls O=E:\simuldata\singlecase4.lst
gams singlecase --input=E:\simuldata5\datag5.xls --output=E:\simuldata\data5.xls O=E:\simuldata\singlecase5.lst
....

Instead of writing a batch file it is also possible to directly generate a command line using the infamous put_utility command:

put_utility "shell" / "gams singlecase --input=E:\simuldata" i.tl:0 "\datag" i.tl:0 ".xls --output=E:\simuldata\data" i.tl:0 ".xls O=E:\simuldata\singlecase" i.tl:0 ".lst";

Probably the best is to consult support@gams.com as this is very hairy.

Often it is better to reorganize the data flow and read all data in the beginning, then perform a loop to calculate the results, and then export all results. The input data and results have then an extra index.