@@ -34,45 +34,8 @@ julia> findall(in(Interval{:open,:closed}(1,6)), y) # (1,6], does not include 1
34
34
5:14
35
35
```
36
36
"""
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)))
76
39
77
40
# We overload Base._findin to avoid an ambiguity that arises with
78
41
# 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)
85
48
end
86
49
87
50
"""
88
- searchsorted_interval(a, i::Interval)
51
+ searchsorted_interval(a, i::Interval; [rev=false] )
89
52
90
53
Return the range of indices of `a` which is inside of the interval `i` (using binary search), assuming that
91
54
`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)
102
65
1:0
103
66
```
104
67
"""
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
106
75
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