I am attempting to read and write .gdx-files using the gams.transfer extension in Python. When I export a set using the container.write-method, the ordering of set elements appears to push members of a previously defined set to the “top” of any subsequently defined sets.
i.e.
import gams.transfer as gt
m=gt.Container()
r=gt.Container()
gt.Set(m,name=‘set1’,records=[‘1’,‘2’,‘3’,‘4’])
gt.Set(m,name=‘set2’,records=[‘0’,‘1’,‘2’,‘3’])
m.write(‘test_case_exported.gdx’)
r.read(‘test_case_exported.gdx’)
set2_exported=r[‘set2’].records
print(set2_exported.iloc[0,0])
prints ‘1’. Opening the .gdx-file confirms that the ordering of set2 becomes [‘1’,‘2’,‘3’,‘0’].
This behavior seems to be consistent and inherent to the container.write-method. It is furthermore consistent across gamspy and gams.transfer.
This appears to me as a bug, but I might have missed something
This appears to me as a bug, but I might have missed something
Assuming I understand your issue correctly, it looks like you are missing some of the GAMS conventions. Specifically, as stated in the documentation “in general, sets in GAMS are regarded as an unordered collection of labels.” For a set to be considered ordered, the initialization of the elements in the set should correspond to the order of the labels in the GAMS Entry order. In your example, Set1 would qualify, but Set2 would not, because the members of Set2 are not defined in the GAMS entry order. For a more accurate account, take a look at Ordered Sets in GAMS.
Hi Karl – Thanks for writing in, welcome to the GAMS forum! A quick tip… you can insert code blocks with the triple tick marks ``` on new lines before and after the code:
import gams.transfer as gt
It’s a nice markdown feature
On to your question… first off, this is not a bug but just how GAMS stores things internally. GAMS uses an internal list called the universe to organize the labels used in any symbol. These appear in order of first appearance. Might be helpful to understand that the labels really are strings (internally)… even if you use numeric types. A lot of this is described in more detail in the link that @Aleh shared.
As for gams.transfer you can get the universe by calling m.getUELs(). This computes the equivalent GAMS universe… The exciting thing about gams.transfer is that you can work with the labels before writing the GDX file. This allows you to customize all your labeling conventions. There is a lot more information on this docs page: UNIVERSE_SET.
You can even call the getUELs() method on a symbol or a dimension of a symbol.