Domain_forwarding with loadRecordsFromGdx

Hi

I am trying to define a set by using domain_forwarding on subsets, and reading those subsets from data. However, this does not work.

I have a added a self-contained example below, which looks like a bug to me. If it is intended behavior, is there another way of defining a superset from subsets loaded from a gdx file?


import gamspy as gp

data = gp.Container()
sub = data.addSet(name="sub", records=["a"])

m = gp.Container()
super = m.addSet(name="super")
sub = m.addSet(name="sub", domain_forwarding=True)

m.loadRecordsFromGdx(data, ["sub"])

len(sub.records) == 1
super.records is None

GAMSPy version

1.5.0

Hi,

Looks like you don’t load any data from gdx in the script that you shared. Can you share the gdx file along with the updated script?

Hi Muhammet

Great work on gamsPy! It is a very elegant product.

In the example, I read from a different container. The behavior is the same if that container is created by reading from a gdx - see example below. (I DID however forget to actually set the domain of the subset in the example above, but the issue remains.)
Is there a better way of loading sets from a gdx, than loading the gdx into a separate container?

import gamspy as gp

data = gp.Container()
super = data.addSet(name="super")
sub = data.addSet(name="sub", domain=[super], domain_forwarding=True, records=["a"])

# Write to GDX and read from GDX
data.write("test.gdx")
data = gp.Container()
data.read("test.gdx")

m = gp.Container()
super = m.addSet(name="super")
sub = m.addSet(name="sub", domain=[super], domain_forwarding=True)

m.loadRecordsFromGdx(data, ["sub"])

len(sub.records) == 1
super.records is None

Thanks for your kind words! loadRecordsFromGdx does not support domain forwarding at the moment but it will be implemented in the next release (which will be released next week).

In general, you can just read the gdx into the same container. For example:

import gamspy as gp

m = gp.Container("test.gdx")
super, sub = m["super"], m["sub"]

But if you need domain forwarding, you can do the following for the moment:

import gamspy as gp

m1 = gp.Container()
m1.read("test.gdx", ['sub'])

m2 = gp.Container()
super = m2.addSet(name="super")
sub = m2.addSet(name="sub", domain=[super], domain_forwarding=True)
sub.setRecords(m1['sub'].records)

print(super.records)
print(len(sub.records) == 1)
print(super.records is None)

This functionality was added with GAMSPy 1.5.1. Here is an example:

from gamspy import Container, Set

gdx_path = "test.gdx"
m = Container()
i = Set(m, "i", records=["i1", "i2", "i3"])
j = Set(m, "j", i, records=["i1", "i2"])
m.write(gdx_path)

m = Container()
i = Set(m, "i")
j = Set(m, "j", i, domain_forwarding=True)
m.loadRecordsFromGdx(gdx_path, ["j"])
assert i.toList() == ["i1", "i2"]
assert j.toList() == ["i1", "i2"]

Great! The first work-around also worked.
I found some other issues with domain_forwarding, but will check if they persist in the new version.