Welcome to Julia’s Discourse forum!, about your question, you can define your own array type, defining the necessary interfaces (see this link). for example, a starting base can be this (supposing the circular size is the size of the data):
struct CircularArray{T,N} <: AbstractArray{T,N}
x::AbstractArray{T,N}
end
the next step would be defining the basic operations: size, getindex and setindex!. here i have some trouble, if someone can help, it can be appreciated.
size(A::CircularArray) = size(A.x)
anyway, if this is made, it can be a nice adition to DataStructures.jl
The question is not super-clear, but I am under the impression that @udistr may just be looking for a function that makes this array, and may be fine with a Matrix. In that case, a loop should be fine.
Defining a new array type was my direction also. But I am still not sure how to implement the basic operations getindex and setindex!. This is so far what I was able to come up with:
struct CircularArray
x
end
function (getindex::CircularArray)(i,j)
x=getindex.x
S=size(x);
nx=S[1];ny=S[2];
if (i>0 && i<=nx) && (j>0 && j<=ny)
return x[i,j]
else
if i<1
i1 = nx+i
j1 = j
return getindex(i1,j1)
end
if i>nx
i1 = i-nx
j1 = j
return getindex(i1,j1)
end
if j<1
i1 = i
j1 = ny+j
return getindex(i1,j1)
end
if j>ny
i1 = i
j1 = j-ny
return getindex(i1,j1)
end
end
end
x=reshape(collect(0:15).%4 .+1,(4,4));
y=x'
x1=CircularArray(x)
y1=CircularArray(y)
i=0;j=1;
x1(i,j),y1(i,j)
What should I do in order to be able to get the index with square brackets - x1[5,1] and how to set values, e.g., x[5,1]=1 ?
I do plan to use this for finite difference calculations but for some operations, such as box mean, it is not enough to have only the halo.
struct CircularArray{T,N} <: AbstractArray{T,N} #inherits from AbstractArray
x::AbstractArray{T,N}
function CircularArray(x::AbstractArray{T,N}) where {T,N}
#creates the type only with a vector x
return new{T,N}(x)
end
end
Base.size(A::CircularArray) = size(A.x) #important: use of Base.function
Base.length(A::CircularArray)=length(A.x)
function Base.getindex(A::CircularArray, I::Vararg{Int, N}) where N # implements A[I]
I2 = size(A)
return Base.getindex(A.x,(mod.(I .- 1,I2) .+ 1)...) #this is the magic operation
end
Base.getindex(A::CircularArray, I) = (A[i] for i in I) #A[1:5], for example
function Base.setindex!(A,value,I::Vararg{Int, N}) where N # A[I] = value
return Base.setindex!(A.x,value,(mod.(I .- 1,I2) .+ 1)...)
end
Base.IndexStyle(::Type{CircularArray}) = IndexCartesian()
CyclicArrays.jl is aimed at handling more complex multi-face array topologies. For example, a cubed-sphere grid with 6 faces, in which the faces are interconnected in a non-trivial manner.