# Derived keys for indexing into JuMP containers

**URL:** https://discourse.julialang.org/t/derived-keys-for-indexing-into-jump-containers/105205
**Category:** Optimization (Mathematical)
**Tags:** jump
**Created:** [October 19, 2023, 9:22pm UTC](https://discourse.julialang.org/t/derived-keys-for-indexing-into-jump-containers/105205 "2023-10-19T21:22:54Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![thevolatilebit](https://avatars.discourse-cdn.com/v4/letter/t/cc9497/32.png) [@thevolatilebit](https://discourse.julialang.org/u/thevolatilebit)
#### Post date: [October 19, 2023, 9:22pm UTC](https://discourse.julialang.org/t/derived-keys-for-indexing-into-jump-containers/105205/1 "2023-10-19T21:22:54Z")

</div>

I am seeking to better understand JuMP’s indexing functionality. As I understand it, when a set of decision variables or constraints in a container is created, JuMP automatically uses the elements of the set as the indexing key for these variables or constraints.

However, I am wondering if we could instruct JuMP to use a derived key instead. To illustrate, consider the following set up:

```plaintext

model = Model()

my_set = Set([MyStruct(1), MyStruct(2)])

@variable(model, x[my_set]) # here, elements of `my_set` serve as indices

```

What I would like to explore is the possibility of using an element’s internal id (or similar property) as an index:

```plaintext

JuMP.derived_key(o::MyStruct) = o.internal_id

@variable(model, y[my_set]) # here, we'd like indices to be based on internal id's

```

Is this possible with JuMP?

@slwu89 is also interested.

---

<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: [October 19, 2023, 9:47pm UTC](https://discourse.julialang.org/t/derived-keys-for-indexing-into-jump-containers/105205/2 "2023-10-19T21:47:07Z")

</div>

Unfortunately this is not possible and there is no workaround.

If you want to use a different index you must explicitly create and use that index.

---

<div class="post-metadata">

### Author: ![thevolatilebit](https://avatars.discourse-cdn.com/v4/letter/t/cc9497/32.png) [@thevolatilebit](https://discourse.julialang.org/u/thevolatilebit)
#### Post date: [October 19, 2023, 10:23pm UTC](https://discourse.julialang.org/t/derived-keys-for-indexing-into-jump-containers/105205/3 "2023-10-19T22:23:35Z")

</div>

Thank you for your swift response!

---

<div class="post-metadata">

### Author: ![thevolatilebit](https://avatars.discourse-cdn.com/v4/letter/t/cc9497/32.png) [@thevolatilebit](https://discourse.julialang.org/u/thevolatilebit)
#### Post date: [October 20, 2023, 11:39pm UTC](https://discourse.julialang.org/t/derived-keys-for-indexing-into-jump-containers/105205/4 "2023-10-20T23:39:22Z")

</div>

It would nevertheless be possible to do something like

```julia
derived_key(x) = x

# Collect iterators with unknown size so they can be used as axes.
_collect(::Base.SizeUnknown, x) = collect(derived_key.(x))

_collect(::Any, x) = derived_key.(x)

```

around [https://github.com/jump-dev/JuMP.jl/blob/12ffa9110700f05fe7504312a903eea13db31324/src/Containers/vectorized\_product\_iterator.jl#L46](https://github.com/jump-dev/JuMP.jl/blob/12ffa9110700f05fe7504312a903eea13db31324/src/Containers/vectorized_product_iterator.jl#L46)

This is evidently a quick “fix” that almost certainly fails to address some edge cases.

For a short demo, it would allow me to do

```julia
model = Model()

struct MyStruct
    x
end

JuMP.Containers.derived_key(s::MyStruct) = s.x ^ 2

my_set = [MyStruct(i) for i=1:3]

@variable(model, x[my_set])

```

resulting in

```julia
1-dimensional DenseAxisArray{VariableRef,1,...} with index sets:
    Dimension 1, [1, 4, 9]
And data, a 3-element Vector{VariableRef}:
 x[1]
 x[4]
 x[9]

```

The question is, would you consider this beneficial to incorporate into JuMP? If so, I would refine it further and submit a PR.

---

<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: [October 20, 2023, 11:59pm UTC](https://discourse.julialang.org/t/derived-keys-for-indexing-into-jump-containers/105205/5 "2023-10-20T23:59:08Z")

</div>

I don’t think we want to support this in JuMP.

The main reason is that it introduces another layer of complexity between the code as written and what gets executed.

In your example, it is much more explicit what you are doing if you do something like this:

```julia
struct MyStruct
    x::Int
end
my_set = Dict(i^2 => MyStruct(i) for i in 1:3)
model = Model()
@variable(model, x[keys(my_set)])

```

---

<div class="post-metadata">

### Author: ![thevolatilebit](https://avatars.discourse-cdn.com/v4/letter/t/cc9497/32.png) [@thevolatilebit](https://discourse.julialang.org/u/thevolatilebit)
#### Post date: [October 21, 2023, 1:38am UTC](https://discourse.julialang.org/t/derived-keys-for-indexing-into-jump-containers/105205/6 "2023-10-21T01:38:19Z")

</div>

Sure, thanks for clarification - and for the awesome work on JuMP in general!
