Skip to content

Commit b3f0d6e

Browse files
aplavinhyrodium
andauthored
add searchsorted_interval (#109)
* add searchsorted_interval Co-authored-by: hyrodium <[email protected]> * bump version Co-authored-by: hyrodium <[email protected]>
1 parent 021cf45 commit b3f0d6e

File tree

4 files changed

+57
-2
lines changed

4 files changed

+57
-2
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "IntervalSets"
22
uuid = "8197267c-284f-5f27-9208-e0e47529a953"
3-
version = "0.7.0"
3+
version = "0.7.1"
44

55
[deps]
66
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"

src/IntervalSets.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ export AbstractInterval, Interval, OpenInterval, ClosedInterval,
1414
, .., ±, ordered, width, leftendpoint, rightendpoint, endpoints,
1515
isopenset, isclosedset, isleftclosed, isrightclosed,
1616
isleftopen, isrightopen, closedendpoints,
17-
infimum, supremum
17+
infimum, supremum,
18+
searchsorted_interval
1819

1920
"""
2021
A subtype of `Domain{T}` represents a subset of type `T`, that provides `in`.

src/findall.jl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,28 @@ function Base._findin(a::Union{AbstractArray, Tuple}, b::Interval)
8383
end
8484
ind
8585
end
86+
87+
"""
88+
searchsorted_interval(a, i::Interval)
89+
90+
Return the range of indices of `a` which is inside of the interval `i` (using binary search), assuming that
91+
`a` is already sorted. Return an empty range located at the insertion point if a does not contain values in `i`.
92+
93+
# Examples
94+
```jldoctest
95+
julia> searchsorted_interval([1,2,3,5], 2..4)
96+
2:3
97+
98+
julia> searchsorted_interval([1,2,3,5], 4..1)
99+
4:3
100+
101+
julia> searchsorted_interval(Float64[], 1..3)
102+
1:0
103+
```
104+
"""
105+
function searchsorted_interval end
106+
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)

test/findall.jl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,33 @@ end
149149
assert_in_interval(reverse(x), interval)
150150
end
151151
end
152+
153+
@testset "searchsorted" begin
154+
x = [-10, 0, 1, 1 + eps(), 1.2, 1.5, 1.9, 2 - eps(), 2]
155+
@test searchsorted_interval(x, -Inf..Inf) == 1:9
156+
i = Interval{:closed, :closed}(1, 2)
157+
@test searchsorted_interval(x, i) == findall(in(i),x) == 3:9
158+
i = Interval{:open , :closed}(1, 2)
159+
@test searchsorted_interval(x, i) == findall(in(i),x) == 4:9
160+
i = Interval{:closed, :open }(1, 2)
161+
@test searchsorted_interval(x, i) == findall(in(i),x) == 3:8
162+
i = Interval{:open , :open }(1, 2)
163+
@test searchsorted_interval(x, i) == findall(in(i),x) == 4:8
164+
i = Interval{:closed, :closed}(1, 1)
165+
@test searchsorted_interval(x, i) == findall(in(i),x) == 3:3
166+
i = Interval{:open , :closed}(1, 1)
167+
@test searchsorted_interval(x, i) == findall(in(i),x) == 3:2
168+
i = Interval{:closed, :open }(1, 1)
169+
@test searchsorted_interval(x, i) == findall(in(i),x) == 3:2
170+
i = Interval{:open , :open }(1, 1)
171+
@test searchsorted_interval(x, i) == findall(in(i),x) == 3:2
172+
i = Interval{:closed, :closed}(2, 1)
173+
@test searchsorted_interval(x, i) == findall(in(i),x) == 9:8
174+
i = Interval{:open , :closed}(2, 1)
175+
@test searchsorted_interval(x, i) == findall(in(i),x) == 9:8
176+
i = Interval{:closed, :open }(2, 1)
177+
@test searchsorted_interval(x, i) == findall(in(i),x) == 9:8
178+
i = Interval{:open , :open }(2, 1)
179+
@test searchsorted_interval(x, i) == findall(in(i),x) == 9:8
180+
end
152181
end

0 commit comments

Comments
 (0)