Matrix to GDX from Python

Questions on using the GAMS APIs (Python, .NET, etc.)
Post Reply
F0043C0
User
User
Posts: 2
Joined: 3 years ago

Matrix to GDX from Python

Post by F0043C0 »

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:

Code: Select all

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?
Last edited by F0043C0 3 years ago, edited 1 time in total.
User avatar
Clemens
Posts: 57
Joined: 7 years ago

Re: Matrix to GDX from Python

Post by Clemens »

Hi,

You can represent the matrix as a 2-dimensional GAMS parameter using the following code:

Code: Select all

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
F0043C0
User
User
Posts: 2
Joined: 3 years ago

Re: Matrix to GDX from Python

Post by F0043C0 »

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?
User avatar
Clemens
Posts: 57
Joined: 7 years ago

Re: Matrix to GDX from Python

Post by Clemens »

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:

Code: Select all

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
Post Reply