Mapping over multidimensional array with eachslice

I have a data opject Array{Float64, 3} where I want to map 2nd and 3rd
dimension a function that accepts some static arguments and takes a Vector{Float64}
from the data object. I tried to do this with

eachslice(data, dims=(2,3)

but this returns views view(::Array{Float64, 3}, :, 1, 1) which my function won’t eat. Should I make the function accept views, or do I convert them beforehand and if so how?

Conversion is simple with a collect:

julia> A = rand(4,4,4);

julia> v = @view A[:,1,1]
4-element view(::Array{Float64, 3}, :, 1, 1) with eltype Float64:
 0.8856095041969669
 0.37755696755493096
 0.9045476323189784
 0.4553299239763875

julia> collect(v)
4-element Vector{Float64}:
 0.8856095041969669
 0.37755696755493096
 0.9045476323189784
 0.4553299239763875

It creates a copy, thus allocates memory.

What are you doing in your function which does not work with views?

1 Like

I think it could work with views. I just assigned it
like f(a::Vector{Float64}), how do I make a proper type
signature to allow views?

You can try f(a::AbstractVector{Float64}), or just f(a).

1 Like

I tried it and it seems I have to copy the array. I guess it is because the underlying
function uses PyCall and then it can not give just a reference to the array.
Nevertheless I am very glad to have found AbstractArray thanks to you as I
struggled with this sometime in the past.

You might want mapslices(f, data; dims=1), as this makes a slice which should be an Array, not a view. Or mapslices(x -> f(x, extra), data; dims=1) to pass extra arguments to f.

It will re-use the same Array for the slice, so might be slightly more efficient than collecting the view. Note that it has the opposite convention to eachslice for what the dims means.

3 Likes

(post deleted by author)