Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate cumsum, cumprod, cumsum_kbn, and accumulate when dim isn't specified #24684

Merged
merged 5 commits into from
Nov 24, 2017
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Add docstrings for accumulation methods on vectors
Fix bug in accumulate when initial value is provided since the implementation
doesn't support multidimentional arrays.

Move the accumulate methods with initial values to the end
  • Loading branch information
andreasnoack committed Nov 23, 2017
commit 9e94f6cac35a2dc1c5b284c7c8254436b579c9de
200 changes: 138 additions & 62 deletions base/multidimensional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,27 @@ function cumsum(A::AbstractArray{T}, axis::Integer) where T
cumsum!(out, A, axis)
end

"""
cumsum(x::AbstractVector)

Cumulative sum a vector. See also [`cumsum!`](@ref)
to use a preallocated output array, both for performance and to control the precision of the
output (e.g. to avoid overflow).

```jldoctest
julia> cumsum([1, 1, 1])
3-element Array{Int64,1}:
1
2
3

julia> cumsum([fill(1, 2) for i in 1:3])
3-element Array{Array{Int64,1},1}:
[1, 1]
[2, 2]
[3, 3]
```
"""
cumsum(x::AbstractVector) = cumsum(x, 1)

"""
Expand All @@ -728,6 +749,11 @@ Cumulative sum of `A` along a dimension, storing the result in `B`. See also [`c
"""
cumsum!(B, A, axis::Integer) = accumulate!(+, B, A, axis)

"""
cumsum!(y::AbstractVector, x::AbstractVector)

Cumulative sum of a vector `x`, storing the result in `y`. See also [`cumsum`](@ref).
"""
cumsum!(y::AbstractVector, x::AbstractVector) = cumsum!(y, x, 1)

"""
Expand Down Expand Up @@ -756,6 +782,27 @@ julia> cumprod(a,2)
"""
cumprod(A::AbstractArray, axis::Integer) = accumulate(*, A, axis)

"""
cumprod(x::AbstractVector)

Cumulative product of a vector. See also
[`cumprod!`](@ref) to use a preallocated output array, both for performance and
to control the precision of the output (e.g. to avoid overflow).

```jldoctest
julia> cumprod(fill(1//2, 3))
3-element Array{Rational{Int64},1}:
1//2
1//4
1//8

julia> cumprod([fill(1//3, 2, 2) for i in 1:3])
3-element Array{Array{Rational{Int64},2},1}:
Rational{Int64}[1//3 1//3; 1//3 1//3]
Rational{Int64}[2//9 2//9; 2//9 2//9]
Rational{Int64}[4//27 4//27; 4//27 4//27]
```
"""
cumprod(x::AbstractVector) = cumprod(x, 1)

"""
Expand All @@ -766,6 +813,12 @@ See also [`cumprod`](@ref).
"""
cumprod!(B, A, axis::Integer) = accumulate!(*, B, A, axis)

"""
cumprod!(y::AbstractVector, x::AbstractVector)

Cumulative product of a vector `x`, storing the result in `y`.
See also [`cumprod`](@ref).
"""
cumprod!(y::AbstractVector, x::AbstractVector) = cumprod!(y, x, 1)

"""
Expand All @@ -778,83 +831,48 @@ there are specialized variants of `accumulate`, see:
[`cumsum`](@ref), [`cumprod`](@ref)

```jldoctest
julia> accumulate(+, [1,2,3])
3-element Array{Int64,1}:
1
3
6

julia> accumulate(*, [1,2,3])
3-element Array{Int64,1}:
1
2
6
julia> accumulate(+, fill(1, 3, 3), 1)
3×3 Array{Int64,2}:
1 1 1
2 2 2
3 3 3

julia> accumulate(+, fill(1, 3, 3), 2)
3×3 Array{Int64,2}:
1 2 3
1 2 3
1 2 3
```
"""
function accumulate(op, A, axis::Integer)
out = similar(A, rcum_promote_type(op, eltype(A)))
accumulate!(op, out, A, axis)
end

accumulate(op, x::AbstractVector) = accumulate(op, x, 1)

