Skip to content

Commit

Permalink
Make max/min synonyms for scalarmax/scalarmin in reductions
Browse files Browse the repository at this point in the history
Fixes #16133
  • Loading branch information
timholy committed Apr 30, 2016
1 parent bbc8e60 commit 54e034a
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 15 deletions.
10 changes: 10 additions & 0 deletions base/reduce.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ r_promote(::typeof(scalarmax), x::WidenReduceResult) = x
r_promote(::typeof(scalarmin), x::WidenReduceResult) = x
r_promote(::typeof(scalarmax), x) = x
r_promote(::typeof(scalarmin), x) = x
r_promote(::typeof(max), x) = r_promote(scalarmax, x)
r_promote(::typeof(min), x) = r_promote(scalarmin, x)


## foldl && mapfoldl
Expand Down Expand Up @@ -126,6 +128,8 @@ mr_empty(::typeof(abs2), op::typeof(+), T) = r_promote(op, abs2(zero(T)::T))
mr_empty(::typeof(identity), op::typeof(*), T) = r_promote(op, one(T)::T)
mr_empty(::typeof(abs), op::typeof(scalarmax), T) = abs(zero(T)::T)
mr_empty(::typeof(abs2), op::typeof(scalarmax), T) = abs2(zero(T)::T)
mr_empty(::typeof(abs), op::typeof(max), T) = mr_empty(abs, scalarmax, T)
mr_empty(::typeof(abs2), op::typeof(max), T) = mr_empty(abs2, scalarmax, T)
mr_empty(f, op::typeof(&), T) = true
mr_empty(f, op::typeof(|), T) = false

Expand Down Expand Up @@ -277,6 +281,9 @@ prod(a) = mapreduce(identity, *, a)

## maximum & minimum

function mapreduce_impl(f, op::typeof(max), A::AbstractArray, first::Int, last::Int)
mapreduce_impl(f, scalarmax, A, first, last)
end
function mapreduce_impl(f, op::typeof(scalarmax), A::AbstractArray, first::Int, last::Int)
# locate the first non NaN number
v = f(A[first])
Expand All @@ -297,6 +304,9 @@ function mapreduce_impl(f, op::typeof(scalarmax), A::AbstractArray, first::Int,
v
end

function mapreduce_impl(f, op::typeof(min), A::AbstractArray, first::Int, last::Int)
mapreduce_impl(f, scalarmin, A, first, last)
end
function mapreduce_impl(f, op::typeof(scalarmin), A::AbstractArray, first::Int, last::Int)
# locate the first non NaN number
v = f(A[first])
Expand Down
28 changes: 13 additions & 15 deletions base/reducedim.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ end

## initialization

for (Op, initfun) in ((:(typeof(+)), :zero), (:(typeof(*)), :one), (:(typeof(scalarmax)), :typemin), (:(typeof(scalarmin)), :typemax))
for (Op, initfun) in ((:(typeof(+)), :zero), (:(typeof(*)), :one), (:(typeof(scalarmax)), :typemin), (:(typeof(scalarmin)), :typemax), (:(typeof(max)), :typemin), (:(typeof(min)), :typemax))
@eval initarray!{T}(a::AbstractArray{T}, ::$(Op), init::Bool) = (init && fill!(a, $(initfun)(T)); a)
end

Expand All @@ -94,32 +94,30 @@ reducedim_initarray0{T}(A::AbstractArray, region, v0::T) = reducedim_initarray0(
#
promote_union(T::Union) = promote_type(T.types...)
promote_union(T) = T

function reducedim_init{S}(f, op::typeof(+), A::AbstractArray{S}, region)
T = promote_union(S)
if method_exists(zero, Tuple{Type{T}})
x = f(zero(T))
z = zero(x) + zero(x)
Tr = typeof(z) == typeof(x) && !isbits(T) ? T : typeof(z)
else
z = zero(sum(f, A))
Tr = typeof(z)
end
return reducedim_initarray(A, region, z, Tr)
_reducedim_init(f, op, zero, sum, A, region)
end

function reducedim_init{S}(f, op::typeof(*), A::AbstractArray{S}, region)
T = promote_union(S)
_reducedim_init(f, op, one, prod, A, region)
end
function _reducedim_init(f, op, fv, fop, A, region)
T = promote_union(eltype(A))
if method_exists(zero, Tuple{Type{T}})
x = f(zero(T))
z = one(x) * one(x)
z = op(fv(x), fv(x))
Tr = typeof(z) == typeof(x) && !isbits(T) ? T : typeof(z)
else
z = one(prod(f, A))
z = fv(fop(f, A))
Tr = typeof(z)
end
return reducedim_initarray(A, region, z, Tr)
end

reducedim_init{T}(f, op::typeof(max), A::AbstractArray{T}, region) = reducedim_init(f, scalarmax, A, region)
reducedim_init{T}(f, op::typeof(min), A::AbstractArray{T}, region) = reducedim_init(f, scalarmin, A, region)
reducedim_init{T}(f::Union{typeof(abs),typeof(abs2)}, op::typeof(max), A::AbstractArray{T}, region) = reducedim_init(f, scalarmax, A, region)

reducedim_init{T}(f, op::typeof(scalarmax), A::AbstractArray{T}, region) = reducedim_initarray0(A, region, typemin(f(zero(T))))
reducedim_init{T}(f, op::typeof(scalarmin), A::AbstractArray{T}, region) = reducedim_initarray0(A, region, typemax(f(zero(T))))
reducedim_init{T}(f::Union{typeof(abs),typeof(abs2)}, op::typeof(scalarmax), A::AbstractArray{T}, region) =
Expand Down
4 changes: 4 additions & 0 deletions test/reducedim.jl
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ A = reshape(1:6, 3, 2)
@test typeof(@inferred(Base.prod(abs, [1.0+1.0im], 1))) == Vector{Float64}
@test typeof(@inferred(Base.prod(abs2, [1.0+1.0im], 1))) == Vector{Float64}

# min/max
@test reducedim(max, A, 1) == [3 6]
@test reducedim(min, A, 2) == reshape([1,2,3], 3, 1)

# Heterogeneously typed arrays
@test sum(Union{Float32, Float64}[1.0], 1) == [1.0]
@test prod(Union{Float32, Float64}[1.0], 1) == [1.0]
Expand Down

0 comments on commit 54e034a

Please sign in to comment.