# Circular array in Julia

**URL:** <https://discourse.julialang.org/t/circular-array-in-julia/25588>\
**Category:** Geo\
**Created:** [June 24, 2019, 12:51am UTC](https://discourse.julialang.org/t/circular-array-in-julia/25588 "2019-06-24T00:51:59Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![udistr](https://avatars.discourse-cdn.com/v4/letter/u/73ab20/32.png) [@udistr](https://discourse.julialang.org/u/udistr)\
**Post date:** [June 24, 2019, 12:51am UTC](https://discourse.julialang.org/t/circular-array-in-julia/25588/1 "2019-06-24T00:51:59Z")

</div>

Is the a simple way in Julia to define circular array, e.g., if I have:

x=zeros(4,4)

I would like that:

x[1,5] = x[1,1]  
x[1,6] = x[1,2]  
…

and

x[5,1] = x[1,1]  
x[6,1] = x[2,1]  
…

I would like to define a more complex grid topology so simple solution like adding the reminder operator:

x[1%4,5%4]

will not help

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [June 24, 2019, 2:31am UTC](https://discourse.julialang.org/t/circular-array-in-julia/25588/2 "2019-06-24T02:31:48Z")

</div>

Welcome to Julia’s Discourse forum!, about your question, you can define your own array type, defining the necessary interfaces ([see this link](https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-array-1)). for example, a starting base can be this (supposing the circular size is the size of the data):

```julia
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.

```julia
size(A::CircularArray) = size(A.x)

```

anyway, if this is made, it can be a nice adition to [DataStructures.jl](https://github.com/JuliaCollections/DataStructures.jl)

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [June 24, 2019, 2:34am UTC](https://discourse.julialang.org/t/circular-array-in-julia/25588/3 "2019-06-24T02:34:15Z")

</div>

> [@udistr](#):
>
> would like to define a more complex grid topology so simple solution like adding the reminder operator:

Also, related post from discourse can help:

> [@Arrays with periodic boundaries](https://discourse.julialang.org/t/arrays-with-periodic-boundaries/4015/4):
>
> If you’re working with e.g. finite-difference approximations and similar lattice-based computations, often it is more flexible to use e.g. “ghost elements” (also called “ghost points”, “ghost cells”, “overlap regions”, “ghost zones”, …): you have an extra array element at each edge of the array that you update with whatever boundary condition you want as needed (e.g. at each time step). The motivation here is: For typical lattice-based simulations, you only need to access elements adjacent …

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [June 24, 2019, 3:38am UTC](https://discourse.julialang.org/t/circular-array-in-julia/25588/4 "2019-06-24T03:38:14Z")

</div>

> [@longemen3000](#):
>
> you can define your own array type

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.

---

<div class="post-metadata">

**Author:** ![udistr](https://avatars.discourse-cdn.com/v4/letter/u/73ab20/32.png) [@udistr](https://discourse.julialang.org/u/udistr)\
**Post date:** [June 24, 2019, 5:14am UTC](https://discourse.julialang.org/t/circular-array-in-julia/25588/5 "2019-06-24T05:14:18Z")

</div>

Thanks [longemen3000](https://discourse.julialang.org/u/longemen3000),

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:

```julia
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.

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [June 24, 2019, 5:21am UTC](https://discourse.julialang.org/t/circular-array-in-julia/25588/6 "2019-06-24T05:21:35Z")

</div>

> [@udistr](#):
>
> ```julia
> if i<1 
> i1 = nx-i 
> j1 = j 
> return getindex(i1,j1)
> 
> ```

so, you need negative implementations?, lets see what can i do

---

<div class="post-metadata">

**Author:** ![udistr](https://avatars.discourse-cdn.com/v4/letter/u/73ab20/32.png) [@udistr](https://discourse.julialang.org/u/udistr)\
**Post date:** [June 24, 2019, 5:27am UTC](https://discourse.julialang.org/t/circular-array-in-julia/25588/7 "2019-06-24T05:27:09Z")

</div>

There is a typo there, it should be:

```julia
i1 = nx+i

```

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [June 24, 2019, 6:11am UTC](https://discourse.julialang.org/t/circular-array-in-julia/25588/8 "2019-06-24T06:11:39Z")

</div>

try this, the implementation is multidimentional

```julia
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() 

```

example code:

```julia
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]

```

this works in N dimensions:

```julia
#1-dimentional example
z = 1:15
z2 = CircularArray(z)
z2[16] # 1
z3 = collect(z2[14:16]) #[14,15,1]

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [June 24, 2019, 6:48am UTC](https://discourse.julialang.org/t/circular-array-in-julia/25588/9 "2019-06-24T06:48:44Z")

</div>

When implementing a circular array, doesn’t it make much more sense to use 0-based indexing?

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [June 24, 2019, 6:53am UTC](https://discourse.julialang.org/t/circular-array-in-julia/25588/10 "2019-06-24T06:53:58Z")

</div>

maybe, my toughts were to preserve the 1-based indexing of julia, and preserve the equality `circular_x[i,j] == x[i,j]`

---

<div class="post-metadata">

**Author:** ![piever](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piever/32/1815_2.png) [@piever](https://discourse.julialang.org/u/piever)\
**Post date:** [June 24, 2019, 11:15am UTC](https://discourse.julialang.org/t/circular-array-in-julia/25588/11 "2019-06-24T11:15:12Z")

</div>

There exists an implementation in ShiftedArrays: [https://github.com/piever/ShiftedArrays.jl/blob/master/src/circshiftedarray.jl](https://github.com/piever/ShiftedArrays.jl/blob/master/src/circshiftedarray.jl)

If you need something more complex but along these lines, hopefully it can serve as a starting point to write your own custom array type.

---

<div class="post-metadata">

**Author:** ![fabiangans](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fabiangans/32/2624_2.png) [@fabiangans](https://discourse.julialang.org/u/fabiangans)\
**Post date:** [June 24, 2019, 1:53pm UTC](https://discourse.julialang.org/t/circular-array-in-julia/25588/12 "2019-06-24T13:53:21Z")

</div>

And there is the `mod1` function to avoid all this shifting indices manually:

```julia
julia> mod1(5,5)
5

julia> mod1(6,5)
1

```

---

<div class="post-metadata">

**Author:** ![udistr](https://avatars.discourse-cdn.com/v4/letter/u/73ab20/32.png) [@udistr](https://discourse.julialang.org/u/udistr)\
**Post date:** [June 24, 2019, 5:14pm UTC](https://discourse.julialang.org/t/circular-array-in-julia/25588/13 "2019-06-24T17:14:59Z")

</div>

Thanks again [longemen3000](https://discourse.julialang.org/u/longemen3000) (and others)! This do what I want except this:

```julia
julia> x1[:,0]
ERROR: BoundsError: attempt to access 4×4 CircularArray{Int64,2} at index [Base.Slice(Base.OneTo(4)), 0]
Stacktrace:
 [1] throw_boundserror(::CircularArray{Int64,2}, ::Tuple{Base.Slice{Base.OneTo{Int64}},Int64}) at ./abstractarray.jl:484
 [2] checkbounds at ./abstractarray.jl:449 [inlined]
 [3] _getindex(::IndexCartesian, ::CircularArray{Int64,2}, ::Base.Slice{Base.OneTo{Int64}}, ::Int64) at ./multidimensional.jl:641
 [4] getindex(::CircularArray{Int64,2}, ::Function, ::Int64) at ./abstractarray.jl:927
 [5] top-level scope at none:0

```

x[1,0] and x[:,1] work so it is only a problem dealing with ranges outside array boundaries. Any ideas how to solve this?

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [June 24, 2019, 5:19pm UTC](https://discourse.julialang.org/t/circular-array-in-julia/25588/14 "2019-06-24T17:19:01Z")

</div>

That’s just a matter of defining the appropriate `checkbounds` specialization. In fact, I think you can simply turn off bounds checks entirely:

```julia
Base.checkbounds(A::CircularArray, I...) = nothing

```

---

<div class="post-metadata">

**Author:** ![francesco.alemanno](https://avatars.discourse-cdn.com/v4/letter/f/e8c25b/32.png) [@francesco.alemanno](https://discourse.julialang.org/u/francesco.alemanno)\
**Post date:** [June 24, 2019, 8:52pm UTC](https://discourse.julialang.org/t/circular-array-in-julia/25588/15 "2019-06-24T20:52:37Z")

</div>

This is material for a small compact package!

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [November 16, 2020, 10:26pm UTC](https://discourse.julialang.org/t/circular-array-in-julia/25588/16 "2020-11-16T22:26:10Z")

</div>

Is there a package with this circular array type available and well-tested already?

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [November 16, 2020, 11:11pm UTC](https://discourse.julialang.org/t/circular-array-in-julia/25588/17 "2020-11-16T23:11:06Z")

</div>

Perhaps [https://github.com/Vexatos/CircularArrays.jl](https://github.com/Vexatos/CircularArrays.jl) ?

---

<div class="post-metadata">

**Author:** ![udistr](https://avatars.discourse-cdn.com/v4/letter/u/73ab20/32.png) [@udistr](https://discourse.julialang.org/u/udistr)\
**Post date:** [November 17, 2020, 5:18am UTC](https://discourse.julialang.org/t/circular-array-in-julia/25588/18 "2020-11-17T05:18:22Z")

</div>

Maybe this one can help:

[https://github.com/udistr/CyclicArrays.jl](https://github.com/udistr/CyclicArrays.jl)

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [January 20, 2021, 1:19pm UTC](https://discourse.julialang.org/t/circular-array-in-julia/25588/19 "2021-01-20T13:19:30Z")

</div>

@udistr can you comment on the difference between CyclicArrays.jl and CircularArrays.jl? Aren’t they equivalent?

---

<div class="post-metadata">

**Author:** ![udistr](https://avatars.discourse-cdn.com/v4/letter/u/73ab20/32.png) [@udistr](https://discourse.julialang.org/u/udistr)\
**Post date:** [January 20, 2021, 1:58pm UTC](https://discourse.julialang.org/t/circular-array-in-julia/25588/20 "2021-01-20T13:58:29Z")

</div>

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.

[Next page](https://discourse.julialang.org/t/circular-array-in-julia/25588.md?page=2)
