-
-
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
Add cummax() and cummin()? #1649
Comments
I think we can have these but in general we ought to be able to do scans with arbitrary functions easily (we probably already can, actually, on phone atm). |
I agree. I think the right way to do this is to define an arbitrary scan function, like use it to define all of |
We can't currently do that without a performance hit. Once code gen specializes on function values, that limitation will go away and a lot of metapeogramming with eval can be replaced with straightforward higher-order functions. |
Good to know that you're hoping to change code gen to be more efficient for those kind of higher-order functions used function as function definitions. |
In the hopes of bumping this, I pushed e6bc5ad, which adds these functions and simple tests of their validity. If I've screwed something up, please let me know and I'll undo the changes. |
Looks ok to me. |
I was also looking for See https://discourse.julialang.org/t/cumulative-min-cumulative-max/25516/4 Now I did import Base: promote_op
# cumulative min
cummin!(B::AbstractArray{T}, A; dims::Integer) where {T} =
accumulate!(min, B, A, dims=dims)
function cummin(A::AbstractArray{T}; dims::Integer) where T
out = similar(A, promote_op(min, T, T))
cummin!(out, A, dims=dims)
end
cummin(x::AbstractVector) = cummin(x, dims=1)
# cumulative max
cummax!(B::AbstractArray{T}, A; dims::Integer) where {T} =
accumulate!(max, B, A, dims=dims)
function cummax(A::AbstractArray{T}; dims::Integer) where T
out = similar(A, promote_op(max, T, T))
cummax!(out, A, dims=dims)
end
cummax(x::AbstractVector) = cummax(x, dims=1) and test using Test
include("accumulate.jl")
@testset "cummin" begin
@testset "1D cummin!" begin
a = [10, 12, 14, 9, 10, 8, 16, 20]
cummin!(a, a, dims=1)
expected_a_cum = [10, 10, 10, 9, 9, 8, 8, 8]
@test a == expected_a_cum
end
@testset "1D cummin" begin
a = [10, 12, 14, 9, 10, 8, 16, 20]
a_cum = cummin(a)
expected_a_cum = [10, 10, 10, 9, 9, 8, 8, 8]
@test a_cum == expected_a_cum
end
end
@testset "cummax" begin
@testset "1D cummax!" begin
a = [10, 12, 14, 9, 10, 8, 16, 20]
cummax!(a, a, dims=1)
expected_a_cum = [10, 12, 14, 14, 14, 14, 16, 20]
@test a == expected_a_cum
end
@testset "1D cummax" begin
a = [10, 12, 14, 9, 10, 8, 16, 20]
a_cum = cummax(a)
expected_a_cum = [10, 12, 14, 14, 14, 14, 16, 20]
@test a_cum == expected_a_cum
end
end More testing and doc is probably required |
An other API idea (inspired by Python / Pandas) could be the use of "expanding" functions julia> a = [10, 12, 14, 9, 10, 8, 16, 20]
8-element Array{Int64,1}:
10
12
14
9
10
8
16
20
julia> cumsum(a)
8-element Array{Int64,1}:
10
22
36
45
55
63
79
99
julia> sum(expanding(a))
8-element Array{Int64,1}:
10
22
36
45
55
63
79
99
julia> cumprod(a)
8-element Array{Int64,1}:
10
120
1680
15120
151200
1209600
19353600
387072000
julia> prod(expanding(a))
8-element Array{Int64,1}:
10
120
1680
15120
151200
1209600
19353600
387072000
julia> cummin(a)
ERROR: UndefVarError: cummin not defined
Stacktrace:
[1] top-level scope at none:0
julia> min(expanding(a))
8-element Array{Int64,1}:
10
10
10
9
9
8
8
8
julia> max(expanding(a))
8-element Array{Int64,1}:
10
12
14
14
14
14
16
20 Same API idea could be applied for rolling functions JeffreySarnoff/RollingFunctions.jl#14 |
Here is possible implementation of this "expanding" functions... struct Expanding
data
end
expanding(data) = Expanding(data)
import Base: sum, prod, min, max
function sum(exp::Expanding)
accumulate(+, exp.data)
end
function prod(exp::Expanding)
accumulate(*, exp.data)
end
function min(exp::Expanding)
accumulate(min, exp.data)
end
function max(exp::Expanding)
accumulate(max, exp.data)
end and test using Test
include("expanding.jl")
@testset "expanding" begin
@testset "cumsum" begin
a = [10, 12, 14, 9, 10, 8, 16, 20]
@test sum(expanding(a)) == [10, 22, 36, 45, 55, 63, 79, 99]
end
@testset "cumprod" begin
a = [10, 12, 14, 9, 10, 8, 16, 20]
@test prod(expanding(a)) == [10, 120, 1680, 15120, 151200, 1209600, 19353600, 387072000]
end
@testset "cummin" begin
a = [10, 12, 14, 9, 10, 8, 16, 20]
@test min(expanding(a)) == [10, 10, 10, 9, 9, 8, 8, 8]
end
@testset "cummax" begin
a = [10, 12, 14, 9, 10, 8, 16, 20]
@test max(expanding(a)) == [10, 12, 14, 14, 14, 14, 16, 20]
end
end
|
Should we have
cummax()
andcummin()
functions to complement thecumsum()
andcumprod()
functions?The text was updated successfully, but these errors were encountered: