# Custom Indices in OffsetArrays

**URL:** <https://discourse.julialang.org/t/custom-indices-in-offsetarrays/22886>\
**Category:** New to Julia\
**Created:** [April 7, 2019, 6:53pm UTC](https://discourse.julialang.org/t/custom-indices-in-offsetarrays/22886 "2019-04-07T18:53:12Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![OvidiusCicero](https://avatars.discourse-cdn.com/v4/letter/o/73ab20/32.png) [@OvidiusCicero](https://discourse.julialang.org/u/OvidiusCicero)\
**Post date:** [April 7, 2019, 6:53pm UTC](https://discourse.julialang.org/t/custom-indices-in-offsetarrays/22886/1 "2019-04-07T18:53:13Z")

</div>

Is it possible to declare an array whose indices leave out every second index, eg such that the set of indices is `0,2,4,6`?

```julia
a[0] = 1
a[2] = 2
a[4] = 3
a[6] = 4

```

The naive try

```julia
using OffsetArrays
y=OffsetArray(collect(1:4),collect(0:2:6))

```

did not work

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [April 7, 2019, 11:37pm UTC](https://discourse.julialang.org/t/custom-indices-in-offsetarrays/22886/2 "2019-04-07T23:37:03Z")

</div>

I think that would be hard to implement.

```julia
struct MyOffsetVector{T,S} <: AbstractVector{T}
    data::Vector{T}
    offset::Int
end
@generated function offset_index(v::MyOffsetVector{T,S}, i) where {T,S}
    S == 1 && return :(i - v.offset + 1)
    log2S = log2(S)
    if round(log2S) == log2S
        return :( ((i - v.offset) >> $log2S) + 1)
    else
        return :( ((i - v.offset) ÷ $S) + 1)
    end
end
@inbounds Base.getindex(v::MyOffsetVector, i) = v.data[offset_index(v,i)]
@inbounds Base.setindex!(v::MyOffsetVector, i, x) = v.data[offset_index(v,i)] = x
Base.size(v::MyOffsetVector) = size(v.data)

```

You might want to replace `offset_index` with something that throws an error if there is a remainder (ie, use `divrem`, and throw an error for non-zero remainders).

I haven’t tested this, but I imagine you’ll see a lot of errors from here.  
For example `IndexStyle()` is neither `IndexLinear()` or `IndexCartesian()`, meaning things like “print” will try generic Cartesian indices incrementing by a step at a time for printing and other array operations.

So if I wanted to do something like this, I’d probably look into defining a new IndexStyle.  
[AbstractArray Interface](https://docs.julialang.org/en/v1/manual/interfaces/index.html#man-interface-array-1).

---

<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:** [April 8, 2019, 6:08am UTC](https://discourse.julialang.org/t/custom-indices-in-offsetarrays/22886/3 "2019-04-08T06:08:51Z")

</div>

> [@OvidiusCicero](#):
>
> Is it possible to declare an array whose indices leave out every second index, eg such that the set of indices is `0,2,4,6` ?

No, this violates the current interface, ie that `axes` returns a `Tuple` of `AbstractUnitRange` objects, which have a step of `1`. See this discussion:

> [@Custom index arithmetic](https://discourse.julialang.org/t/custom-index-arithmetic/14374):
>
> This is a clarifying question about [custom indexing](https://docs.julialang.org/en/stable/devdocs/offset-arrays/#man-custom-indices-1). If x::AbstractVector has a conforming interface, can I assume that that the valid indexes are firstindex(x):lastindex(x), ie they are integers (so nothing wacky like Float64s or Symbol), forming a contiguous range, so I can do arithmetic on them, at least index += some\_step. This is for an algorithm that I find difficult to express in an iterator form using eachindex. Sorry if this is obvious and already clearly discussed in the manual.

---

<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:** [April 8, 2019, 6:16am UTC](https://discourse.julialang.org/t/custom-indices-in-offsetarrays/22886/4 "2019-04-08T06:16:57Z")

</div>

it is necessary? if its an even number, you can use a normal array and apply and operation over the index:

```julia
my_index(i) = Int(i/2)+1
a = 1:10
julia> a[my_index(0)] #=a[1]

```

if its not, you can raise an error or round to a corresponding integer

---

<div class="post-metadata">

**Author:** ![OvidiusCicero](https://avatars.discourse-cdn.com/v4/letter/o/73ab20/32.png) [@OvidiusCicero](https://discourse.julialang.org/u/OvidiusCicero)\
**Post date:** [April 8, 2019, 6:46am UTC](https://discourse.julialang.org/t/custom-indices-in-offsetarrays/22886/5 "2019-04-08T06:46:23Z")

</div>

Yes, that is what I currently do.

No it is not necessary

---

<div class="post-metadata">

**Author:** ![OvidiusCicero](https://avatars.discourse-cdn.com/v4/letter/o/73ab20/32.png) [@OvidiusCicero](https://discourse.julialang.org/u/OvidiusCicero)\
**Post date:** [April 8, 2019, 6:47am UTC](https://discourse.julialang.org/t/custom-indices-in-offsetarrays/22886/6 "2019-04-08T06:47:03Z")

</div>

okay thank you for your clarification
