Skip to content

Commit 744ead4

Browse files
jw3126ViralBShah
authored andcommitted
fix maximum on generic orders (#30441)
Close #30436 Address the non-numeric values case that is visible only with long arrays reported in #30320
1 parent 99efc91 commit 744ead4

File tree

3 files changed

+31
-7
lines changed

3 files changed

+31
-7
lines changed

base/reduce.jl

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -452,18 +452,22 @@ julia> prod(1:20)
452452
prod(a) = mapreduce(identity, mul_prod, a)
453453

454454
## maximum & minimum
455-
function _fast(::typeof(max),x,y)
455+
_fast(::typeof(min),x,y) = min(x,y)
456+
_fast(::typeof(max),x,y) = max(x,y)
457+
function _fast(::typeof(max), x::AbstractFloat, y::AbstractFloat)
456458
ifelse(isnan(x),
457459
x,
458460
ifelse(x > y, x, y))
459461
end
460462

461-
function _fast(::typeof(min),x,y)
463+
function _fast(::typeof(min),x::AbstractFloat, y::AbstractFloat)
462464
ifelse(isnan(x),
463465
x,
464466
ifelse(x < y, x, y))
465467
end
466468

469+
_isnan(x) = false
470+
_isnan(x::Real) = isnan(x)
467471
isbadzero(::typeof(max), x::AbstractFloat) = (x == zero(x)) & signbit(x)
468472
isbadzero(::typeof(min), x::AbstractFloat) = (x == zero(x)) & !signbit(x)
469473
isbadzero(op, x) = false
@@ -479,10 +483,10 @@ function mapreduce_impl(f, op::Union{typeof(max), typeof(min)},
479483
start = first
480484
stop = start + chunk_len - 4
481485
while stop <= last
482-
isnan(v1) && return v1
483-
isnan(v2) && return v2
484-
isnan(v3) && return v3
485-
isnan(v4) && return v4
486+
_isnan(v1) && return v1
487+
_isnan(v2) && return v2
488+
_isnan(v3) && return v3
489+
_isnan(v4) && return v4
486490
@inbounds for i in start:4:stop
487491
v1 = _fast(op, v1, f(A[i+1]))
488492
v2 = _fast(op, v2, f(A[i+2]))

stdlib/Test/src/Test.jl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export @testset
2121
# Legacy approximate testing functions, yet to be included
2222
export @inferred
2323
export detect_ambiguities, detect_unbound_args
24-
export GenericString, GenericSet, GenericDict, GenericArray
24+
export GenericString, GenericSet, GenericDict, GenericArray, GenericOrder
2525
export TestSetException
2626

2727
import Distributed: myid
@@ -1546,6 +1546,15 @@ end
15461546
GenericArray{T}(args...) where {T} = GenericArray(Array{T}(args...))
15471547
GenericArray{T,N}(args...) where {T,N} = GenericArray(Array{T,N}(args...))
15481548

1549+
"""
1550+
The `GenericOrder` can be used to test APIs for their support
1551+
of generic ordered types.
1552+
"""
1553+
struct GenericOrder{T}
1554+
val::T
1555+
end
1556+
Base.isless(x::GenericOrder, y::GenericOrder) = isless(x.val,y.val)
1557+
15491558
Base.keys(a::GenericArray) = keys(a.a)
15501559
Base.axes(a::GenericArray) = axes(a.a)
15511560
Base.length(a::GenericArray) = length(a.a)

test/reduce.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,17 @@ end
233233
end
234234
end
235235

236+
@testset "maximum works on generic order #30320" begin
237+
for n in [1:20;1500]
238+
arr = randn(n)
239+
@test GenericOrder(maximum(arr)) === maximum(map(GenericOrder, arr))
240+
@test GenericOrder(minimum(arr)) === minimum(map(GenericOrder, arr))
241+
f = x -> x
242+
@test GenericOrder(maximum(f,arr)) === maximum(f,map(GenericOrder, arr))
243+
@test GenericOrder(minimum(f,arr)) === minimum(f,map(GenericOrder, arr))
244+
end
245+
end
246+
236247
@test isnan(maximum([NaN]))
237248
@test isnan(minimum([NaN]))
238249
@test isequal(extrema([NaN]), (NaN, NaN))

0 commit comments

Comments
 (0)