Is it possible to index an array with a tuple?

Is this the only way?

julia> a
5-element Vector{Float64}:
 3.00000e+00
 2.00000e+00
 5.00000e+00
 9.02242e-01
 7.68556e-01

julia> t
(3, 2, 5)

julia> a[[t...]]
3-element Vector{Float64}:
 5.00000e+00
 2.00000e+00
 7.68556e-01

This allocates :frowning:

[a[i] for i in t]?

or

julia> @benchmark view($a, SVector($t))
BenchmarkTools.Trial: 10000 samples with 1000 evaluations.
 Range (min … max):  2.584 ns … 8.786 ns  β”Š GC (min … max): 0.00% … 0.00%
 Time  (median):     2.605 ns             β”Š GC (median):    0.00%
 Time  (mean Β± Οƒ):   2.618 ns Β± 0.136 ns  β”Š GC (mean Β± Οƒ):  0.00% Β± 0.00%

   β–β–ˆβ–                                                       
  β–ˆβ–ˆβ–ˆβ–ˆβ–…β–‚β–‚β–‚β–‚β–‚β–β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–‚β–β–‚β–‚β–‚β–‚β–‚β–‚ β–‚
  2.58 ns        Histogram: frequency by time       3.17 ns <

 Memory estimate: 0 bytes, allocs estimate: 0.
5 Likes

Yes, with β€œLabelled Arrays”

i.e.

using LabelledArrays

r = []
for x = 1:12 push!(r, x*30-29:x*30) end
l=(:a1,:a2,:a3,:a4,:b1,:b2,:b3,:b4,:c1,:c2,:c3,:c4)
LA = @SLArray (3,10,2,2,3) (NamedTuple{l}(r))
LA = LA(rand(1:50, 3,10,2,2,3)) 

println(LA,"\n")
println(LA.c3')
println(LA.c4[2:3:30])  

Or if you don’t need a vector as output

julia> map(t->getindex(a,t),t)
(5.0, 2.0, 0.768556)

Another option:

a[collect(Iterators.flatten(t))]
@btime getindex.(($a,), $t)
  2.000 ns (0 allocations: 0 bytes)
(5.0, 2.0, 0.768556)
2 Likes

Alas:

julia> @btime $a[collect(Iterators.flatten($t))]
  75.617 ns (2 allocations: 160 bytes)
3-element Vector{Float64}:
 5.00000e+00
 2.00000e+00
 7.68556e-01

I realize I omitted an important aspect of this: I wish to assign to a subarray. Like this:

julia> @btime $a[[$t...]] .= 0
  40.445 ns (1 allocation: 80 bytes)
3-element view(::Vector{Float64}, [3, 2, 5]) with eltype Float64:
 0.00000e+00
 0.00000e+00
 0.00000e+00

which, as you can see, allocates.

That’s the ticket!

julia> @btime $a[SVector($t)] .= 0
  4.300 ns (0 allocations: 0 bytes)
3-element view(::Vector{Float64}, [3, 2, 5]) with eltype Float64 with indices SOneTo(3):
 0.00000e+00
 0.00000e+00
 0.00000e+00
1 Like

Are you sure that using StaticArrays for this is better than the simple, more general Julia for loop?

for i in t
   a[i] = 0
end
2 Likes

Indeed, it is not.

julia> @btime for i in $t
          $a[i] = 0
       end
  3.200 ns (0 allocations: 0 bytes)

julia> @btime $a[SVector($t)] .= 0
  4.300 ns (0 allocations: 0 bytes)
3-element view(::Vector{Float64}, [3, 2, 5]) with eltype Float64 with indices SOneTo(3):
 0.00000e+00
 0.00000e+00
 0.00000e+00
2 Likes