Custom indices range for arrays


#1

The Julia manual talks about being able to define custom unit ranges https://docs.julialang.org/en/v1/devdocs/offset-arrays/index.html.

There are at least 3 packages that deal with this. 1) https://github.com/JuliaArrays/CustomUnitRanges.jl 2) https://github.com/JuliaArrays/OffsetArrays.jl 3) https://github.com/JuliaArrays/EndpointRanges.jl

I am not having much luck figuring it out. I am trying to duplicate fortran code, this piece specifically

COMPLEX, DIMENSION(n,  0:nk) :: eikx
COMPLEX, DIMENSION(n,-nk:nk) :: eiky, eikz

In this particular case it is incredibly helpful to have negative indices (and 0 too).

One issue I have run into with OffsetArrays is that I can’t use setindex! or setindex. Unfortunately I must update the elements in the 2 dimension array constantly.

Is there a way to make a 2 dimensional complex array that can have negative indices and is mutable?


#2

Following and slightly adapting the first example in the readme of OffsetArrays I get:

julia> nk = 1
1

julia> y = OffsetArray{Complex{Float64}}(undef, -nk:nk, -nk:nk)
OffsetArray(::Array{Complex{Float64},2}, -1:1, -1:1) with eltype Complex{Float64} with indices -1:1×-1:1:
 6.94641e-310+6.94641e-310im  6.94641e-310+6.94641e-310im  6.94641e-310+6.94641e-310im
 6.94641e-310+6.94641e-310im  6.94641e-310+6.94641e-310im  6.94641e-310+6.94641e-310im
 6.94641e-310+6.94641e-310im  6.94641e-310+6.94641e-310im  6.94641e-310+6.94641e-310im

julia> y[-nk,-nk] = 1
1

julia> y
OffsetArray(::Array{Complex{Float64},2}, -1:1, -1:1) with eltype Complex{Float64} with indices -1:1×-1:1:
          1.0+0.0im           6.94641e-310+6.94641e-310im  6.94641e-310+6.94641e-310im
 6.94641e-310+6.94641e-310im  6.94641e-310+6.94641e-310im  6.94641e-310+6.94641e-310im
 6.94641e-310+6.94641e-310im  6.94641e-310+6.94641e-310im  6.94641e-310+6.94641e-310im

#3

Yes this works! I was playing around with a simpler example from a forum and it would not allow me to mutate :S. This however does, so I am happy with that.

I was playing with test = OffsetArray(1:5,-2:2), and I could not update the values after… this is probably due to the use of a range.


#4

Yes, it uses the range as underlying storage:

julia> typeof(OffsetArray(1:5,-2:2))
OffsetArray{Int64,1,UnitRange{Int64}}

julia> typeof(OffsetArray([1:5...],-2:2)) # this you can mutate
OffsetArray{Int64,1,Array{Int64,1}}

The last parameter is the underlying storage.