ElasticArrays/ArraysofArrays for Vector of Arrays

mrVeng
Tue, 26 Oct 2021 18:54:12 +0000
General Usage

Dear all,

I would like to use ArraysOfArrays and ElasticArrays to handle indexing a Vector vec of type Vector{<:AbstractArray{T}} where {T} better, as I often need to call vec[iter][idx], and afaik with these packages I can internally index vec as a pure Vector{T}. I figured out how to use both packages together fairly easily with a Matrix:

using ArraysOfArrays, ElasticArrays, Random
Ncols = 1000
Nrows = 100
T = Int64

ela = ElasticArray{T}(undef, Ncols, Nrows)
vov = VectorOfSimilarArrays(ela) #ArrayOfSimilarArrays{Int64, 1, 1, 2, ElasticMatrix{Int64, Vector{Int64}}}

Now, vov.data is still a Matrix, and it contains type information that it stores an ElasticMatrix, so I can resize the last dimension arbitrarily often, which is really nice:

resize!(vov, 123)
resize!(vov, 12)
resize!(vov, Nrows)

I played around with ElasticArrays and Vector of Vectors, and figured that I can actually resize the number of inner vectors, AND push!() them, which makes it possible to change both dimensions without additional allocations:

ela2 = ElasticVector([zeros(T, Nrows) for _ in 1:Ncols])
push!(ela2[1], 1)
resize!(ela2, 123)
resize!(ela2, 12)
resize!(ela2, Ncols)

Unfortunately, there is no easy way to access ela2.data as a pure Vector/Matrix anymore, as it is stored as a Vector{Vector{Int}}.

Is there a way that I can convert ela2 to an ArraysOfArrays, such that

I can still push!() and resize!() as in the example before,

and also have the data somewhere stored as a pure Matrix/Vector{Int} instead of a Vector{Vector{Int}}? I tried this already but it seems all type information is lost when converting the ElasticArray to an ArrayofArrays:

ela2 = ElasticVector([zeros(T, Nrows) for _ in 1:Ncols])
ela2.data #Vector{Vector{Int64}}
vov2 = VectorOfSimilarArrays(ela2) #No more ELASTICARRAY in type information: 1000-element ArrayOfSimilarArrays{Int64, 1, 1, 2, Matrix{Int64}}

vov2.data #100×1000 Matrix{Int64} - This is perfect
# However, we can no longer resize/push!() the array as the ElasticVector type has been converted to a standard Vector:
resize!(vov2, 123) #MethodError: no method matching resize!(::Matrix{Int64}, ::Int64, ::Int64)
push!(vov2[1], 1) # MethodError: no method matching resize!(::SubArray{Int64...

@oschulz - Sorry for tagging you, but I believe you will know if what I want is even possible.

6 posts - 2 participants