# Mapping Linear Indices to Cartesian Indices

**URL:** <https://discourse.julialang.org/t/mapping-linear-indices-to-cartesian-indices/130424>\
**Category:** General Usage\
**Tags:** question\
**Created:** [July 2, 2025, 5:33pm UTC](https://discourse.julialang.org/t/mapping-linear-indices-to-cartesian-indices/130424 "2025-07-02T17:33:04Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![prconlin](https://avatars.discourse-cdn.com/v4/letter/p/b19c9b/32.png) [@prconlin](https://discourse.julialang.org/u/prconlin)\
**Post date:** [July 2, 2025, 5:33pm UTC](https://discourse.julialang.org/t/mapping-linear-indices-to-cartesian-indices/130424/1 "2025-07-02T17:33:05Z")

</div>

Hello,

I’m working with matrices in such a way that I want to be able to access values by both the Cartesian and linear Indices. I want to be able to map any given linear index to its Cartesian counterpart and vice versa.

This is the best I have so far:

```julia
> a = rand(3,3)

3×3 Matrix{Float64}:
 0.806 0.512 0.657
 0.278 0.313 0.266
 0.793 0.707 0.720

> for (index, value) in enumerate(CartesianIndices(a))
       println(index, ", ", Tuple(value), ", ", a[index])
  end

1, (1, 1), 0.806
2, (2, 1), 0.278
3, (3, 1), 0.793
4, (1, 2), 0.512
5, (2, 2), 0.313
6, (3, 2), 0.707
7, (1, 3), 0.657
8, (2, 3), 0.266
9, (3, 3), 0.720

```

The loop iterates over the matrix using its Cartesian indices, and enumerate applies a label to each element which happens to correspond to the linear index. I can save this map as an array of tuples, which would work, but it seems really clumsy. And I’m sure there is a built-in function that does what I need, I just haven’t been able to google exactly the right phrase yet.

Thanks in advance

---

<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:** [July 2, 2025, 5:44pm UTC](https://discourse.julialang.org/t/mapping-linear-indices-to-cartesian-indices/130424/2 "2025-07-02T17:44:29Z")

</div>

> [@prconlin](#):
>
> map any given linear index to its Cartesian counterpart

Both `LinearIndices(a)` and `CartesianIndices(a)` are array-like objects, which can be indexed in either way. Is this what you want?

```julia
julia> CartesianIndices(rand(3,3))[6]
CartesianIndex(3, 2)

julia> LinearIndices(rand(3,3))[CartesianIndex(3,2)]
6

```

You can also map or broadcast over these things, e.g. `broadcast(println, LinearIndices(rand(3,3)), " -> ", CartesianIndices(rand(3,3)), " -> ", rand(3,3));`

---

<div class="post-metadata">

**Author:** ![prconlin](https://avatars.discourse-cdn.com/v4/letter/p/b19c9b/32.png) [@prconlin](https://discourse.julialang.org/u/prconlin)\
**Post date:** [July 2, 2025, 6:17pm UTC](https://discourse.julialang.org/t/mapping-linear-indices-to-cartesian-indices/130424/3 "2025-07-02T18:17:45Z")

</div>

Thanks for your reply.

I’m looking for a function that will take in one type of index and output the other for a given matrix. Something like `Cart2Linear(a, (2,2))`, which would output 5 for a 3x3 matrix `a` There would also be an inverse function `Linear2Cart()` which does the opposite.

Looking at your note, `LinearIndices()` does (part of) what I need:

```julia
> a = rand(3,3)

3×3 Matrix{Float64}:
 0.806 0.512 0.657
 0.278 0.313 0.266
 0.793 0.707 0.720

> a_linear = LinearIndices(a)

3×3 LinearIndices{2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}:
 1 4 7
 2 5 8
 3 6 9

```

simply calling `a_linear[i,j]` gives me the linear index corresponding to Cartesian index (i, j), which is exactly what want. The inverse doesn’t seem to work exactly the same way, though:

```julia
> CartesianIndices(a)
CartesianIndices((3, 3))

```

I was expecting a 3x3 matrix of tuples, where each tuple is the the Cartesian index of that element.

If necessary, it wouldn’t be difficult to write a function which computes the Cartesian index for any linear index given the dimensions of the matrix. But I expected that this functionality would already exist.

---

<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:** [July 2, 2025, 6:22pm UTC](https://discourse.julialang.org/t/mapping-linear-indices-to-cartesian-indices/130424/4 "2025-07-02T18:22:24Z")

</div>

We should probably make `LinearIndices` and `CartesianIndices` print more similarly.

> [@prconlin](#):
>
> I was expecting a 3x3 matrix of tuples,

Yeah, that’s what it is — well, it’s a matrix of `CartesianIndex`es that hold the tuples — but it just doesn’t print like it.

```julia
julia> collect(CartesianIndices((3, 3)))
3×3 Matrix{CartesianIndex{2}}:
 CartesianIndex(1, 1) CartesianIndex(1, 2) CartesianIndex(1, 3)
 CartesianIndex(2, 1) CartesianIndex(2, 2) CartesianIndex(2, 3)
 CartesianIndex(3, 1) CartesianIndex(3, 2) CartesianIndex(3, 3)

```

---

<div class="post-metadata">

**Author:** ![prconlin](https://avatars.discourse-cdn.com/v4/letter/p/b19c9b/32.png) [@prconlin](https://discourse.julialang.org/u/prconlin)\
**Post date:** [July 2, 2025, 8:29pm UTC](https://discourse.julialang.org/t/mapping-linear-indices-to-cartesian-indices/130424/5 "2025-07-02T20:29:17Z")

</div>

Oh, okay. That makes sense.

So for a given matrix `a`, we can convert a linear index `n` to a Cartesian index using:  
`CartesianIndices(a)[n]`  
Inversely, we can convert a Cartesian index `(i,j)` to a linear index using:  
`LinearIndices(a)[2,2]`

This is exactly what I needed. One remaining question - do the above methods allocate a new matrix every time? That would be problematic.

---

<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:** [July 2, 2025, 8:40pm UTC](https://discourse.julialang.org/t/mapping-linear-indices-to-cartesian-indices/130424/6 "2025-07-02T20:40:32Z")

</div>

> [@prconlin](#):
>
> One remaining question - do the above methods allocate a new matrix every time?

Nope, just like the range `1:9`, they are lazy computational objects that just _behave_ like an `Array`. You can index into them and even do maths on them, but they won’t take up any space unless you explicitly `collect` them like I did above. They’re often completely removed from the actual compiled code.