"""
accumulate(op, v0, A)
accumulate(op, x::AbstractVector)

Like `accumulate`, but using a starting element `v0`. The first entry of the result will be
`op(v0, first(A))`.
Cumulative operation `op` on a vector. See also
[`accumulate!`](@ref) to use a preallocated output array, both for performance and
to control the precision of the output (e.g. to avoid overflow). For common operations
there are specialized variants of `accumulate`, see:
[`cumsum`](@ref), [`cumprod`](@ref)

# Examples
```jldoctest
julia> accumulate(+, 100, [1,2,3])
julia> accumulate(+, [1,2,3])
3-element Array{Int64,1}:
101
103
106
1
3
6

julia> accumulate(min, 0, [1,2,-1])
julia> accumulate(*, [1,2,3])
3-element Array{Int64,1}:
0
0
-1
1
2
6
```
"""
function accumulate(op, v0, A, axis::Integer)
T = rcum_promote_type(op, typeof(v0), eltype(A))
out = similar(A, T)
accumulate!(op, out, v0, A, 1)
end

accumulate(op, v0, x::AbstractVector) = accumulate(op, v0, x, 1)

function accumulate!(op::Op, B, A::AbstractVector, axis::Integer) where Op
isempty(A) && return B
v1 = first(A)
_accumulate1!(op, B, v1, A, axis)
end

function accumulate!(op, B, v0, A::AbstractVector, axis::Integer)
isempty(A) && return B
v1 = op(v0, first(A))
_accumulate1!(op, B, v1, A, axis)
end

accumulate!(op, y::AbstractVector, v0, x::AbstractVector) = accumulate!(op, y, v0, x, 1)

function _accumulate1!(op, B, v1, A::AbstractVector, axis::Integer)
axis > 0 || throw(ArgumentError("axis must be a positive integer"))
inds = linearindices(A)
inds == linearindices(B) || throw(DimensionMismatch("linearindices of A and B don't match"))
axis > 1 && return copy!(B, A)
i1 = inds[1]
cur_val = v1
B[i1] = cur_val
@inbounds for i in inds[2:end]
cur_val = op(cur_val, A[i])
B[i] = cur_val
end
return B
end
accumulate(op, x::AbstractVector) = accumulate(op, x, 1)

"""
accumulate!(op, B, A, dim)
Expand Down Expand Up @@ -888,7 +906,17 @@ function accumulate!(op, B, A, axis::Integer)
return B
end

accumulate!(op, y::AbstractVector, x::AbstractVector) = accumulate!(op, y, x, 1)
"""
accumulate!(op, y, x::AbstractVector)

Cumulative operation `op` on a vector `x`, storing the result in `y`.
See also [`accumulate`](@ref).
"""
function accumulate!(op::Op, y, x::AbstractVector) where Op
isempty(x) && return y
v1 = first(x)
_accumulate1!(op, y, v1, x, 1)
end

@noinline function _accumulate!(op, B, A, R1, ind, R2)
# Copy the initial element in each 1d vector along dimension `axis`
Expand All @@ -903,6 +931,54 @@ accumulate!(op, y::AbstractVector, x::AbstractVector) = accumulate!(op, y, x, 1)
B
end

"""
accumulate(op, v0, x::AbstractVector)

Like `accumulate`, but using a starting element `v0`. The first entry of the result will be
`op(v0, first(A))`.

# Examples
```jldoctest
julia> accumulate(+, 100, [1,2,3])
3-element Array{Int64,1}:
101
103
106

julia> accumulate(min, 0, [1,2,-1])
3-element Array{Int64,1}:
0
0
-1
```
"""
function accumulate(op, v0, x::AbstractVector)
T = rcum_promote_type(op, typeof(v0), eltype(x))
out = similar(x, T)
accumulate!(op, out, v0, x)
end

function accumulate!(op, y, v0, x::AbstractVector)
isempty(x) && return y
v1 = op(v0, first(x))
_accumulate1!(op, y, v1, x, 1)
end

function _accumulate1!(op, B, v1, A::AbstractVector, axis::Integer)
axis > 0 || throw(ArgumentError("axis must be a positive integer"))
inds = linearindices(A)
inds == linearindices(B) || throw(DimensionMismatch("linearindices of A and B don't match"))
axis > 1 && return copy!(B, A)
i1 = inds[1]
cur_val = v1
B[i1] = cur_val
@inbounds for i in inds[2:end]
cur_val = op(cur_val, A[i])
B[i] = cur_val
end
return B
end

### from abstractarray.jl

"""
Expand Down