# Mod1 for CartesianIndex

**URL:** <https://discourse.julialang.org/t/mod1-for-cartesianindex/125065>\
**Category:** New to Julia\
**Tags:** cartesianindices\
**Created:** [January 22, 2025, 9:31am UTC](https://discourse.julialang.org/t/mod1-for-cartesianindex/125065 "2025-01-22T09:31:27Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![JoergF](https://avatars.discourse-cdn.com/v4/letter/j/47e85d/32.png) [@JoergF](https://discourse.julialang.org/u/JoergF)\
**Post date:** [January 22, 2025, 9:31am UTC](https://discourse.julialang.org/t/mod1-for-cartesianindex/125065/1 "2025-01-22T09:31:27Z")

</div>

Since there is no implementation of mod1 for a CartesianIndex I wanted to implement one myself. However I am confused how to make it performant.

```julia
function mod1(CI::CartesianIndex{2}, MOD::CartesianIndex{2})
    CartesianIndex(mod1(CI[1], MOD[1]), mod1(CI[2], MOD[2]))
end

```

This implementation is performing well is however not very generic.  
The more generic version I came up with

```julia
function mod1(CI::CartesianIndex{N}, MOD::CartesianIndex{N}) where N
	vals = [mod1(CI[i], MOD[i]) for i in 1:N]
	CartesianIndex(vals...)
end

```

unfortunately (and obviously) does not perform all too well.  
So basically I am wondering how to implement the generic version more performant.

---

<div class="post-metadata">

**Author:** ![anowacki](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/anowacki/32/17375_2.png) [@anowacki](https://discourse.julialang.org/u/anowacki)\
**Post date:** [January 22, 2025, 9:46am UTC](https://discourse.julialang.org/t/mod1-for-cartesianindex/125065/2 "2025-01-22T09:46:20Z")

</div>

> [@JoergF](#):
>
> ```julia
> function mod1(CI::CartesianIndex{N}, MOD::CartesianIndex{N}) where N
> vals = [mod1(CI[i], MOD[i]) for i in 1:N]
> CartesianIndex(vals...)
> end
> 
> ```

Replace this with, using [`ntuple`](https://docs.julialang.org/en/v1/base/base/#Base.ntuple):

```julia
function mod1(CI::CartesianIndex{N}, MOD::CartesianIndex{N}) where N
    vals = ntuple(i -> Base.mod1(CI[i], MOD[i]), N)
    CartesianIndex(vals...)
end

```

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [January 22, 2025, 3:11pm UTC](https://discourse.julialang.org/t/mod1-for-cartesianindex/125065/3 "2025-01-22T15:11:49Z")

</div>

Normally I would have implemented this by converting to `Tuple` and broadcasting like

```julia
function Base.mod1(CI::CartesianIndex{N}, MOD::CartesianIndex{N}) where N
	CartesianIndex(mod1.(Tuple(CI), Tuple(MOD)))
end

```

but for some reason this results in allocations so benchmarks poorly relative to the `ntuple` implementation. Oh well, `ntuple` it is…

I wasn’t going to post just to say that. What I really wrote in to say is that this function is an example of [type piracy](https://docs.julialang.org/en/v1/manual/style-guide/#avoid-type-piracy) and should be avoided except as a pull request to Julia itself. Otherwise, consider naming it something else to avoid the potential for (not so?) hilarious bugs in the future.

---

<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:** [January 22, 2025, 3:20pm UTC](https://discourse.julialang.org/t/mod1-for-cartesianindex/125065/4 "2025-01-22T15:20:30Z")

</div>

This seems like something we could support directly. We have `mod(::Int, ::UnitRange)`; the direct corollary here is `mod(::CartesianIndex, ::CartesianIndices)`.

```julia-repl
julia> mod(9, 1:7)
2

julia> mod(CartesianIndex((2,9)), CartesianIndices((1:2, 1:7)))
ERROR: MethodError: no method matching mod(::CartesianIndex{2}, ::CartesianIndices{2, Tuple{UnitRange{Int64}, UnitRange{Int64}}})
Stacktrace:
 [1] top-level scope
   @ REPL[5]:1

```

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [January 22, 2025, 3:26pm UTC](https://discourse.julialang.org/t/mod1-for-cartesianindex/125065/5 "2025-01-22T15:26:30Z")

</div>

I was thinking about that. The annoying thing is that we don’t have support for (nor an obvious answer for) `mod(::Int, ::StepRange)` so couldn’t support all `CartesianIndices`. But it still seems like a nice generalization in the `AbstractUnitRange` cases where it would apply. It would probably be accepted as a PR to Base without too much fuss.

---

<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:** [January 22, 2025, 3:30pm UTC](https://discourse.julialang.org/t/mod1-for-cartesianindex/125065/6 "2025-01-22T15:30:45Z")

</div>

Yeah, the most powerful idiom this would enable is `mod(i, CartesianIndices(A))`, where you can be sure that it’s a `CartesianIndices{<:AbstractUnitRange}`. I think it’s fine to leave the other cases as a method error.

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [January 22, 2025, 6:00pm UTC](https://discourse.julialang.org/t/mod1-for-cartesianindex/125065/7 "2025-01-22T18:00:47Z")

</div>

aside from type piracy

```julia
function mod1(CI::CartesianIndex{N}, MOD::CartesianIndex{N}) where N
	vals = (mod1(CI[i], MOD[i]) for i in 1:N)
	CartesianIndex(vals...)
end

```
