JuMP variable container with repeated index

This is a nice example. I see why you got confused! Let me try and talk you through what’s happening.

julia> using JuMP

julia> m = Model()
A JuMP Model
Feasibility problem with:
Variables: 0
Model mode: AUTOMATIC
CachingOptimizer state: NO_OPTIMIZER
Solver name: No optimizer attached.

julia> inds = [1 2 3; 2 4 5; 3 5 5]
3×3 Matrix{Int64}:
 1  2  3
 2  4  5
 3  5  5

julia> @variable(m, x[unique(vec(inds))]) # create independent scalar variables
1-dimensional DenseAxisArray{VariableRef,1,...} with index sets:
    Dimension 1, [1, 2, 3, 4, 5]
And data, a 5-element Vector{VariableRef}:
 x[1]
 x[2]
 x[3]
 x[4]
 x[5]

So far so good. You created a vector of variables with 5 elements, and the keys are 1 through 5.

julia> @constraint(m, x[inds]>=0, PSDCone())
ERROR: KeyError: key [1 2 3; 2 4 5; 3 5 5] not found

Hmm. JuMP tried to use inds as a key, instead of creating a matrix using those indices.

You want to use:

julia> [x[i] for i in inds]
3×3 Matrix{VariableRef}:
 x[1]  x[2]  x[3]
 x[2]  x[4]  x[5]
 x[3]  x[5]  x[5]

So:

julia> @constraint(m, [x[i] for i in inds] >= 0, PSDCone())
[x[1]  x[2]  x[3];
 x[2]  x[4]  x[5]; ∈ PSDCone()
 x[3]  x[5]  x[5]]

What happened in the next error?

julia> @variable(m, y[inds])
ERROR: Repeated index 2. Index sets must have unique elements.

JuMP tried to create something like @variable(m, y[[1 2 3 2 4 5 3 5 5]]) by calling vec(inds). You either need to use unique again, or perhaps use y[1:3, 1:3] to create a 3x3 matrix.

I would write your model as:

inds = [1 2 3; 2 4 5; 3 5 5]
model = Model()
@variable(model, x[unique(inds)])
@constraint(model, [x[i] for i in inds] >= 0, PSDCone())

If you know that inds is going to contain the integers 1:N, then you can even write

inds = [1 2 3; 2 4 5; 3 5 5]
model = Model()
@variable(model, x[unique(inds)], container = Array)
@constraint(model, [x[i] for i in inds] >= 0, PSDCone())

and now x is a Vector not a DenseAxisArray:

julia> @variable(model, x[unique(inds)], container = Array)
5-element Vector{VariableRef}:
x[1]
x[2]
x[3]
x[4]
x[5]
3 Likes