JuliaArrays / ArrayViews.jl

A Julia package to explore a new system of array views
MIT License
19 stars 18 forks source link

Using view() with map() #25

Closed ahwillia closed 9 years ago

ahwillia commented 9 years ago

Is there a way to apply map() to an ArrayView in Julia?

using ArrayViews
A = rand(10,10);
sum(map(x->x>0.5,A[1,:])); # works, gives something reasonable, e.g. 5
sum(map(x->x>0.5,view(A,1,:)))

Using the ArrayView produces the following error

ERROR: `similar` has no method matching similar(::StridedView{Float64,2,0,Array{Float64,2}}, ::Type{Bool}, ::(Int64,Int64))
in similar at abstractarray.jl:116
in map at abstractarray.jl:1329

I also posted this question on stack overflow, but wasn't sure if I should post here as well. Feel free to close this if this isn't the appropriate venue.

andreasnoack commented 9 years ago

I think this is the right place to post this. There ought to be a similar method defined for ArrayViews. It would be great if you could prepare a pull request with this.

ahwillia commented 9 years ago

I can try. This similar method in src/common.jl looks really close to what we want?

similar{T}(a::StridedArrayView{T}, ::Type{T}, dims::Dims) = Array(T, dims)

Are you saying we just to repeat this for StridedView rather than StridedArrayView?

similar{T}(a::StridedView{T}, ::Type{T}, dims::Dims) = Array(T, dims)

Not sure that I understand the distinction between the two.

andreasnoack commented 9 years ago

I think that you should simply remove the {T} part of StridedArrayView{T}. It seems wrong that you can only choose the same element type as the input arrays. Could you try to change that?

simonster commented 9 years ago

StridedArrayView is the supertype of all ArrayViews, so that part is right. But this method is only applicable when the type is the same as the type of the view. I think it should be:

similar{T}(a::StridedArrayView, ::Type{T}, dims::Dims) = Array(T, dims)

I also don't think the other two methods should be necessary since they are defined in Base.

ahwillia commented 9 years ago

Yes, what you suggest works now. What should I do with the other two methods? If I delete the {T} part from those, I get a warning:

Warning: static parameter T does not occur in signature for similar at /home/alex/.julia/v0.3/ArrayViews/src/common.jl:64.
The method will not be callable.

My guess would be this? (Sorry I'm still a bit new to julia)

similar(a::StridedArrayView) = Array(typeof(a), size(a))
similar(a::StridedArrayView, dims::Dims) = Array(typeof(a), dims)
similar{T}(a::StridedArrayView, ::Type{T}, dims::Dims) = Array(T, dims)
andreasnoack commented 9 years ago

Just try to delete them completely. As @simonster said, they should be covered by methods in base.

ahwillia commented 9 years ago

Ok. Deleting them seems to work. Will open a pull request.

julia> using ArrayViews
julia> A = rand(10,10);
julia> similar(view(A,1,:))
1x10 Array{Float64,2}:
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
julia> similar(view(A,1,:),(2,2))
2x2 Array{Float64,2}:
 0.0  0.0
 0.0  0.0
julia> sum(map(x->x>0.5,view(A,1,:)))
7