# List comprehension of JuMP variables

Beginner to Julia and want to quickly recapitulate an ILP model I wrote in Python to evaluate speed in JuMP.

I’m wondering how list comprehensions work for JuMP objects?

In Python, I use list comprehension to make the following constraints:

``````# PYTHON
for k in range(0,math.ceil(K_window/34)):
model.addConstr(y_i_k.sum('*',[l for l in range(k*34,min(k*34+34,K_window))]) <=1,name='Seen_'+str(k))
``````

After reading about Julia syntax on list comprehension, I tried the following but it does not work:

``````# JULIA
for k in 1:floor(Int, K_window/34)
@constraint(model, sum(y_i_k[:, l] for l in (k*34):min(k*34, min(k*34+34, K_window)), dims=1) <=1)
end
``````

I realize this is question may alternatively be categorized as “First Steps”, I have a hunch it’s just me not understanding Julia syntax? Thank you for your help.

So `y_i_k[:, l]` is the `l`th column of `y_i_k`. So the sum is a vector. Then you constraint this sum to be smaller than 1. What does it means for a vector to be smaller than a number ?
If you want each entry to be smaller than 1, do `.<=` instead of `<=`.

2 Likes

I see, I’d like to get the column sum. I was expecting a scalar output, rather than a vector.

More explicitly, I want the sum of all entry in that column to be less than or equal to 1

Here, you are constraining, for each row, the sum of all entries of that row that are in the column range `(k*34):min(k*34, min(k*34+34, K_window))` to be smaller than or equal to 1.

1 Like

Oops, yes you are right, I am trying to constrain each row sum of given indeces to be less than or equal to 1.

I find the following expression works. Maybe there is a more elegant way of writing this?

``````for k in 1:floor(Int, K_window/34)
@constraint(model, [i in 1:I_round], sum(y_i_k[i, l] for l in [k*34:min(k*34, min(k*34+34, K_window))]) <=1)
end
``````

I doesn’t work for me because `[k*34:min(k*34, min(k*34+34, K_window))]` is a vector containing one range so the for loop has one iteration with `l = k*34:min(k*34, min(k*34+34, K_window))` and the `sum` is therefore the some of one term which is the term itself and you are left with a vector that cannot be compared to 1.
So either do
`sum(y_i_k[i, l] for l in k*34:min(k*34, min(k*34+34, K_window)))`
or
`sum(y_i_k[i, k*34:min(k*34, min(k*34+34, K_window))])`

1 Like

Thank you for your patience and guidance @blegat!

May I ask why sometimes the list comprehensions look like they are “evaluated”, rather than expressed?

What I mean is, in Python I have written this line:

``````for i in range(I_round):
for k in range(K_window):
model.addConstr(gp.quicksum(r_i_j[i,j]*y_i_k[i,k]*s_j_k[j,k] for j in range(J))>= T1*y_i_k[i,k])
``````

In Julia, the following are not expressed as terms of r_i_j*y_i_k*s_j_k, but directly evaluated (0). I wonder why this is the case?

``````for i in 1:I_round
for k in 1:K_window
@constraint(model, sum(r_i_j[i,1:J]*y_i_k[i,k]*s_j_k[1:J,k]) >= T1*y_i_k[i,k] )
end
end
``````

Hi there! Since you’re new to Julia, please read this post.

In particular, it’s easier to help if you provide a minimal working example that we can copy-paste and see the same result.

but directly evaluated (0)

Presumably, there is a typo somewhere. I can’t say more because I can’t run your code. The direct equivalent of your Python constraint is:

``````@constraint(
model,
[i=1:I_round, k=1:K_window],
sum(r_i_j[i, j] * y_i_k[i, k] * s_j_k[j, k] for j in 1:J) >= T1 * y_i_k[i, k],
)
``````
1 Like

I see, the indeces can be provided outside the summation, and the list comprehension can still be employed inside.

I will read over the introductory post, thank you for pointing me to this reference!