ArraysOfArrays.jl
A Julia package for efficient storage and handling of nested arrays. ArraysOfArrays provides two different types of nested arrays: ArrayOfSimilarArrays
and VectorOfArrays
.
This package also defines and exports the following new functions applicable to nested arrays in general:
nestedview
andflatview
switch between a flat and a nested view of the same data.innersize
returns the size of the elements of an array, provided they all have equal size.deepgetindex
,deepsetindex!
anddeepview
provide index-based access across multiple layers of nested arraysinnermap
anddeepmap
apply a function to the elements of the inner (resp. innermost) arrays.abstract_nestedarray_type
returns the type of nestedAbstractArray
s for a given innermost element type with multiple layers of nesting.consgroupedview
computes a grouping of equal consecutive elements on a vector and applies it to another vector or (named or unnamed) tuple of vectors.
ArrayOfSimilarArrays
An ArrayOfSimilarArrays
offers a duality of view between representing the same data as both a flat multi-dimensional array and as an array of equally-sized arrays:
A_flat = rand(2,3,4,5,6)
A_nested = nestedview(A_flat, 2)
creates a view of A_flat
as an array of arrays:
A_nested isa AbstractArray{<:AbstractArray{T,2},3} where T
A_flat
is always available via flatview
. A_flat
and A_nested
are backed by the same data, no data is copied:
flatview(A_nested) === A_flat
Calling getindex
on A_nested
returns a view into A_flat
:
fill!(A_nested[2, 4, 3], 4.2)
all(x -> x == 4.2, A_flat[:, :, 2, 4, 3])
Type aliases
The following type aliases are defined:
VectorOfSimilarArrays{T,M} = AbstractArrayOfSimilarArrays{T,M,1}
ArrayOfSimilarVectors{T,N} = AbstractArrayOfSimilarArrays{T,1,N}
VectorOfSimilarVectors{T} = AbstractArrayOfSimilarArrays{T,1,1}
For each of the types there is also an abstract type (AbstractArrayOfSimilarArrays
, etc.).
If a VectorOfSimilarArrays
is backed by an ElasticArrays.ElasticArray
, additional element arrays can be pushed into it and resize!
is available too:
Appending data and resizing
using ElasticArrays
A_nested = nestedview(ElasticArray{Float64}(undef, 2, 3, 0), 2)
for i in 1:4
push!(A_nested, rand(2, 3))
end
size(flatview(A_nested)) == (2, 3, 4)
resize!(A_nested, 6)
size(flatview(A_nested)) == (2, 3, 6)
There is a full duality between the nested and the flat view of the data. A_flat
may be resized freely without breaking the inner consistency of A_nested
: Changes in the shape of one will result in changes in the shape of the other.
VectorOfArrays
A VectorOfArrays
represents a vector of arrays of equal dimensionality but different size. It is a nested interpretation of the concept of a "ragged array".
VA = VectorOfArrays{Float64, 2}()
push!(VA, rand(2, 3))
push!(VA, rand(4, 2))
size(VA[1]) == (2,3)
size(VA[2]) == (4,2)
Internally, all data is stored efficiently in a single, flat and memory-contiguous vector, accessible via flatview
:
VA_flat = flatview(VA)
VA_flat isa Vector{Float64}
Calling getindex
on A_nested
returns a view into A_flat
:
VA_flat = flatview(VA)
view(VA_flat, 7:14) == vec(VA[2])
fill!(view(VA_flat, 7:14), 2.4)
all(x -> x == 2.4, VA[2])
fill!(view(VA_flat, 7:14), 4.2)
all(x -> x == 4.2, VA[2])
Type aliases
The following type aliases are defined:
VectorOfVectors{T,VT,VI,VD} = VectorOfArrays{T,1,VT,VI,VD}
Appending data and resizing
A VectorOfArrays
is grown by appending data to it. resize!
can be used to shrink it, but not to grow it (the size of the additional element arrays would be unknown):
length(resize!(VA, 1)) == 1
but
resize!(VA, 4)
will fail.
Note: The vector returned by flatview(VA)
must not be resized directly, doing so would break the internal consistency of VA
.