Does anyone know if we have an array package that lets you specify an arbitrary getindex
function? Implementing it is pretty trivial; aside from tests, this is a complete package:
module ClosureArrays
export ClosureArray
struct ClosureArray{T,N,F,P,Axs} <: AbstractArray{T,N}
getindex::F
parent::P
axes::Axs
end
ClosureArray{T}(getindex::F, parent, axes) where {T,F} =
ClosureArray{T, length(axes), F, typeof(parent), typeof(axes)}(getindex, parent, axes)
ClosureArray(getindex::F, parent, axes) where F =
ClosureArray{Base._return_type(getindex, Tuple{typeof(parent), Vararg{Int, length(axes)}})}(getindex, parent, axes)
Base.@propagate_inbounds Base.getindex(A::ClosureArray{T,N}, i::Vararg{Int,N}) where {T,N} =
convert(T, A.getindex(A.parent, i...))::T
Base.size(A::ClosureArray) = map(length, A.axes)
Base.axes(A::ClosureArray) = A.axes
end
and here would be a demo of an array that reverses the dimensions (mimicking PermutedDimsArray
):
julia> P = rand(3,5,4);
julia> A = ClosureArray(P, reverse(axes(P))) do AA, i...
AA[reverse(i)...]
end;
julia> A[3,2,1] == P[1,2,3]
true
and another that lazily sums along dimension 2:
julia> A = ClosureArray(P, (axes(P, 1), axes(P, 3))) do AA, i1, i2
sum(view(AA, i1, :, i2))
end;
julia> size(A)
(3, 4)
julia> A[1, 3] == sum(P[1, :, 3])
true
If we don’t have this already, I can add ClosureArrays to JuliaArrays. (Or should it be called GetindexArrays?)