The Python API tutotial on the GAMS website mentions how to convert a dictionary into a GAMS parameter struct. If I have a python matrix like the one below:
A=
[[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.]]
What is the simplest way to add this to an instantiated database object and export it as a gdx file?
Hi,
You can represent the matrix as a 2-dimensional GAMS parameter using the following code:
from gams import *
A=[[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.]]
ws = GamsWorkspace(".")
db = ws.add_database('data')
mat = db.add_parameter('mat', 2)
for m in range(len(A)):
for n in range(len(A[m])):
mat.add_record(['m'+str(m+1),'n'+str(n+1)]).value = A[m][n]
db.export()
Hope that helps,
Clemens
Thank you so much!
Would there be a faster/more efficient way to do this if I were using a csr_matrix or any other type of sparse matrix?
I can not say anything about csr_matrix in particular, but if possible, you can skip the zeros of any sparse matrix representation when writing to an instance of GamsParameter. Filling data using the Object-oriented Python API always works record based by calling my_symbol.add_record([key1, key2,… keyN]).value = val. So in your example, you would actually only make two calls in order to add the (non-zero) data instead of m*n calls.
You perhaps want to create the domain sets for your parameter in advance and fill them with m1*mN and n1*nN or similar. Then you can use db.add_parameter_dc(‘mat’, [set_m,set_n]) in order to add the 2-dimensional parameter mat with domains set_m and set_n. Some example code:
set_m = db.add_set('m', 1)
set_n = db.add_set('n', 1)
for m in range(len(A)):
set_m.add_record(str(m+1))
for n in range(len(A[0])):
set_n.add_record(str(n+1))
mat = db.add_parameter_dc('mat', [set_m, set_n])
for m in range(len(A)):
for n in range(len(A[0])):
if A[m][n] != 0:
mat.add_record([str(m+1),str(n+1)]).value=A[m][n]
Best,
Clemens