I am trying to write a custom indexed array (with reflective boundary conditions). I would really like to be able to slice the array in the same way that the amazing developers of ShiftedArrays did.
x = reshape(1:100,10,10)
x1 = ShiftedArrays.circshift(x,(1,1))
x1[-10:10,-10:10]
which just gives an array using the index look-up scheme.
Doing what I thought was copying their approach, I modified code from other custom indexing posts here and came to the following.
module tmp
struct ReflectArray{T, N} <: AbstractArray{T, N}
parent::AbstractArray{T,N}
function ReflectArray(x::AbstractArray{T,N}) where {T,N}
return new{T,N}(x)
end
end
function reflectindex(i::Int,N::Int)
if (0 < i <= N)
return i
elseif (-N < i <= 0)
return -i+1
elseif (N < i <= 2*N)
return 2*N - i + 1
else
error("Outside of first order reflective bounds!")
end
end
Base.size(A::ReflectArray) = size(A.parent)
function Base.getindex(A::ReflectArray{T, N}, ind::Vararg{Int, N}) where {T, N}
v = A.parent
@boundscheck checkbounds(v, ind...)
i = map(reflectindex, ind, size(A))
@inbounds ret = v[i...]
ret
end
end
This works for grabbing single elements out of an array, but the same slicing call as above is failing. Any help/thoughts as to why.
c = tmp.ReflectArray(collect(x));
c[-10:10,-10:10]
BoundsError: attempt to access 10Ă—10 Main.tmp.ReflectArray{Int64,2} at index [-10:10, -10:10]
Edit: I was working off of https://github.com/JuliaArrays/ShiftedArrays.jl/blob/master/src/circshiftedarray.jl assuming all of the relevant code was there.