Skip to content

Commit

Permalink
rcum_convert
Browse files Browse the repository at this point in the history
  • Loading branch information
jw3126 committed Jan 14, 2018
1 parent bec650a commit b48095c
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 5 deletions.
11 changes: 6 additions & 5 deletions base/multidimensional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -734,13 +734,14 @@ end
# see discussion in #18364 ... we try not to widen type of the resulting array
# from cumsum or cumprod, but in some cases (+, Bool) we may not have a choice.
rcum_promote_type(op, ::Type{T}, ::Type{S}) where {T,S} = promote_op(op, T, S)
rcum_promote_type(op, ::Type{T}) where {T<:Number} = rcum_promote_type(op, T,T)
rcum_promote_type(op, ::Type{T}) where {T} = T
rcum_promote_type(op, ::Type{T}) where {T} = rcum_promote_type(op, T,T)

# handle sums of Vector{Bool} and similar. it would be nice to handle
# any AbstractArray here, but it's not clear how that would be possible
rcum_promote_type(op, ::Type{Array{T,N}}) where {T,N} = Array{rcum_promote_type(op,T), N}

rcum_convert(::Type{T}, x) where {T} = convert(T,x)
rcum_convert(::Type{T}, c::Char) where {T <: AbstractString} = T(string(c))
# accumulate_pairwise slightly slower then accumulate, but more numerically
# stable in certain situations (e.g. sums).
# it does double the number of operations compared to accumulate,
Expand Down Expand Up @@ -1021,7 +1022,7 @@ function accumulate!(op, B, A, dim::Integer)
# register usage and will be slightly faster
ind1 = inds_t[1]
@inbounds for I in CartesianIndices(tail(inds_t))
tmp = convert(eltype(B), A[first(ind1), I])
tmp = rcum_convert(eltype(B), A[first(ind1), I])
B[first(ind1), I] = tmp
for i_1 = first(ind1)+1:last(ind1)
tmp = op(tmp, A[i_1, I])
Expand Down Expand Up @@ -1071,7 +1072,7 @@ end
# Copy the initial element in each 1d vector along dimension `dim`
ii = first(ind)
@inbounds for J in R2, I in R1
B[I, ii, J] = A[I, ii, J]
B[I, ii, J] = rcum_convert(eltype(B), A[I, ii, J])
end
# Accumulate
@inbounds for J in R2, i in first(ind)+1:last(ind), I in R1
Expand Down Expand Up @@ -1119,7 +1120,7 @@ function _accumulate1!(op, B, v1, A::AbstractVector, dim::Integer)
inds == linearindices(B) || throw(DimensionMismatch("linearindices of A and B don't match"))
dim > 1 && return copyto!(B, A)
i1 = inds[1]
cur_val = v1
cur_val = rcum_convert(eltype(B), v1)
B[i1] = cur_val
@inbounds for i in inds[2:end]
cur_val = op(cur_val, A[i])
Expand Down
4 changes: 4 additions & 0 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2179,6 +2179,10 @@ end

#25506
@test accumulate((acc, x) -> acc+x[1], 0, [(1,2), (3,4), (5,6)]) == [1, 4, 9]
@test accumulate(*, ['a', 'b']) == ["a", "ab"]
@inferred accumulate(*, String[])
@test accumulate(*, ['a' 'b'; 'c' 'd'], 1) == ["a" "b"; "ac" "bd"]
@test accumulate(*, ['a' 'b'; 'c' 'd'], 2) == ["a" "ab"; "c" "cd"]
end

struct F21666{T <: Base.TypeArithmetic}
Expand Down

0 comments on commit b48095c

Please sign in to comment.