-1

Good morning,

I've been searching through the internet a way to make a list or table with 2 indexes. Currently I've build a code for 1 index that is mass = list(range(0,value(m.n)+1)) and I fill this list with this expression mass[i] = value(m.mass[i]).

But now I have to introduce another variable that has two indexes as the following x[i,j] = value(m.x[i,j]). I've tried with x = []*value(m.ph). But what I want is to get something like x = [value(m.n)]*value(m.ph) in order to state that I have a table like. values (m.n) as rows and phases (m.ph) as columns.

The goal of doing so is graphing those variables with this function plt.plot(time,x). Idk if it will be possible to do this kind of list, table or matrix as you want to call it, but it will be very useful to know it because I got kinda stuck because of it.

My code is as following:

n = Param(initialize = 10, within = Integers)

N = Set(initialize = range(0,value(m.n)+1))


#What I got

x1 = [0,1,2,3,4,5,6,7,8,9,10]

x = list(range(0,value(m.n)+1))


for i in m.N:
    x[i] = x1[i]


#What I try to do

ph = Param(initialize = 2, within = Integers)
Ph = Set(initialize = range(0,value(m.n)+1))

x2 = [[0,0],[1,1],[2,2],[3,3],[4,4]]

x = []*value(m.ph) 

for i in m.N:
    for j in m.Ph:
        x[i,j] = x2[i,j]

The error is as following:

  File "C:/Users/Manuel/Desktop/StackExample.py", line 38, in <module>
    x[i,j] = x2[i,j]

TypeError: list indices must be integers or slices, not tuple 

Thank you so much.

EDIT: What I want is create a list with two indexes in Python making those indexes have the length I required being these lenght defined by m.n = Param(initialize = 32, within = Integers) and m.ph = Param(initialize = 2, within = Integers).

  • Provide input, required ouput. Your question is unclear. – Aniket Bote Apr 29 '18 at 10:06
  • I've updated the post, I don't know if that was what you asked for or isn't it. Thanks in advance for replying. – Manuel Duran Perez Apr 29 '18 at 10:15
  • 2
    I think what @AniketBote was requesting is a [mcve]. In other words, some code we can run which can replicate the error. While there are some smart people on SO, the mortals among us need to *run some code* to debug it for you. – jpp Apr 29 '18 at 10:18
  • I think I made a runable code, could you try it to see if it shows what I want from it? – Manuel Duran Perez Apr 29 '18 at 10:33

2 Answers2

0

Use dictionaries instead of lists. Dictionaries can be double indexed, which will make them indexed by tuples.

Writing your parameters should be:

paramName = Param(setOfIndiceA, setOfIndiceB, initialize=aDictionary)

Where setOfIndiceA and setOfIndiceB are the sets where fisrst (A) and second (B) indices of your dictionary are contained.

If (a,b) tuples from your indices are sparse (not all value of set A correspond to a value of set B and vice-versa), use one single set of tuples such as

listOfIndicesAB = [(1,1),(1,3),(2,1),(2,4)]
setOfIndicesAB = Set(initialize=listOfIndicesAB)
V. Brunelle
  • 1,038
  • 11
  • 29
  • Shall I include a different dictionary for each variable? Or do I have to create a new dictionary for each variable who has double indexes? – Manuel Duran Perez May 06 '18 at 17:05
  • A distinction between variables and parameters has to be made. Only parameters need a dictionary to hold the data, however, both variables AND parameters needs to have sets for their indices (In the previous code: setOfIndicesA). This way, it will be possible for Pyomo to know the parameters/variables domain. If in your comment, you meant parameters, then do as you wish. The same dictionary can be reused as often as you want. I personally only use dictionaries since they are more flexibles than lists. – V. Brunelle May 07 '18 at 02:54
  • You will certainly need to create a dictionary for each double indexed params, but not necessarily for single indexed ones (I think). – V. Brunelle May 07 '18 at 02:55
0

I found a way two convert the values from from a two dimensional pyomo variable to a two dimensional list. I am not sure if this is what you were looking for but what i understood from the headline. I assume that you indexed your variables with numbers

from pyomo.environ import *

model = ConcreteModel()

# Setup a two dimensional pyomo variable
model.set1 = RangeSet(0, 10)
model.set2 = RangeSet(0, 5)
# initialize with any number as example
model.variable = Var(model.set1, model.set2, initialize=3)
# do your optimization...

# Create an empty list with the same dimensions as the indexed variable
converted_list = [[None for j in range(len(model.set2))]
                  for i in range(len(model.set1))]

#call all touples and values from the variable class
#call the touple values from the dictionary and use them two index the list
for index in model.variable:
    converted_list[index.__getitem__(0)][index.__getitem__(
        1)] = model.variable[index].value

print(converted_list)

This gives you the initialized data or solution if you use your variable for an optimization.

[[3, 3, 3, 3, 3, 3], [3, 3, 3, 3, 3, 3], [3, 3, 3, 3, 3, 3], [3, 3, 3, 3, 3, 3], [3, 3, 3, 3, 3, 3], [3, 3, 3, 3, 3, 3], [3, 3, 3, 3, 3, 3], [3, 3, 3, 3, 3, 3], [3, 3, 3, 3, 3, 3], [3, 3, 3, 3, 3, 3], [3, 3, 3, 3, 3, 3]]

You can call values like this from it:

print(converted_list[1][3])
Julian B.
  • 1
  • 2