2

The new julia 0.5 has improved support for views of arrays. Is it possible to use this functionality to allow views of custom types? E.g. so I could

immutable test
    a::Vector{Int}
    b::Vector{Int}
end

then define a getviewfunction that would e.g. give me a view of test like test(view(a,1:3), view(b,1:3) when passed 1:3 as the argument? (Just doing this creates a new test object where a and b are copies of the subarrays, which is not what I want). Thanks!

Fengyang Wang
  • 11,901
  • 2
  • 38
  • 67
Michael K. Borregaard
  • 7,864
  • 1
  • 28
  • 35

1 Answers1

3

The key is that if you want your type to hold either Array or SubArray, you need to make it parametric. Otherwise it will be converted (copied) on construction of the new object.

julia> immutable MyType{T}
           a::T
           b::T
       end

julia> Base.view(mt::MyType, args...) = MyType(view(mt.a, args...), view(mt.b, args...))

julia> mt = MyType(rand(5),rand(5))
MyType{Array{Float64,1}}([0.791258,0.605581,0.126802,0.559727,0.156383],[0.773287,0.223521,0.926932,0.0301801,0.68872])

julia> view(mt, 2:3)
MyType{SubArray{Float64,1,Array{Float64,1},Tuple{UnitRange{Int64}},true}}([0.605581,0.126802],[0.223521,0.926932])
Tom Breloff
  • 1,782
  • 9
  • 15
  • Thanks a lot for this! (the world of Julia is [still] small, isn't it...) I have to admit I don't understand it completely - why does making the type parametric alter whether the arrays get copied? Do you know of somewhere in the docs to read about this? - I think understanding this might solve a number of current headaches... – Michael K. Borregaard Oct 12 '16 at 19:24
  • It's easier than you think. The parameter T just means "I can be anything, as long as `a` and `b` have the same type". So if you pass any `a` and `b` of the same type to the constructor, it will happily accept them as-is. However if you explicitly say "I must have 2 Vector{Int}", then if you pass them something else it will try to `convert(Vector{Int}, a)` and same for `b`. – Tom Breloff Oct 12 '16 at 20:44
  • Also note that you could use the type signature `immutable MyType{T<:AbstractVector}` to limit the allowed types to anything that is a subtype of `AbstractVector`, which is true for both `Vector{T}` and `SubArray{T,1,...}` – Tom Breloff Oct 12 '16 at 20:46
  • Thanks, OK I didn't realize that specifying a type (non-parametrically) might trigger a copy, though I can see it makes sense. The types I want to create views of are already parametric, and their fields are also composite types, of which some are parametric, so I might be trigggering partial copying of objects. I guess the solution must then be to make all the fields parametric to ensure that no conversion takes place? This has certainly given me something to look for. – Michael K. Borregaard Oct 13 '16 at 05:10