Skip to content

Commit

Permalink
add more defaults for reductions over empty arrays (JuliaLang#29919)
Browse files Browse the repository at this point in the history
From discussion in JuliaLang#28535
  • Loading branch information
simonbyrne committed Nov 2, 2023
1 parent dabb93a commit 09617ac
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 2 deletions.
9 changes: 7 additions & 2 deletions base/reduce.jl
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,9 @@ reduce_empty(::typeof(*), ::Type{<:AbstractChar}) = ""
reduce_empty(::typeof(&), ::Type{Bool}) = true
reduce_empty(::typeof(|), ::Type{Bool}) = false

reduce_empty(::typeof(max), T) = typemin(T)
reduce_empty(::typeof(min), T) = typemax(T)

reduce_empty(::typeof(add_sum), ::Type{Union{}}) = _empty_reduce_error(add_sum, Union{})
reduce_empty(::typeof(add_sum), ::Type{T}) where {T} = reduce_empty(+, T)
reduce_empty(::typeof(add_sum), ::Type{T}) where {T<:SmallSigned} = zero(Int)
Expand All @@ -373,8 +376,10 @@ mapreduce_empty(::typeof(identity), op, T) = reduce_empty(op, T)
mapreduce_empty(::typeof(abs), op, T) = abs(reduce_empty(op, T))
mapreduce_empty(::typeof(abs2), op, T) = abs2(reduce_empty(op, T))

mapreduce_empty(f::typeof(abs), ::typeof(max), T) = abs(zero(T))
mapreduce_empty(f::typeof(abs2), ::typeof(max), T) = abs2(zero(T))
mapreduce_empty(::typeof(abs), ::typeof(max), T) = abs(zero(T))
mapreduce_empty(::typeof(abs), ::typeof(min), T) = typemax(abs(zero(T)))
mapreduce_empty(::typeof(abs2), ::typeof(max), T) = abs2(zero(T))
mapreduce_empty(::typeof(abs2), ::typeof(min), T) = typemax(abs2(zero(T)))

# For backward compatibility:
mapreduce_empty_iter(f, op, itr, ItrEltype) =
Expand Down
19 changes: 19 additions & 0 deletions test/reduce.jl
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ end
@test mapreduce(abs2, *, Float64[]) === 1.0
@test mapreduce(abs2, max, Float64[]) === 0.0
@test mapreduce(abs, max, Float64[]) === 0.0
@test mapreduce(abs2, min, Float64[]) === Inf
@test mapreduce(abs, min, Float64[]) === Inf
@test_throws ArgumentError mapreduce(abs2, &, Float64[])
@test_throws ArgumentError mapreduce(abs2, |, Float64[])
@test_throws ["reducing over an empty collection is not allowed",
"consider supplying `init`"] mapreduce(abs2, &, Float64[])
@test_throws str -> !occursin("Closest candidates are", str) mapreduce(abs2, &, Float64[])
Expand Down Expand Up @@ -260,6 +264,21 @@ prod2(itr) = invoke(prod, Tuple{Any}, itr)
@test minimum(sin, []; init=1) == 1
@test extrema(sin, []; init=(1, -1)) == (1, -1)

@test maximum(Float64[]) === -Inf
@test minimum(Float64[]) === +Inf

@test maximum(Float32[]) === -Inf32
@test minimum(Float32[]) === +Inf32

@test maximum(abs, Int[]) === 0
@test_throws ArgumentError minimum(abs, Int[])

@test maximum(abs, Float64[]) === 0.0
@test minimum(abs, Float64[]) === +Inf

@test maximum(abs, Float32[]) === 0.0f0
@test minimum(abs, Float32[]) === +Inf32

@test maximum(5) == 5
@test minimum(5) == 5
@test extrema(5) == (5, 5)
Expand Down

0 comments on commit 09617ac

Please sign in to comment.