Loading...
Searching...
No Matches
Container

A GAMS Transfer Matlab container stores a collection of symbols and is therefore comparable to a GDX file.

It is indeed a fundamental feature of containers to read from or write to GDX files. GDX files can be operated in two different modes, default and indexed, which are also supported by GAMS Transfer Matlab containers, see Indexed GDX for more info.

Creating a Container

Creating a container is easy. Either:

  • Create an Empty Container:
    c = Container();
  • Create a Container With Symbols From a GDX File:
    c = Container('path/to/file.gdx');
  • Create a Container With Symbols From Another Container:
    c1 = Container('path/to/file.gdx');
    ...
    c2 = Container(c1);
Note
On default, GAMS Transfer Matlab tries to find the GAMS system directory using the PATH environment variable (this is not the Matlab path). Whether GAMS was found, can be checked by looking at c.gams_dir (empty string = not found). Alternatively, one can pass a GAMS system path to the Container constructor: c = Container("gams_dir", "path/to/gams");.

Reading From GDX

Above was a first example of how to read a whole GDX file into a container. But often it is useful to only read certain symbols or to specify the records format. With the container's Container.read method, you get more control.

Consider for the following that c is some container and source is either a GDX file (e.g. source = "path/to/file.gdx") or another container object. Then:

  • Reading all Symbols:
    Read in a all symbols with
    c.read(source);
  • Reading a Subset of Symbols:
    In order to only read the symbols x and z from a GDX file, do
    c.read(source, 'symbols', {'x', 'z'});
  • Reading Symbols in a Certain Records Format:
    GAMS Transfer can load the symbol records into different Matlab data structures also referred to as records format. There are struct, table (default), dense_matrix and sparse_matrix, each with certain advantages and disadvantages. In order to read in a symbols as dense_matrix, do
    c.read(source, 'format', 'dense_matrix');
  • Reading a Subset of Symbol Values:
    Finally note that GDX files store multiple values per symbol. Sets have element_text, Parameters have value and Equations and Variables have level, marginal, lower, upper, scale, see Records for more information. On default, all values are read, but you can select a subset by
    c.read(source, 'values', {'level', 'marginal'});
    Note that here, level also enables element_text and value. Moreover, marginal has no influence on Sets and Parameters. It is even possible to specify no values in order to read none GDX records. This would then only read the symbol meta data like name or description.
  • ...and of course it is possible to mix and match all the above.
Note
When reading from different GDX files it can happen that two different symbols have the same name. It is currently not possible to rename a symbol on load or to merge symbol contents, for example. GAMS Transfer Matlab will simply raise an error.

Writing To GDX

A container with all symbols and symbol records can be written to a GDX file with it's Container.write method. It is possible to write a compressed GDX file. Simply write with:

  • Writing all Symbols:
    Write all symbols to a GDX file with
    c.write('path/to/file.gdx');
  • Writing a Subset of Symbols:
    In order to only write the symbols x and z to a GDX file, do
    c.write('path/to/file.gdx', 'symbols', {'x', 'z'});
  • Writing a Compressed GDX File:
    In order to write compressed, set the parameter compress to true:
    c.write('path/to/file.gdx', 'compress', true);
Note
It is not possible to write the container if any of the symbols to write is not valid (see also Validate Symbol Records). Further note that a symbol can be considered valid but still has domain violations, which would lead to an error when writing, see also Domain Violations.
Advanced Users Only:
GDX expects the symbol records to be sorted in a certain order. Since this can be difficult for the user to achieve, the records are sorted (without overwriting) on default when writing to GDX. Users who know that their symbol records are sorted correctly, can set the Container.write method argument sorted to true in order to improve efficiency. Symbol records dense_matrix and sparse_matrix are sorted per definition (sorted has no effect). GDX expects the following order for struct and table formats. Symbol records are sorted by domain UEL codes in ascending order w.r.t. dimension 1 first, then 2, then 3, etc. However, UEL codes are here not relative to the symbol, but global to the whole container where only the first occurence is relevant. This also means that symbol order within a container also influences the UEL order and hence symbol record order. The method Container.getUELs returns this global UEL ordering and can be a help to establish the correct ordering. Note that Container.getUELs creates this set only on request and is not very efficient.

Naming Symbols

GAMS Transfer follows the GDX convention for naming symbols. That means, symbol names can consist of alpha-numeric characters and _ (but not at the beginning). Name length must be shorter than 64. Symbol names are considered case insensitive, i.e. adding a symbol named X after adding x is not allowed because the names are considered equal. Methods that accept symbol names as input, accept symbol names in any case.

To get the original names of symbols registered in a container, use Container.getSymbolNames. To check if a symbol exists, use Container.hasSymbols. For example consider a container m with symbol sym1:

>> m.hasSymbols({'Sym1', 'sym1', 'sYM1'})
ans =
1×3 logical array
1 1 1
>> m.getSymbolNames({'Sym1', 'sym1', 'sYM1'})
ans =
1×3 cell array
{'sym1'} {'sym1'} {'sym1'}

