From d9ce18b47aa8d2f80a85ed0e8c0f376375cea203 Mon Sep 17 00:00:00 2001 From: Alexander Plavin Date: Thu, 9 Nov 2023 15:57:19 -0500 Subject: [PATCH 1/4] use old searchsorted() implementation until julia 1.11 --- src/findall.jl | 75 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 12 deletions(-) diff --git a/src/findall.jl b/src/findall.jl index bd41604..d89f4fe 100644 --- a/src/findall.jl +++ b/src/findall.jl @@ -34,8 +34,50 @@ julia> findall(in(Interval{:open,:closed}(1,6)), y) # (1,6], does not include 1 5:14 ``` """ -Base.findall(interval_d::Base.Fix2{typeof(in), <:Interval}, x::AbstractRange) = - searchsorted_interval(x, interval_d.x; rev=step(x) < zero(step(x))) +if VERSION < v"1.11-" + function Base.findall(interval_d::Base.Fix2{typeof(in),Interval{L,R,T}}, x::AbstractRange) where {L,R,T} + isempty(x) && return 1:0 + + interval = interval_d.x + il, ir = firstindex(x), lastindex(x) + δx = step(x) + a,b = if δx < zero(δx) + rev = findall(in(interval), reverse(x)) + isempty(rev) && return rev + + a = (il+ir)-last(rev) + b = (il+ir)-first(rev) + + a,b + else + lx, rx = first(x), last(x) + l = max(leftendpoint(interval), lx - oneunit(δx)) + r = min(rightendpoint(interval), rx + oneunit(δx)) + + (l > rx || r < lx) && return 1:0 + + a = il + max(0, round(Int, cld(l-lx, δx))) + a += (a ≤ ir && (x[a] == l && L == :open || x[a] < l)) + + b = min(ir, round(Int, cld(r-lx, δx)) + il) + b -= (b ≥ il && (x[b] == r && R == :open || x[b] > r)) + + a,b + end + # Reversing a range could change sign of values close to zero (cf + # sign of the smallest element in x and reverse(x), where x = + # range(BigFloat(-0.5),stop=BigFloat(1.0),length=10)), or more + # generally push elements in or out of the interval (as can cld), + # so we need to check once again. + a += +(a < ir && x[a] ∉ interval) - (il < a && x[a-1] ∈ interval) + b += -(il < b && x[b] ∉ interval) + (b < ir && x[b+1] ∈ interval) + + a:b + end +else + Base.findall(interval_d::Base.Fix2{typeof(in), <:Interval}, x::AbstractRange) = + searchsorted_interval(x, interval_d.x; rev=step(x) < zero(step(x))) +end # We overload Base._findin to avoid an ambiguity that arises with # Base.findall(interval_d::Base.Fix2{typeof(in),Interval{L,R,T}}, x::AbstractArray) @@ -65,15 +107,24 @@ julia> searchsorted_interval(Float64[], 1..3) 1:0 ``` """ -function searchsorted_interval(X, i::Interval{L, R}; rev=false) where {L, R} - if rev === true - _searchsorted_begin(X, rightendpoint(i), Val(R); rev):_searchsorted_end(X, leftendpoint(i), Val(L); rev) - else - _searchsorted_begin(X, leftendpoint(i), Val(L); rev):_searchsorted_end(X, rightendpoint(i), Val(R); rev) +function searchsorted_interval end + +if VERSION < v"1.11-" + searchsorted_interval(X, i::Interval{:closed, :closed}) = searchsortedfirst(X, leftendpoint(i)) :searchsortedlast(X, rightendpoint(i)) + searchsorted_interval(X, i::Interval{:closed, :open}) = searchsortedfirst(X, leftendpoint(i)) :(searchsortedfirst(X, rightendpoint(i)) - 1) + searchsorted_interval(X, i::Interval{ :open, :closed}) = (searchsortedlast(X, leftendpoint(i)) + 1):searchsortedlast(X, rightendpoint(i)) + searchsorted_interval(X, i::Interval{ :open, :open}) = (searchsortedlast(X, leftendpoint(i)) + 1):(searchsortedfirst(X, rightendpoint(i)) - 1) +else + function searchsorted_interval(X, i::Interval{L, R}; rev=false) where {L, R} + if rev === true + _searchsorted_begin(X, rightendpoint(i), Val(R); rev):_searchsorted_end(X, leftendpoint(i), Val(L); rev) + else + _searchsorted_begin(X, leftendpoint(i), Val(L); rev):_searchsorted_end(X, rightendpoint(i), Val(R); rev) + end end -end -_searchsorted_begin(X, x, ::Val{:closed}; rev) = searchsortedfirst(X, x; rev, lt=<) -_searchsorted_begin(X, x, ::Val{:open}; rev) = searchsortedlast(X, x; rev, lt=<) + 1 - _searchsorted_end(X, x, ::Val{:closed}; rev) = searchsortedlast(X, x; rev, lt=<) - _searchsorted_end(X, x, ::Val{:open}; rev) = searchsortedfirst(X, x; rev, lt=<) - 1 + _searchsorted_begin(X, x, ::Val{:closed}; rev) = searchsortedfirst(X, x; rev, lt=<) + _searchsorted_begin(X, x, ::Val{:open}; rev) = searchsortedlast(X, x; rev, lt=<) + 1 + _searchsorted_end(X, x, ::Val{:closed}; rev) = searchsortedlast(X, x; rev, lt=<) + _searchsorted_end(X, x, ::Val{:open}; rev) = searchsortedfirst(X, x; rev, lt=<) - 1 +end From 152636d593b5631209b39fe27b5efe65b4f2329a Mon Sep 17 00:00:00 2001 From: Alexander Plavin Date: Thu, 9 Nov 2023 17:04:49 -0500 Subject: [PATCH 2/4] fix docstring --- src/findall.jl | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/findall.jl b/src/findall.jl index d89f4fe..ec8179e 100644 --- a/src/findall.jl +++ b/src/findall.jl @@ -34,8 +34,8 @@ julia> findall(in(Interval{:open,:closed}(1,6)), y) # (1,6], does not include 1 5:14 ``` """ -if VERSION < v"1.11-" - function Base.findall(interval_d::Base.Fix2{typeof(in),Interval{L,R,T}}, x::AbstractRange) where {L,R,T} +function Base.findall(interval_d::Base.Fix2{typeof(in),Interval{L,R,T}}, x::AbstractRange) where {L,R,T} + @static if VERSION < v"1.11-" isempty(x) && return 1:0 interval = interval_d.x @@ -73,10 +73,9 @@ if VERSION < v"1.11-" b += -(il < b && x[b] ∉ interval) + (b < ir && x[b+1] ∈ interval) a:b - end -else - Base.findall(interval_d::Base.Fix2{typeof(in), <:Interval}, x::AbstractRange) = + else searchsorted_interval(x, interval_d.x; rev=step(x) < zero(step(x))) + end end # We overload Base._findin to avoid an ambiguity that arises with From d3c3c30382a123f6e03ba8d74ba716ebc8bf79ef Mon Sep 17 00:00:00 2001 From: Alexander Plavin Date: Sat, 11 Nov 2023 11:58:56 -0500 Subject: [PATCH 3/4] fix findall on zero-step ranges --- src/findall.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/findall.jl b/src/findall.jl index ec8179e..72bfb91 100644 --- a/src/findall.jl +++ b/src/findall.jl @@ -41,6 +41,10 @@ function Base.findall(interval_d::Base.Fix2{typeof(in),Interval{L,R,T}}, x::Abst interval = interval_d.x il, ir = firstindex(x), lastindex(x) δx = step(x) + if iszero(δx) + val = only(unique(x)) + return val ∈ interval ? (firstindex(x):lastindex(x)) : (1:0) + end a,b = if δx < zero(δx) rev = findall(in(interval), reverse(x)) isempty(rev) && return rev From 8401b595b36071e181a2f23ea0b260aa97ae035e Mon Sep 17 00:00:00 2001 From: Alexander Plavin Date: Sat, 11 Nov 2023 12:02:04 -0500 Subject: [PATCH 4/4] bump --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 05650dc..63b8065 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "IntervalSets" uuid = "8197267c-284f-5f27-9208-e0e47529a953" -version = "0.7.8" +version = "0.7.9" [deps] Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"