User Tools

Site Tools


gams:loop_over_file_names

How do I loop over file names?

Q: I 've written a GAMS program using the xls2gms function to upload data and the execute_unload function to save the final result. However, I need to run the same GAMS code for 50 different countries, which means I have 50 different xls input files. Is there a way to loop over file names so that I can change the input file and the output file each time (e.g. Input_file_CountryX.xls, Results_CountryX.gdx) ?

-----------------------
*Read data from external spreadsheet
$call =xls2gms i=Input_file_Country1.xls r1=Sets!set_i
o1=industries.set r2=Sets!set_o o2=occupations.set r3=Wages!matrixB
o3=matrixB.inc r4=Sets!MatrixA o4=Average.inc

set i /
$include industries.set
/;
set o /
$include occupations.set
/;
**************
*Define B from external spreadsheet
Table B(o,i) degree of belief
$include matrixB.inc
;
Parameter avg(i) average by industry/
$include Average.inc
/;
**************

Equations, Objective Function, etc.

**************
*Run the model to get results
 Model WAGES /objective/;
 Solve WAGES using dnlp minimizing find_min;
 Display w.l, w.m;
**************
*Export results to Excel by creating a .gdx file
execute_unload "Results_Country1.gdx" w.L w.M
execute 'gdxxrw.exe Results_Country1.gdx var=w.L'

You could use GAMS as a platform independent scripting language. For example you could change your program to parametrize the file names:

Change the following lines:

$call =xls2gms i=Input_file_Country1.xls r1=Sets!set_i...
...
execute_unload "Results_Country1.gdx" w.L w.M
execute 'gdxxrw.exe Results_Country1.gdx var=w.L'

to

$call =xls2gms i=Input_file_%instance%.xls r1=Sets!set_i...
...
execute_unload "Results_%instance%.gdx" w.L w.M
execute 'gdxxrw.exe Results_%instance%.gdx var=w.L'

Now, when you call your GAMS program you supply the instance name by adding –instance=Country1 to the GAMS call. Create a second GAMS model e.g. run.gms that contains the following information:

$call gams mymodel.gms --instance=Country1
$if errorlevel 1 $abort 'problems with instance Country1'
$call gams mymodel.gms --instance=Country2
$if errorlevel 1 $abort 'problems with instance Country2'
...
$call gams mymodel.gms --instance=Country50
$if errorlevel 1 $abort 'problems with instance Country50'

If you want to keep the log and lst file from the individual runs, use GAMS parameters lo, o and lf:

$call gams mymodel.gms --instance=Country1 lo=2 o=Country1.lst
lf=Country1.log
$if errorlevel 1 $abort 'problems with instance Country1'
...

Moreover, you could use GAMS to create the model run.gms: Create another GAMS model makerun.gms:

set i instances /1*50/;

file frun / run.gms /; put frun '* Run file to run ' card(i):0 '
instances of mymodel';
loop(i,
 put / '$call gams mymodel.gms --instance=Country' i.tl:0 ' lo=2 o=Country' i.tl:0 '.lst lf=Country' i.tl:0 '.log'
     / "$if errorlevel 1 $abort 'problems with instance Country"
i.tl:0 "'";
);

Another approach using the put_ utility is shown here.

gams/loop_over_file_names.txt · Last modified: 2009/03/04 14:14 by support