Wednesday, August 26, 2009

GAMS: $loaddc vs $load

In GAMS models I often see $load being used to read data from a GDX file where $loaddc is more appropriate. Here is why.

GAMS has the concept of domain checking (like type checking in programming languages). E.g. when we do

GAMS File Data File

set c 'cities' /
   Chicago
   Houston
   NewYork
   Phoenix
/;
parameter pop(c) 'population' /
$include population.inc
/;

Houston      2242193
Chicago      2853114
NYC          8363710
Phoenix      1567924

This fragment has a problem: the key for New York is not identical. So GAMS will issue an error message

  11  NYC          8363710
****    $170
**** LINE      3 INCLUDE     C:\projects\test\population.inc
**** LINE      8 INPUT       C:\projects\test\domain.gms
**** 170  Domain violation for element

Now we do the same with a GDX file, and $load:

GAMS File Data File

set c 'cities' / 
   Chicago
   Houston 
   NewYork
   Phoenix 
/;
parameter pop(c) 'population';
$gdxin population.gdx
$load pop

display pop;

pop

When we run this fragment, we don’t see any error or warning! Of course the data is wrong: the population of New York is not read and is kept at its default value of zero. The display shows:

----     10 PARAMETER pop  population

Chicago 2853114.000,    Houston 2242193.000,    Phoenix 1567924.000

The $load is just too unreliable to be used for anything that is larger than can be inspected by eye-balling. Compared to an old-fashioned include file it is really a step back.

A fixed version of $load was introduced later and is called $loaddc:

GAMS File Data File

set c 'cities' / 
   Chicago
   Houston 
   NewYork
   Phoenix 
/;
parameter pop(c) 'population';
$gdxin population.gdx
$loaddc pop

pop

This will enforce domain checking:

--- LOAD  pop = 1:pop
**** 1 Domain errors for symbol pop
     NYC
   9  $loaddc pop
****            $649
**** 649  Domain violation when loading from GDX file

In general $load’s should not be used. In some rare special cases a $load can be used to select from a larger data set, but then you should add extra checks to prevent a situation as described here to slip through without error.