From 359e4b5418b8aacbe5fbfc394231d466733c8a6a Mon Sep 17 00:00:00 2001 From: Vincent Yu Date: Wed, 15 Jun 2022 04:29:57 +0000 Subject: [PATCH 1/7] Restrict `middle(::AbstractRange)` eltype and improve performance --- src/Statistics.jl | 23 ++++++++--------------- test/runtests.jl | 5 +++++ 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/Statistics.jl b/src/Statistics.jl index b4771bed..de11815c 100644 --- a/src/Statistics.jl +++ b/src/Statistics.jl @@ -764,21 +764,6 @@ equivalent in both value and type to computing their mean (`(x + y) / 2`). """ middle(x::Number, y::Number) = x/2 + y/2 -""" - middle(range) - -Compute the middle of a range, which consists of computing the mean of its extrema. -Since a range is sorted, the mean is performed with the first and last element. - -```jldoctest -julia> using Statistics - -julia> middle(1:10) -5.5 -``` -""" -middle(a::AbstractRange) = middle(a[1], a[end]) - """ middle(a) @@ -788,6 +773,9 @@ extrema and then computing their mean. ```jldoctest julia> using Statistics +julia> middle(1:10) +5.5 + julia> a = [1,2,3.6,10.9] 4-element Vector{Float64}: 1.0 @@ -801,6 +789,11 @@ julia> middle(a) """ middle(a::AbstractArray) = ((v1, v2) = extrema(a); middle(v1, v2)) +function middle(a::AbstractRange{<:Real}) + isempty(a) && throw(ArgumentError("middle of an empty range is undefined.")) + return mean(a) +end + """ median!(v) diff --git a/test/runtests.jl b/test/runtests.jl index e4d4ba81..3a066f1e 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -21,6 +21,11 @@ Random.seed!(123) for T in [Bool,Int8,Int16,Int32,Int64,Int128,UInt8,UInt16,UInt32,UInt64,UInt128,Float16,Float32,Float64] @test middle(one(T)) === middle(one(T), one(T)) end + + @test_throws Exception middle(Int[]) + @test_throws Exception middle(1:0) + @test_throws MethodError middle([1.0im, 2.0im]) + @test_throws MethodError middle(LinRange(1.0im, 2.0im, 2)) end @testset "median" begin From da564eb2b7bf68acb466f6fc4118314bf7a4a51d Mon Sep 17 00:00:00 2001 From: Vincent Yu Date: Thu, 16 Jun 2022 02:10:30 +0000 Subject: [PATCH 2/7] Revert eltype restriction --- src/Statistics.jl | 2 +- test/runtests.jl | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Statistics.jl b/src/Statistics.jl index de11815c..c96e93f1 100644 --- a/src/Statistics.jl +++ b/src/Statistics.jl @@ -789,7 +789,7 @@ julia> middle(a) """ middle(a::AbstractArray) = ((v1, v2) = extrema(a); middle(v1, v2)) -function middle(a::AbstractRange{<:Real}) +function middle(a::AbstractRange) isempty(a) && throw(ArgumentError("middle of an empty range is undefined.")) return mean(a) end diff --git a/test/runtests.jl b/test/runtests.jl index 3a066f1e..0bc39f52 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -24,8 +24,6 @@ Random.seed!(123) @test_throws Exception middle(Int[]) @test_throws Exception middle(1:0) - @test_throws MethodError middle([1.0im, 2.0im]) - @test_throws MethodError middle(LinRange(1.0im, 2.0im, 2)) end @testset "median" begin @@ -963,4 +961,4 @@ end @test isequal(cor(mx, Int[]), fill(NaN, 2, 1)) @test isequal(cov(Int[], my), fill(-0.0, 1, 3)) @test isequal(cor(Int[], my), fill(NaN, 1, 3)) -end \ No newline at end of file +end From 9e63e4751b19b000358044a6a874301de361cb72 Mon Sep 17 00:00:00 2001 From: Vincent Yu Date: Thu, 16 Jun 2022 14:23:53 +0000 Subject: [PATCH 3/7] Apply suggestions from code review Co-authored-by: Milan Bouchet-Valat --- src/Statistics.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Statistics.jl b/src/Statistics.jl index c96e93f1..6872a224 100644 --- a/src/Statistics.jl +++ b/src/Statistics.jl @@ -765,7 +765,7 @@ equivalent in both value and type to computing their mean (`(x + y) / 2`). middle(x::Number, y::Number) = x/2 + y/2 """ - middle(a) + middle(a::AbstractArray) Compute the middle of an array `a`, which consists of finding its extrema and then computing their mean. @@ -791,7 +791,7 @@ middle(a::AbstractArray) = ((v1, v2) = extrema(a); middle(v1, v2)) function middle(a::AbstractRange) isempty(a) && throw(ArgumentError("middle of an empty range is undefined.")) - return mean(a) + return middle(first(r), last(r)) end """ From dd678a5a12f254edbee23a7544616168f53e90d2 Mon Sep 17 00:00:00 2001 From: Vincent Yu Date: Thu, 16 Jun 2022 14:36:32 +0000 Subject: [PATCH 4/7] Fix typo: `r` -> `a` --- src/Statistics.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Statistics.jl b/src/Statistics.jl index 6872a224..040ac972 100644 --- a/src/Statistics.jl +++ b/src/Statistics.jl @@ -791,7 +791,7 @@ middle(a::AbstractArray) = ((v1, v2) = extrema(a); middle(v1, v2)) function middle(a::AbstractRange) isempty(a) && throw(ArgumentError("middle of an empty range is undefined.")) - return middle(first(r), last(r)) + return middle(first(a), last(a)) end """ @@ -990,9 +990,9 @@ end require_one_based_indexing(v) n = length(v) - + @assert n > 0 # this case should never happen here - + m = alpha + p * (one(alpha) - alpha - beta) aleph = n*p + oftype(p, m) j = clamp(trunc(Int, aleph), 1, n-1) @@ -1005,7 +1005,7 @@ end a = v[j] b = v[j + 1] end - + if isfinite(a) && isfinite(b) return a + γ*(b-a) else From cf1d8074317199def68f9c991d93868ccf9f2f84 Mon Sep 17 00:00:00 2001 From: Vincent Yu Date: Thu, 16 Jun 2022 16:19:39 +0000 Subject: [PATCH 5/7] Update test/runtests.jl Co-authored-by: Milan Bouchet-Valat --- test/runtests.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 0bc39f52..8a5ced2e 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -22,8 +22,8 @@ Random.seed!(123) @test middle(one(T)) === middle(one(T), one(T)) end - @test_throws Exception middle(Int[]) - @test_throws Exception middle(1:0) + @test_throws MethodError middle(Int[]) + @test_throws ArgumentError middle(1:0) end @testset "median" begin From 7eeda9632ddfbc448e4b6f3373150a45b9c50944 Mon Sep 17 00:00:00 2001 From: Vincent Yu Date: Sun, 19 Jun 2022 03:28:03 +0000 Subject: [PATCH 6/7] Fix CI failure --- test/runtests.jl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 8a5ced2e..c1d4db39 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -22,7 +22,11 @@ Random.seed!(123) @test middle(one(T)) === middle(one(T), one(T)) end - @test_throws MethodError middle(Int[]) + if VERSION < v"1.8.0-DEV.1343" + @test_throws ArgumentError middle(Int[]) + else + @test_throws MethodError middle(Int[]) + end @test_throws ArgumentError middle(1:0) end @@ -550,16 +554,16 @@ end @test cor(tmp, tmp) <= 1.0 @test cor(tmp, tmp2) <= 1.0 end - + @test cor(Int[]) === 1.0 @test cor([im]) === 1.0 + 0.0im @test_throws MethodError cor([]) @test_throws MethodError cor(Any[1.0]) - + @test cor([1, missing]) === 1.0 @test ismissing(cor([missing])) @test_throws MethodError cor(Any[1.0, missing]) - + @test Statistics.corm([true], 1.0) === 1.0 @test_throws MethodError Statistics.corm(Any[0.0, 1.0], 0.5) @test Statistics.corzm([true]) === 1.0 From 17bc7a78886066e28d900382fd24a745090cbe46 Mon Sep 17 00:00:00 2001 From: Vincent Yu Date: Sun, 19 Jun 2022 03:35:01 +0000 Subject: [PATCH 7/7] Add `middle(0:typemax(Int))` test --- test/runtests.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/runtests.jl b/test/runtests.jl index c1d4db39..35242c27 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -28,6 +28,8 @@ Random.seed!(123) @test_throws MethodError middle(Int[]) end @test_throws ArgumentError middle(1:0) + + @test middle(0:typemax(Int)) === typemax(Int) / 2 end @testset "median" begin