Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Library improvements
* Arithmetic is type-preserving for more types; e.g. `(x::Int8) + (y::Int8)` now
yields an `Int8` ([#3759]).

* Reductions (e.g. `reduce`, `sum`) widen small types (integers smaller than `Int`, and `Float16`).
* Reductions (e.g. `reduce`, `sum`) widen small types (integers smaller than `Int`, and `Float16`). Similarly for `cumsum` ([#9665]).

* New `Dates` module for calendar dates and other time-interval calculations ([#7654]).

Expand Down Expand Up @@ -1149,5 +1149,8 @@ Too numerous to mention.
[#9261]: https://github.com/JuliaLang/julia/issues/9261
[#9271]: https://github.com/JuliaLang/julia/issues/9271
[#9294]: https://github.com/JuliaLang/julia/issues/9294
[#9569]: https://github.com/JuliaLang/julia/issues/9569
[#9418]: https://github.com/JuliaLang/julia/issues/9418
[#9452]: https://github.com/JuliaLang/julia/issues/9452
[#9569]: https://github.com/JuliaLang/julia/issues/9569
[#9578]: https://github.com/JuliaLang/julia/issues/9578
[#9665]: https://github.com/JuliaLang/julia/issues/9665
22 changes: 12 additions & 10 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1452,11 +1452,11 @@ symdiff(a) = a
symdiff(a, b) = union(setdiff(a,b), setdiff(b,a))
symdiff(a, b, rest...) = symdiff(a, symdiff(b, rest...))

_cumsum_type{T<:Number}(v::AbstractArray{T}) = typeof(+zero(T))
_cumsum_type(v) = typeof(v[1]+v[1])
_cumsum_type{T<:Number}(v::AbstractArray{T}) = typeof(r_promote(AddFun, zero(T)::T))
_cumsum_type(v) = typeof(r_promote(AddFun, v[1]))

for (f, fp, op) = ((:cumsum, :cumsum_pairwise!, :+),
(:cumprod, :cumprod_pairwise!, :*) )
for (f, f!, fp, op) = ((:cumsum, :cumsum!, :cumsum_pairwise!, :+),
(:cumprod, :cumprod!, :cumprod_pairwise!, :*) )
# in-place cumsum of c = s+v[range(i1,n)], using pairwise summation
@eval function ($fp){T}(v::AbstractVector, c::AbstractVector{T}, s, i1, n)
local s_::T # for sum(v[range(i1,n)]), i.e. sum without s
Expand All @@ -1475,16 +1475,18 @@ for (f, fp, op) = ((:cumsum, :cumsum_pairwise!, :+),
return s_
end

@eval function ($f)(v::AbstractVector)
@eval function ($f!)(result::AbstractVector, v::AbstractVector)
n = length(v)
if n == 0; return result; end
($fp)(v, result, $(op==:+ ? :(zero(v[1])) : :(one(v[1]))), 1, n)
return result
end

@eval function ($f)(v::AbstractVector)
c = $(op===:+ ? (:(similar(v,_cumsum_type(v)))) :
(:(similar(v))))
if n == 0; return c; end
($fp)(v, c, $(op==:+ ? :(zero(v[1])) : :(one(v[1]))), 1, n)
return c
return ($f!)(c, v)
end

@eval ($f)(A::AbstractArray) = ($f)(A, 1)
end

for (f, op) = ((:cummin, :min), (:cummax, :max))
Expand Down
7 changes: 7 additions & 0 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -978,4 +978,11 @@ a = [ [ 1 0 0 ], [ 0 0 0 ] ]
# issue #9648
let x = fill(1.5f0, 10^7)
@test abs(1.5f7 - cumsum(x)[end]) < 3*eps(1.5f7)
@test cumsum(x) == cumsum!(similar(x), x)
end

# cumsum type consistency (discussed in #9650)
let x = Uint8[1,2,3,4,6,7]
@test eltype(cumsum(x)) == typeof(sum(x)) == eltype(cumsum(reshape(x,3,2)))
@test cumsum(x) == cumsum!(similar(x),x) == cumsum!(similar(x,Int), x)
end