-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
cumsum fixes (fixes #18363 and #18336) #18364
Changes from all commits
a0f30e6
4263ffb
4fca7c1
deef68d
1980212
6821c02
f3b745f
e4a0988
fc6643e
9ed4912
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -446,8 +446,14 @@ ctranspose{T<:Real}(A::AbstractVecOrMat{T}) = transpose(A) | |
transpose(x::AbstractVector) = [ transpose(v) for i=of_indices(x, OneTo(1)), v in x ] | ||
ctranspose{T}(x::AbstractVector{T}) = T[ ctranspose(v) for i=of_indices(x, OneTo(1)), v in x ] | ||
|
||
_cumsum_type{T<:Number}(v::AbstractArray{T}) = typeof(+zero(T)) | ||
_cumsum_type(v) = typeof(v[1]+v[1]) | ||
# 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{T<:Number}(op, ::Type{T}) = promote_op(op, T) | ||
rcum_promote_type{T}(op, ::Type{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{T,N}(op, ::Type{Array{T,N}}) = Array{rcum_promote_type(op,T), N} | ||
|
||
for (f, f!, fp, op) = ((:cumsum, :cumsum!, :cumsum_pairwise!, :+), | ||
(:cumprod, :cumprod!, :cumprod_pairwise!, :*) ) | ||
|
@@ -470,14 +476,18 @@ for (f, f!, fp, op) = ((:cumsum, :cumsum!, :cumsum_pairwise!, :+), | |
end | ||
|
||
@eval function ($f!)(result::AbstractVector, v::AbstractVector) | ||
n = length(v) | ||
li = linearindices(v) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Best would be to have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I see that the Okay, changed it to (Note also that this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. http://docs.julialang.org/en/latest/devdocs/offset-arrays/#background Though if this isn't to be backported, then perhaps you could just stick with the original, since the situation with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the definition/documentation for |
||
li != linearindices(result) && throw(DimensionMismatch("input and output array sizes and indices must match")) | ||
n = length(li) | ||
if n == 0; return result; end | ||
($fp)(v, result, $(op==:+ ? :(zero(first(v))) : :(one(first(v)))), first(indices(v,1)), n) | ||
i1 = first(li) | ||
@inbounds result[i1] = v1 = v[i1] | ||
n == 1 && return result | ||
($fp)(v, result, v1, i1+1, n-1) | ||
return result | ||
end | ||
|
||
@eval function ($f)(v::AbstractVector) | ||
c = $(op===:+ ? (:(similar(v,_cumsum_type(v)))) : (:(similar(v)))) | ||
return ($f!)(c, v) | ||
@eval function ($f){T}(v::AbstractVector{T}) | ||
return ($f!)(similar(v, rcum_promote_type($op, T)), v) | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can do
without specializing for
<:Number
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
promote_eltype_op
gives the wrong answers for non-Number
arguments too. e.g. it givesBase.promote_eltype_op(+, Range{Int}) --> Int
when I wantRange{Int}
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's why I left the second definition. Maybe some day, if we get triangular dispatch or something like it, that will be easier.
EDIT: I see that for
Range
that won't work unless we also have something like triangular dispatch.