Skip to content

Commit 8240745

Browse files
Remove ragged field, and go back to simple AbstractArray interface.
1 parent 6250057 commit 8240745

File tree

3 files changed

+41
-45
lines changed

3 files changed

+41
-45
lines changed

src/vector_of_array.jl

Lines changed: 26 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,49 @@
1-
abstract AbstractVectorOfArray{T, N} <: AbstractArray{T, N}
2-
31
# Based on code from M. Bauman Stackexchange answer + Gitter discussion
4-
type VectorOfArray{T, N, A} <: AbstractVectorOfArray{T, N}
2+
3+
type VectorOfArray{T, N, A} <: AbstractArray{T, N}
54
data::A # A <: AbstractVector{<: AbstractArray{T, N - 1}}
5+
#TODO: I don't really use dims, how do I get rid of it, and still have everything work?
66
dims::NTuple{N, Int}
7-
ragged::Bool
87
end
98

109
function VectorOfArray(vec::AbstractVector)
11-
# Only allow a vector of equally shaped subtypes, this will not work for ragged arrays
12-
ragged = !all(size(vec[1]) == size(v) for v in vec)
13-
VectorOfArray(vec, (size(vec[1])..., length(vec)), ragged)
10+
# Only allow a vector of equally shaped subtypes, this will not work for ragged arrays
11+
#@assert all(size(vec[1]) == size(v) for v in vec)
12+
VectorOfArray(vec, (size(vec[1])..., length(vec)))
1413
end
1514

16-
VectorOfArray{T, N}(vec::AbstractVector{T}, dims::NTuple{N}, ragged::Bool) = VectorOfArray{eltype(T), N, typeof(vec)}(vec, dims, ragged)
17-
@inline function Base.size(S::AbstractVectorOfArray)
18-
if S.ragged
19-
return size(S.data)
20-
else
21-
return S.dims
22-
end
23-
end
15+
VectorOfArray{T, N}(vec::AbstractVector{T}, dims::NTuple{N}) = VectorOfArray{eltype(T), N, typeof(vec)}(vec, dims)
16+
Base.size(S::VectorOfArray) = (size(S.data[1])..., length(S.data))
2417

25-
@inline function Base.getindex{T, N}(S::AbstractVectorOfArray{T, N}, I::Vararg{Int, N})
26-
@boundscheck checkbounds(S, I...)
27-
S.ragged && throw(BoundsError("A ragged VectorOfArray does not support Cartesian indexing"))
28-
S.data[I[end]][Base.front(I)...]
18+
@inline function Base.getindex{T, N}(S::VectorOfArray{T, N}, I::Vararg{Int, N})
19+
@boundscheck checkbounds(S, I...) # is this needed?
20+
S.data[I[end]][Base.front(I)...]
2921
end
3022
# Linear indexing will be over the container elements, not the individual elements
3123
# unlike an true AbstractArray
32-
@inline Base.getindex{T, N}(S::AbstractVectorOfArray{T, N}, I::Union{Int, Colon, AbstractArray{Int}}) = S.data[I]
24+
@inline Base.getindex{T, N}(S::VectorOfArray{T, N}, I::Int) = S.data[I]
25+
@inline Base.getindex{T, N}(S::VectorOfArray{T, N}, I::AbstractArray{Int}) = S.data[I]
3326

34-
Base.copy(S::AbstractVectorOfArray) = VectorOfArray(copy(S.data), S.dims, S.ragged)
27+
Base.copy(S::VectorOfArray) = VectorOfArray(copy(S.data), S.dims)
3528

36-
Base.sizehint!{T, N}(S::AbstractVectorOfArray{T, N}, i) = sizehint!(S.data, i)
29+
Base.sizehint!{T, N}(S::VectorOfArray{T, N}, i) = sizehint!(S.data, i)
3730

