Not clear why cumsum! doesn't work in this simple case

The source vector is a column of x and the destination vector is a different column of x. There is nothing in the documentation or source code that says that the base array can’t be the same. Seems to defeat the purpose for some common cases. See the example.

It’s easy enough to use the non-inplace version.

Well, it doesn’t work when I do an example with x and y–different base arrays. It appears that it doesn’t like slices for some reason. Is there something about slices that makes the implementation infeasible?

Example:

julia> x = [collect(1:5) collect(4:8) zeros(Int,5)]

5×3 Array{Int64,2}:
 1  4  0
 2  5  0
 3  6  0
 4  7  0
 5  8  0

julia> display(x)
5×3 Array{Int64,2}:
 1  4  0
 2  5  0
 3  6  0
 4  7  0
 5  8  0

julia> cumsum!(x[:,3], x[:,2], dims=1)
5-element Array{Int64,1}:
  4
  9
 15
 22
 30

julia> x
5×3 Array{Int64,2}:
 1  4  0
 2  5  0
 3  6  0
 4  7  0
 5  8  0

You’re making a copy when you slice x. That copy is modified but x is unchanged. If you use views instead, then you get (presumably) the desired result:

julia> @views cumsum!(x[:,3], x[:,2], dims=1)
5-element view(::Array{Int64,2}, :, 3) with eltype Int64:
  4
  9
 15
 22
 30

julia> x
5×3 Array{Int64,2}:
 1  4   4
 2  5   9
 3  6  15
 4  7  22
 5  8  30
4 Likes

Woops! Sometimes I forget when we copy and when we get an alias to the same data in memory.

That’s easy to fix. No problem doing this with the macro. Is this the best way for this use case?

Thanks.

Other than looping manually, yes, that should be pretty good. Creating the views is not that expensive compared to copying the array contents (depending on the size of the input array, of course).

On master creating views is now basically free, so in 1.5 using views will be just as good as writing out the loops.

4 Likes