From 2b24bd7a8d4b8e3a7aea5119c8fbab0298695cb8 Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Fri, 22 May 2020 14:45:44 +0200 Subject: [PATCH 1/2] Fix minimum and maximum in the presence of missing values --- base/reduce.jl | 9 +++++---- test/reduce.jl | 12 ++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/base/reduce.jl b/base/reduce.jl index 414bac5099f78..20cee1148b27d 100644 --- a/base/reduce.jl +++ b/base/reduce.jl @@ -573,10 +573,11 @@ function mapreduce_impl(f, op::Union{typeof(max), typeof(min)}, simdstop = start + chunk_len - 4 while simdstop <= last - 3 # short circuit in case of NaN - v1 == v1 || return v1 - v2 == v2 || return v2 - v3 == v3 || return v3 - v4 == v4 || return v4 + # === true is there to ignore missing + (v1 == v1) === true || return v1 + (v2 == v2) === true || return v2 + (v3 == v3) === true || return v3 + (v4 == v4) === true || return v4 @inbounds for i in start:4:simdstop v1 = _fast(op, v1, f(A[i+0])) v2 = _fast(op, v2, f(A[i+1])) diff --git a/test/reduce.jl b/test/reduce.jl index 69b8b1911e7ea..ee0566b1e4c7c 100644 --- a/test/reduce.jl +++ b/test/reduce.jl @@ -338,6 +338,18 @@ A = circshift(reshape(1:24,2,3,4), (0,1,1)) @test size(extrema(A,dims=(1,2,3))) == size(maximum(A,dims=(1,2,3))) @test extrema(x->div(x, 2), A, dims=(2,3)) == reshape([(0,11),(1,12)],2,1,1) +@testset "maximum/minimum/extrema with missing values" begin + for x in (Vector{Union{Int,Missing}}(missing, 10), + Vector{Union{Int,Missing}}(missing, 257)) + @test maximum(x) === minimum(x) === missing + @test extrema(x) === (missing, missing) + fill!(x, 1) + x[1] = missing + @test maximum(x) === minimum(x) === missing + @test extrema(x) === (missing, missing) + end +end + # any & all @test @inferred any([]) == false From 37251935a5542d1df0398cc8547088f4bb2b2fba Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Sat, 30 May 2020 12:27:09 +0200 Subject: [PATCH 2/2] Fix comment --- base/reduce.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/base/reduce.jl b/base/reduce.jl index 20cee1148b27d..1f67989f5c871 100644 --- a/base/reduce.jl +++ b/base/reduce.jl @@ -572,8 +572,7 @@ function mapreduce_impl(f, op::Union{typeof(max), typeof(min)}, start = first + 1 simdstop = start + chunk_len - 4 while simdstop <= last - 3 - # short circuit in case of NaN - # === true is there to ignore missing + # short circuit in case of NaN or missing (v1 == v1) === true || return v1 (v2 == v2) === true || return v2 (v3 == v3) === true || return v3