# JuMP variable container with repeated index

**URL:** <https://discourse.julialang.org/t/jump-variable-container-with-repeated-index/72782>\
**Category:** Optimization (Mathematical)\
**Tags:** jump\
**Created:** [December 8, 2021, 3:30pm UTC](https://discourse.julialang.org/t/jump-variable-container-with-repeated-index/72782 "2021-12-08T15:30:30Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Thomas](https://avatars.discourse-cdn.com/v4/letter/t/e36b37/32.png) [@Thomas](https://discourse.julialang.org/u/Thomas)\
**Post date:** [December 8, 2021, 3:30pm UTC](https://discourse.julialang.org/t/jump-variable-container-with-repeated-index/72782/1 "2021-12-08T15:30:30Z")

</div>

I wonder how JuMP experts would create an SDP variable over some index matrix constrained during creation. From the docs, it is recommended to constraint variable upon creation if possible. Can the following be improved (if any)?

```julia
using JuMP
m = Model()
inds = [1 2 3; 2 4 5; 3 5 5]
@variable(m, x[unique(vec(inds))]) # create independent scalar variables
@constraint(m, x[inds]>=0, PSDCone()) # then add PSD constraint
@variable(m, y[inds]) # ERROR: Repeated index 2. Index sets must have unique elements.
@variable(m, z[1:3,1:3], PSD) # need to add further equality constraints

```

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [December 8, 2021, 7:10pm UTC](https://discourse.julialang.org/t/jump-variable-container-with-repeated-index/72782/2 "2021-12-08T19:10:10Z")

</div>

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

```nohighlight
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.

```nohighlight
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
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:

```nohighlight
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?

```nohighlight
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:

```julia
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

```julia
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
julia> @variable(model, x[unique(inds)], container = Array)
5-element Vector{VariableRef}:
x[1]
x[2]
x[3]
x[4]
x[5]

```

---

<div class="post-metadata">

**Author:** ![Thomas](https://avatars.discourse-cdn.com/v4/letter/t/e36b37/32.png) [@Thomas](https://discourse.julialang.org/u/Thomas)\
**Post date:** [December 9, 2021, 10:58am UTC](https://discourse.julialang.org/t/jump-variable-container-with-repeated-index/72782/3 "2021-12-09T10:58:44Z")

</div>

Many thanks @odow for taking time and write such a detailed reply. I did not notice that `@constraint(m, x[inds]>=0, PSDCone())` is wrong because I used `M = x[inds]; @constraint(m, M>=0, PSDCone())` in my program. Your solution `@constraint(m, [x[i] for i in inds] >= 0, PSDCone())` is nicer than me.

I also had a careful read of the documentation and I think the syntax above does not create variable constrained on creation [Variables · JuMP](https://jump.dev/JuMP.jl/stable/manual/variables/#jump_variables_on_creation)

Is there any heuristic to follow in terms of performance when creating variables? I know this is not really a bottleneck for most usecases, unless one is implementing a very badly formulated optimization.
