# How to take the index of a variable in sagemath? I used the method in the post to generate a matrix with entries which have indices.

def symbolic_matrix(root,m,n):
mlist=[]
for i in range(m):
for j in range(n):
mlist.append(root+'_'+str(i)+'_'+str(j))
return Matrix(SR,m,n,mlist)

k,n=4,8
r1=symbolic_matrix('y',k,n)
r1


Now I would like to get the index of the entries of the matrix r1. For example, the index of y_1_2 is [1,2]. How to do this in sagemath? I tried something like y.index(y_1_2) but it doesn't work. Thank you very much.

edit retag close merge delete

If you are willing to work with a polynomial ring instead of the symbolic ring, then you can construct those with generators given as an array: PolynomialRing(QQ, 3, 5, var_array='y'). There is no obvious way to access the indices of those generators, unfortunately.

Sort by » oldest newest most voted It's better to set things up more conveniently from the beginning. Symbolically:

indices = [(i,j) for i in range(3) for j in range(5)]
variables = [var('y_{}_{}'.format(i,j)) for (i,j) in indices]
y = dict(zip(indices, variables))
M = matrix(SR, 3, 5, variables)


Or with polynomials:

indices = [(i,j) for i in range(3) for j in range(5)]
R = PolynomialRing(QQ, ['y_{}_{}'.format(i,j) for (i,j) in indices])
y = dict(zip(indices, R.gens()))
M = matrix(R, 3, 5, R.gens())


In both cases:

sage: y[2,0]
y_2_0
sage: M[1,3] is y[1,3]
True

more One possible solution is to construct/return not only a matrix but also a mapping (dict) of variables to their indices - like:

def symbolic_matrix(root,m,n):
var2ind = {}
mlist=[]
for i in range(m):
for j in range(n):
v = SR(root+'_'+str(i)+'_'+str(j))
var2ind[v] = [i,j]
mlist.append(v)
return Matrix(SR,m,n,mlist), var2ind

k,n=4,8
r1, v2i = symbolic_matrix('y',k,n)

v2i[r1[2,3]]

more I think the easiest thing to do, maybe the only thing to do, is to parse the name of the variable as a string. Try str(r1[0,0]).split('_'), for example. If you let a = r1[0,0], then str(a).split('_')[1:] will give you the two indices as strings, so you could do [int(s) for s in str(a).split('_')[1:]].

more