@@ -34,45 +34,8 @@ julia> findall(in(Interval{:open,:closed}(1,6)), y) # (1,6], does not include 1
34345:14
3535```
3636"""
37- function Base. findall (interval_d:: Base.Fix2{typeof(in),Interval{L,R,T}} , x:: AbstractRange ) where {L,R,T}
38- isempty (x) && return 1 : 0
39-
40- interval = interval_d. x
41- il, ir = firstindex (x), lastindex (x)
42- δx = step (x)
43- a,b = if δx < zero (δx)
44- rev = findall (in (interval), reverse (x))
45- isempty (rev) && return rev
46-
47- a = (il+ ir)- last (rev)
48- b = (il+ ir)- first (rev)
49-
50- a,b
51- else
52- lx, rx = first (x), last (x)
53- l = max (leftendpoint (interval), lx - oneunit (δx))
54- r = min (rightendpoint (interval), rx + oneunit (δx))
55-
56- (l > rx || r < lx) && return 1 : 0
57-
58- a = il + max (0 , round (Int, cld (l- lx, δx)))
59- a += (a ≤ ir && (x[a] == l && L == :open || x[a] < l))
60-
61- b = min (ir, round (Int, cld (r- lx, δx)) + il)
62- b -= (b ≥ il && (x[b] == r && R == :open || x[b] > r))
63-
64- a,b
65- end
66- # Reversing a range could change sign of values close to zero (cf
67- # sign of the smallest element in x and reverse(x), where x =
68- # range(BigFloat(-0.5),stop=BigFloat(1.0),length=10)), or more
69- # generally push elements in or out of the interval (as can cld),
70- # so we need to check once again.
71- a += + (a < ir && x[a] ∉ interval) - (il < a && x[a- 1 ] ∈ interval)
72- b += - (il < b && x[b] ∉ interval) + (b < ir && x[b+ 1 ] ∈ interval)
73-
74- a: b
75- end
37+ Base. findall (interval_d:: Base.Fix2{typeof(in), <:Interval} , x:: AbstractRange ) =
38+ searchsorted_interval (x, interval_d. x; rev= step (x) < zero (step (x)))
7639
7740# We overload Base._findin to avoid an ambiguity that arises with
7841# Base.findall(interval_d::Base.Fix2{typeof(in),Interval{L,R,T}}, x::AbstractArray)
@@ -85,7 +48,7 @@ function Base._findin(a::Union{AbstractArray, Tuple}, b::Interval)
8548end
8649
8750"""
88- searchsorted_interval(a, i::Interval)
51+ searchsorted_interval(a, i::Interval; [rev=false] )
8952
9053Return the range of indices of `a` which is inside of the interval `i` (using binary search), assuming that
9154`a` is already sorted. Return an empty range located at the insertion point if a does not contain values in `i`.
@@ -102,9 +65,15 @@ julia> searchsorted_interval(Float64[], 1..3)
102651:0
10366```
10467"""
105- function searchsorted_interval end
68+ function searchsorted_interval (X, i:: Interval{L, R} ; rev= false ) where {L, R}
69+ if rev === true
70+ _searchsorted_begin (X, rightendpoint (i), Val (R); rev): _searchsorted_end (X, leftendpoint (i), Val (L); rev)
71+ else
72+ _searchsorted_begin (X, leftendpoint (i), Val (L); rev): _searchsorted_end (X, rightendpoint (i), Val (R); rev)
73+ end
74+ end
10675
107- searchsorted_interval (X, i :: Interval {:closed, :closed} ) = searchsortedfirst (X, leftendpoint (i)) :searchsortedlast (X, rightendpoint (i) )
108- searchsorted_interval (X, i :: Interval{:closed , :open} ) = searchsortedfirst (X, leftendpoint (i)) :( searchsortedfirst (X, rightendpoint (i)) - 1 )
109- searchsorted_interval (X, i :: Interval{ :open, : closed} ) = ( searchsortedlast (X, leftendpoint (i)) + 1 ) : searchsortedlast (X, rightendpoint (i) )
110- searchsorted_interval (X, i :: Interval{ :open , :open} ) = ( searchsortedlast ( X, leftendpoint (i)) + 1 ) : ( searchsortedfirst (X, rightendpoint (i)) - 1 )
76+ _searchsorted_begin (X, x, :: Val {:closed} ; rev ) = searchsortedfirst (X, x; rev, lt = < )
77+ _searchsorted_begin (X, x , :: Val{: open}; rev ) = searchsortedlast (X, x; rev, lt = < ) + 1
78+ _searchsorted_end (X, x, :: Val{: closed}; rev ) = searchsortedlast (X, x; rev, lt = < )
79+ _searchsorted_end (X, x , :: Val{: open}; rev ) = searchsortedfirst ( X, x; rev, lt = < ) - 1
0 commit comments