# How to find the index of a Dense Axis Array?

**URL:** <https://discourse.julialang.org/t/how-to-find-the-index-of-a-dense-axis-array/53204>\
**Category:** Optimization (Mathematical)\
**Tags:** question\
**Created:** [January 12, 2021, 1:39pm UTC](https://discourse.julialang.org/t/how-to-find-the-index-of-a-dense-axis-array/53204 "2021-01-12T13:39:43Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![fredih](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredih/32/20945_2.png) [@fredih](https://discourse.julialang.org/u/fredih)\
**Post date:** [January 12, 2021, 1:39pm UTC](https://discourse.julialang.org/t/how-to-find-the-index-of-a-dense-axis-array/53204/1 "2021-01-12T13:39:43Z")

</div>

Hello! I know I can use something like ` findall(x->x==1, myArray)` to find the indices of elements of value 1 inside `myArray`.

However, my variables in my optimization problem are DenseAxisArrays, as they are indexed with numbers and strings. So when I do, for example:

`findall(x->x==1,JuMP.value.(Z))`

I get:

```julia
ERROR: MethodError: no method matching CartesianIndices(::Tuple{Array{Any,1},Array{Any,1},Base.OneTo{Int64}})
Closest candidates are:
  CartesianIndices(::JuMP.Containers.DenseAxisArray) at C:\Users\Alfredo\.julia\packages\JuMP\qhoVb\src\Containers\DenseAxisArray.jl:111
  CartesianIndices(::AbstractArray) at multidimensional.jl:264
  CartesianIndices(::Tuple{}) at multidimensional.jl:255

```

How could I get the indices?

**Edit: here’s a minimal working example**

```julia
using JuMP, Cbc

m = Model(Cbc.Optimizer)

TASKS = ["TASK1"]
EQUIPMENTS = ["EQUIPMENT1"]
@variable(m, Z[E in EQUIPMENTS, T in TASKS, 1:32], Bin)
@constraint(m, sum(Z)==1)
@objective(m, Min, sum(Z))
optimize!(m)

#output
println(JuMP.value.(Z))
println(JuMP.objective_value(m))
println(JuMP.termination_status(m))
println("Finished!")

```

---

<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:** [January 12, 2021, 10:07pm UTC](https://discourse.julialang.org/t/how-to-find-the-index-of-a-dense-axis-array/53204/4 "2021-01-12T22:07:13Z")

</div>

You want:

```nohighlight
[Z[i] for i in eachindex(Z) if value(Z[i]) > 0.5]

1-element Array{VariableRef,1}:
Z[EQUIPMENT1,TASK1,1]

```

or perhaps:

```julia
[k.I for k in keys(Z) if value(Z[k]) > 0.5]

1-element Array{Tuple{String,String,Int64},1}:
("EQUIPMENT1", "TASK1", 1)

```

The documentation needs to be improved on this front: [https://github.com/jump-dev/JuMP.jl/issues/1663](https://github.com/jump-dev/JuMP.jl/issues/1663)

---

<div class="post-metadata">

**Author:** ![NiclasMattsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/niclasmattsson/32/21988_2.png) [@NiclasMattsson](https://discourse.julialang.org/u/NiclasMattsson)\
**Post date:** [January 12, 2021, 10:34pm UTC](https://discourse.julialang.org/t/how-to-find-the-index-of-a-dense-axis-array/53204/5 "2021-01-12T22:34:09Z")

</div>

Interesting. Apparently `findall(f, A)` calls `pairs(A)` which in turn calls `CartesianIndices(axes(A))`. And that errors since JuMP has defined `axes(A)` for a `DenseAxisArray´ to return the axes you originally specified instead of integer axes:

```julia
julia> axes(Z)
(["EQUIPMENT1"], ["TASK1"], Base.OneTo(32))

julia> CartesianIndices(axes(Z))
ERROR: MethodError: no method matching CartesianIndices(::Tuple{Vector{String}, Vector{String}, Base.OneTo{Int64}})

```

So JuMP probably needs to rethink this approach. A hack that would make `findall` work is to define `pairs` for a `DenseAxisArray`:

```julia
julia> Base.pairs(x::JuMP.Containers.DenseAxisArray) = pairs(x.data)

julia> findall(x->x==1, JuMP.value.(Z))
1-element Vector{CartesianIndex{3}}:
 CartesianIndex(1, 1, 2)

```

But to avoid committing type piracy, a better workaround for you might be to just do:

```julia
julia> findall(x->x==1, JuMP.value.(Z).data)
1-element Vector{CartesianIndex{3}}:
 CartesianIndex(1, 1, 2)

```

In any case, please open an issue for this in the JuMP repo.

EDIT: Got ninja’d by @odow there. He suggests a different approach to get the index - but wouldn’t it be better for interoperability if a `DenseAxisArray` worked like any other `AbstractArray`? Have JuMP devs now settled long term on their own container types or is the hope still that some other generic SomeAxisArray package will take care of the details?

---

<div class="post-metadata">

**Author:** ![fredih](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredih/32/20945_2.png) [@fredih](https://discourse.julialang.org/u/fredih)\
**Post date:** [January 13, 2021, 12:35pm UTC](https://discourse.julialang.org/t/how-to-find-the-index-of-a-dense-axis-array/53204/6 "2021-01-13T12:35:46Z")

</div>

@odow Thanks! It worked! And I agree, the documentation should be improved. Thanks for commenting the issue!

@NiclasMattsson Thank you too, your solution also worked! But I’m having trouble understanding the rest of your post, as I’m really new to Julia; I’ve only been using it from the last week.

What I’m getting is that you’re suggesting to redefine de function pairs for when the parameter is a DenseAxisArray. But what is type piracy? And why would redefining pairs would be commiting type piracy?

And what is interoperability?

Also, I will mark @odow 's reply as solution, because I realized that a cartesian index is not what I want, as it won’t give me the string of the corresponding index.

Thank you both!
