Matrix to GDX from Python

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