Accessing Symbols

Symbols are stored in the struct Container.data, with fieldnames equal to the symbol names. For Example this is:

>> m.data
ans =
struct with fields:
i: [1×1 gams.transfer.Set]
j: [1×1 gams.transfer.Set]
a: [1×1 gams.transfer.Parameter]
b: [1×1 gams.transfer.Parameter]
d: [1×1 gams.transfer.Parameter]
f: [1×1 gams.transfer.Parameter]
c: [1×1 gams.transfer.Parameter]
x: [1×1 gams.transfer.Variable]
z: [1×1 gams.transfer.Variable]
cost: [1×1 gams.transfer.Equation]
supply: [1×1 gams.transfer.Equation]
demand: [1×1 gams.transfer.Equation]

In addition to accessing Container.data directly, symbol handle lists can be queried via the methods Container.getSets, Container.getParameters, Container.getVariables, Container.getEquations, Container.getAliases or via Container.getSymbols given a list of symbol names.

>> vars = transpose(m.getSymbols({'x', 'z'}))
vars =
1×2 cell array
{1×1 gams.transfer.Variable} {1×1 gams.transfer.Variable}

This can be particularly useful in combination with the functions Container.listSymbols, Container.listSets, Container.listAliases, Container.listParameters, Container.listVariables and Container.listEquations that list the names of symbols of the corresponding type, as shown below:

>> transpose(m.listVariables())
ans =
1×2 cell array
{'x'} {'z'}
>> vars = transpose(m.getSymbols(m.listVariables()))
vars =
1×2 cell array
{1×1 gams.transfer.Variable} {1×1 gams.transfer.Variable}
>> {vars{1}.name, vars{2}.name}
ans =
1×2 cell array
{'x'} {'z'}
Note
When accessing the symbols via Container.data, then the case of characters matters. This is not the case for Container.getSymbols.

Removing Symbols

To remove a symbol from the Container, simply call Container.removeSymbols:

m.removeSymbols('x');
m.removeSymbols({'a', 'b'});
Attention
If a Set is removed from the Container, a handle to that Set can still exist as a domain of another symbol or be linked to by an alias. This will make these other symbols invalid, see isValid.

Reordering Symbols

The GDX file requires the symbols to be sorted such that, for example, a Set used as domain of another symbol appears before that symbol. The Container will try to establish a valid ordering when writing the data to GDX. However, this operation can also be invoked manually by calling the method Container.reorderSymbols.

Symbol Overview

The methods Container.describeSets, Container.describeAliases, Container.describeParameters, Container.describeVariables and Container.describeEquations allow for an overview over the symbols of the corresponding type stored in the Container. These methods return a table listing for each symbol the properties / statistics given in the following table. Here, an x means that this property / statistic is available for the symbol type.

Property / Statistic Description Set Alias Parameter Variable Equation
name Name of symbol x x x x x
is_singleton Indicates if set is a singleton set (true) or not (false) x x
alias_with Set an alias is linked to x
type Variable or Equation type, see VariableType and EquationType x x
format Format records are stored in, see Records Format x x x x x
dimension Dimension of symbol x x x x x
domain_type Type of domain, e.g. relaxed or regular x x x x x
domain Domain of symbol x x x x x
size Size or shape of symbol x x x x x
number_records Number of symbol GDX records x x x x x
number_values Number of stored records values x x x x x
sparsity Sparsity of symbol records w.r.t. to count x x x x x
min Minimum value x
mean Mean value x
max Maximum value x
where_min Domain entry of record with minimum value x
where_max Domain entry of record with maximum value x
min_level Minimum value of level values x x
mean_level Mean value of level values x x
max_level Maximum value of level values x x
where_max_abs_level Domain entry of record with maximum absolute level value x x

For Example, this looks like:

>> tbl = m.describeVariables();
>> tbl(:,1:9)
ans =
2×9 table
name type format dimension domain_type domain size number_records number_values
____ ________ ______ _________ ___________ ______ _____ ______________ _____________
x positive table 2 regular [i,j] [2,3] 6 30
z free table 0 none [] [] 1 5
>> tbl(:,10:14)
ans =
2×5 table
sparsity min_level mean_level max_level where_max_abs_level
________ _________ __________ _________ ___________________
0 0 150 300 [seattle,chicago]
0 153.68 153.68 153.68 []

Indexed GDX

GDX files can be operated in two different modes, default and indexed (also called IDX), which are also supported by GAMS Transfer Matlab containers:

The mode – default or indexed – can be specified when creating a Container and cannot be changed thereafter:

c = Container('indexed', true);

In indexed mode, pass the shape of the symbol instead of the domain to the symbol constructor. For example, to create a 2x3 matrix parameter, do:

d = Parameter(m, 'd', [2, 3], 'description', 'distance in thousands of miles');
Note
The only supported symbols in indexed mode are Parameters.
In indexed mode it is not possible to set the property domain or using the UEL related methods (e.g. getUELs or setUELs), while in default mode the property size cannot be set and is inferred from by the domain.