# Reverse view of an array

**URL:** <https://discourse.julialang.org/t/reverse-view-of-an-array/9657>\
**Category:** Internals & Design\
**Created:** [March 12, 2018, 5:00am UTC](https://discourse.julialang.org/t/reverse-view-of-an-array/9657 "2018-03-12T05:00:48Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![kevin.squire](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kevin.squire/32/62_2.png) [@kevin.squire](https://discourse.julialang.org/u/kevin.squire)\
**Post date:** [March 12, 2018, 5:00am UTC](https://discourse.julialang.org/t/reverse-view-of-an-array/9657/1 "2018-03-12T05:00:48Z")

</div>

While reviewing a recent pull request in `Images.jl`, I ran across [this line](https://github.com/arijitkar98/Images.jl/blob/b4a4437c64c4eddb5b04ebec5f8f8fdfba44d345/src/algorithms.jl#L897):

```julia
    cum_pmf_sq_2 = reverse!(cumsum(reverse!(prob_mass_function_sq)))

```

Using `reverse!` is better than `reverse` here, but writing out the loops manually would certainly be more efficient. I’m wondering if it’s worthwhile to try to add some conveniences for this:

1. Add a `reverse` or `rev` keyword to `accumulate` (and `cumsum`, `cumprod`, etc.)
2. Add a `ReverseView` wrapper to a `Vector`, which reverses the indexes (and therefore iteration), but otherwise leaves the data alone.

@stevengj recently added `Iterators.Reverse`, but that doesn’t work here, as `cumsum` (which is based on `accumulate`) requires an `AbstractArray`, and `Iterators.Reverse` isn’t one of those.

I can, of course, make these additions in a package, but they seem general enough that perhaps they could be included in Base. Thoughts?

Cheers,  
Kevin

---

<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:** [March 12, 2018, 7:22am UTC](https://discourse.julialang.org/t/reverse-view-of-an-array/9657/2 "2018-03-12T07:22:25Z")

</div>

A `ReverseView` would compose better than extra keywords to functions. If the performance penalty is not too large, it would be my preferred solution, as a middle ground between optimized loops and copying operations.

---

<div class="post-metadata">

**Author:** ![nalimilan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nalimilan/32/147_2.png) [@nalimilan](https://discourse.julialang.org/u/nalimilan)\
**Post date:** [March 12, 2018, 8:41am UTC](https://discourse.julialang.org/t/reverse-view-of-an-array/9657/3 "2018-03-12T08:41:07Z")

</div>

> [@kevin.squire](#):
>
> @stevengj recently added Iterators.Reverse, but that doesn’t work here, as cumsum (which is based on accumulate) requires an AbstractArray, and Iterators.Reverse isn’t one of those.

Is there a fundamental reason why `accumulate` couldn’t work with any iterator? It looks like we just need to fix that limitation.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 12, 2018, 12:21pm UTC](https://discourse.julialang.org/t/reverse-view-of-an-array/9657/4 "2018-03-12T12:21:18Z")

</div>

> [@kevin.squire](#):
>
> Add a `ReverseView` wrapper to a `Vector`

`SubArray` already supports this. Try `view(a, lastindex(a):-1:firstindex(a))`. (`using Compat` for `firstindex` and `lastindex` on 0.6.)

Having an `accumulate` function that works on iterators would be great, though it is [tricky to make fast and type-stable](https://github.com/JuliaLang/julia/pull/25766). Here, however, note that `cumsum` on floating-point arrays is actually much more accurate than any iterator-based version because it [uses pairwise summation](https://github.com/JuliaLang/julia/issues/9648). Also, I suspect that the original use-case in this thread might want to use `cumsum!` so that it could operate in-place, and that wouldn’t be possible for iterators.

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [March 12, 2018, 2:47pm UTC](https://discourse.julialang.org/t/reverse-view-of-an-array/9657/5 "2018-03-12T14:47:36Z")

</div>

Just a side-track: isn’t it possible to use series math to do, for instance, `cumsum!` on Iterators?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 12, 2018, 2:48pm UTC](https://discourse.julialang.org/t/reverse-view-of-an-array/9657/6 "2018-03-12T14:48:55Z")

</div>

> [@yakir12](#):
>
> isn’t it possible to use series math to do, for instance, `cumsum!` on Iterators?`

The iterator protocol in Julia provides no way to mutate the iterator contents.

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [March 12, 2018, 2:53pm UTC](https://discourse.julialang.org/t/reverse-view-of-an-array/9657/7 "2018-03-12T14:53:50Z")

</div>

Oh right…

---

<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:** [March 15, 2023, 8:35pm UTC](https://discourse.julialang.org/t/reverse-view-of-an-array/9657/9 "2023-03-15T20:35:41Z")

</div>

2 posts were split to a new topic: [How to create a reversed view that allows for growing arrays?](https://discourse.julialang.org/t/how-to-create-a-reversed-view-that-allows-for-growing-arrays/96148)

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [March 15, 2023, 10:09pm UTC](https://discourse.julialang.org/t/reverse-view-of-an-array/9657/10 "2023-03-15T22:09:27Z")

</div>

> [@kevin.squire](#):
>
> 1. Add a `ReverseView` wrapper to a `Vector`, which reverses the indexes (and therefore iteration), but otherwise leaves the data alone.

Could it support multi-dimensional arrays too? Via a `dim` keyword,

```julia
R = ReverseView(A; dims=(2,4))

```

would reverse indices along dimensions 2 and 4, whereas dimensions 1, 3 (or any other dimension) map to the original array unchanged:

```julia
R[i,j,k,l] == A[i, end - j + 1, k, end - l + 1]

```

To achieve this with `view`, it seems necessary to specify what happens for each dimension explicitly,

```julia
R = @view A[:, lastindex(A,2):-1:firstindex(A,2), :, lastindex(A,4):-1:firstindex(A,4)]

```

which is considerably more verbose and harder to read. It’s also harder to write in a context where `A` has an unknown number of dimensions but you know that dimension 2 has to be reversed (which admittedly need not be that common).

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 16, 2023, 12:12am UTC](https://discourse.julialang.org/t/reverse-view-of-an-array/9657/11 "2023-03-16T00:12:03Z")

</div>

> [@e3c6](#):
>
> Could it support multi-dimensional arrays too? Via a `dim` keyword,

This already works:

```julia
R = @view A[axes(A,1), reverse(axes(A,2)), axes(A,3), reverse(axes(A,4))]

```

It would be convenient to just do

```julia
I = CartesianIndices(A)
R = @view A[reverse(I, dims=(2,4))]

```

but I noticed that reversing `CartesianIndices` is currently highly suboptimal (returning an `Array`), so that would have to be fixed first: [optimized reverse(::CartesianIndices, dims=...) · Issue #49021 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/49021)
