From df79cc64a8f7bcb485a366f967c5db51ec340484 Mon Sep 17 00:00:00 2001 From: Alexander Plavin Date: Thu, 9 Nov 2023 15:54:49 -0500 Subject: [PATCH] also findall --- src/findall.jl | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/src/findall.jl b/src/findall.jl index 6683e75..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)