38-
function Base.push!{T, N}(S::AbstractVectorOfArray{T, N}, new_item::AbstractArray)
39-
if S.dims[1:(end - 1)] == size(new_item)
40-
S.dims = (S.dims[1:(end - 1)]..., S.dims[end] + 1)
41-
else
42-
S.ragged = true
43-
# just revert down to a vector of elements, make the dims data meaningless
44-
#TODO: this is stupid ugly
45-
S.dims = tuple(-ones(Int, N)...)
46-
end
47-
push!(S.data, copy(new_item))
31+
function Base.push!{T, N}(S::VectorOfArray{T, N}, new_item::AbstractVector)
32+
#@assert S.dims[1:(end - 1)] == size(new_item)
33+
#S.dims = (S.dims[1:(end - 1)]..., S.dims[end] + 1)
34+
push!(S.data, new_item)
4835
end
49-
function Base.append!{T, N}(S::AbstractVectorOfArray{T, N}, new_item::AbstractVectorOfArray{T, N})
36+
37+
function Base.append!{T, N}(S::VectorOfArray{T, N}, new_item::VectorOfArray{T, N})
5038
for item in copy(new_item)
51-
push!(S, item)
39+
push!(S, item)
5240
end
5341
return S
5442
end
5543

44+
5645
# The iterator will be over the subarrays of the container, not the individual elements
5746
# unlike an true AbstractArray
58-
Base.start{T, N}(S::AbstractVectorOfArray{T, N}) = 1
59-
Base.next{T, N}(S::AbstractVectorOfArray{T, N}, state) = (S[state], state + 1)
60-
Base.done{T, N}(S::AbstractVectorOfArray{T, N}, state) = state >= length(S.data) + 1
61-
62-
# convert to a regular, sense array
63-
function vecarr_to_arr(va::AbstractVectorOfArray)
64-
va[[Colon() for d in 1:length(va.dims)]...]
65-
end
47+
Base.start{T, N}(S::VectorOfArray{T, N}) = 1
48+
Base.next{T, N}(S::VectorOfArray{T, N}, state) = (S[state], state + 1)
49+
Base.done{T, N}(S::VectorOfArray{T, N}, state) = state >= length(S.data) + 1

test/basic_indexing.jl

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
1+
using RecursiveArrayTools
12

23
# Example Problem
34
recs = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
45
testa = cat(2, recs...)
56
testva = VectorOfArray(recs)
6-
testa[1:2, 1:2] == [1 2; 4 5]
7-
testva[1:2, 1:2] == [1 2; 4 5]
7+
testa[1:2, 1:2] == [1 4; 2 5]
8+
testva[1:2, 1:2] == [1 4; 2 5]
89
testa[1:2, 1:2] == [1 4; 2 5]
910

1011
# # ndims == 2
1112
recs = [rand(8) for i in 1:10]
1213
testa = cat(2, recs...)
1314
testva = VectorOfArray(recs)
1415

16+
# ## Linear indexing
17+
testva[1] == testa[:, 1]
18+
testva[:] == recs
19+
testva[end] == testa[:, end]
20+
testva[2:end] == [recs[i] for i = 2:length(recs)]
21+
1522
# ## (Int, Int)
1623
@test testa[5, 4] == testva[5, 4]
1724

@@ -49,3 +56,8 @@ testva = VectorOfArray(recs)
4956

5057
# ## (Range, Range, Range)
5158
@test testa[2:3, 2:3, 1:2] == testva[2:3, 2:3, 1:2]
59+
60+
# ## Make sure that 1:1 like ranges are not collapsed
61+
@test testa[1:1, 2:3, 1:2] == testva[1:1, 2:3, 1:2]
62+
63+
# ## Test ragged arrays work, or give errors as needed

test/interface_tests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ append!(testva, testva)
2020
# Test that adding a array of different dimension triggers the ragged flag
2121
push!(testva, [-1, -2, -3, -4])
2222
#testva #TODO: this screws up printing, try to make a fallback
23-
testva.ragged
23+
#testva.ragged
2424
@test_throws BoundsError testva[1:2, 5:6]
2525
@test testva[9] == [-1, -2, -3, -4]
2626
testva[end]

0 commit comments

Comments
 (0)