Skip to content

Commit 7c9fce8

Browse files
authored
Merge pull request #36 from mbauman/teh/intervals
Rebase on IntervalSets
2 parents 051aa93 + ca97a6f commit 7c9fce8

File tree

11 files changed

+80
-138
lines changed

11 files changed

+80
-138
lines changed

.travis.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ os:
33
- linux
44
- osx
55
julia:
6-
- 0.4
76
- 0.5
87
- nightly
98
notifications:

REQUIRE

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
julia 0.4
1+
julia 0.5-
2+
IntervalSets
23
Iterators
34
Compat
45
RangeArrays

src/AxisArrays.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
module AxisArrays
22

3-
using RangeArrays, Iterators, Compat
3+
using RangeArrays, Iterators, IntervalSets, Compat
44
using Compat.view
55

6-
export AxisArray, Axis, Interval, axisnames, axisvalues, axisdim, axes, .., atindex
6+
export AxisArray, Axis, axisnames, axisvalues, axisdim, axes, atindex
7+
8+
# From IntervalSets:
9+
export ClosedInterval, ..
10+
Base.@deprecate_binding Interval ClosedInterval
711

812
include("core.jl")
913
include("intervals.jl")

src/core.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ Two main types of axes supported by default include:
117117
of elements.
118118
119119
* Dimensional axis -- These are sorted vectors or iterators that can
120-
be indexed by `Interval()`. These are commonly used for sequences of
120+
be indexed by `ClosedInterval()`. These are commonly used for sequences of
121121
times or date-times. For regular sample rates, ranges can be used.
122122
123123
User-defined axis types can be added along with custom indexing
@@ -142,8 +142,8 @@ Symbols for column headers.
142142
```julia
143143
A = AxisArray(reshape(1:15, 5, 3), Axis{:time}(.1:.1:0.5), Axis{:col}([:a, :b, :c]))
144144
A[Axis{:time}(1:3)] # equivalent to A[1:3,:]
145-
A[Axis{:time}(Interval(.2,.4))] # restrict the AxisArray along the time axis
146-
A[Interval(0.,.3), [:a, :c]] # select an interval and two columns
145+
A[Axis{:time}(ClosedInterval(.2,.4))] # restrict the AxisArray along the time axis
146+
A[ClosedInterval(0.,.3), [:a, :c]] # select an interval and two columns
147147
```
148148
149149
""" ->

src/indexing.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,15 +136,15 @@ axisindexes(t, ax, idx) = error("cannot index $(typeof(ax)) with $(typeof(idx));
136136

137137
# Dimensional axes may be indexed directy by their elements if Non-Real and unique
138138
# Maybe extend error message to all <: Numbers if Base allows it?
139-
axisindexes{T<:Real}(::Type{Dimensional}, ax::AbstractVector{T}, idx::T) = error("indexing by axis value is not supported for axes with $(eltype(ax)) elements; use an Interval instead")
139+
axisindexes{T<:Real}(::Type{Dimensional}, ax::AbstractVector{T}, idx::T) = error("indexing by axis value is not supported for axes with $(eltype(ax)) elements; use an ClosedInterval instead")
140140
function axisindexes(::Type{Dimensional}, ax::AbstractVector, idx)
141-
idxs = searchsorted(ax, Interval(idx,idx))
141+
idxs = searchsorted(ax, ClosedInterval(idx,idx))
142142
length(idxs) > 1 && error("more than one datapoint lies on axis value $idx; use an interval to return all values")
143143
idxs[1]
144144
end
145145

146146
# Dimensional axes may be indexed by intervals to select a range
147-
axisindexes{T}(::Type{Dimensional}, ax::AbstractVector{T}, idx::Interval) = searchsorted(ax, idx)
147+
axisindexes{T}(::Type{Dimensional}, ax::AbstractVector{T}, idx::ClosedInterval) = searchsorted(ax, idx)
148148

149149
# Or repeated intervals, which only work if the axis is a range since otherwise
150150
# there will be a non-constant number of indices in each repetition.

src/intervals.jl

Lines changed: 32 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,15 @@
1-
@doc """
2-
An Interval represents all values between and including its two endpoints.
3-
Intervals are parameterized by the type of its endpoints; this type must be
4-
a concrete leaf type that supports a partial ordering. Promoting arithmetic
5-
is defined for Intervals of `Number` and `Dates.AbstractTime`.
6-
7-
### Type parameters
8-
9-
```julia
10-
immutable Interval{T}
11-
```
12-
* `T` : the type of the interval's endpoints. Must be a concrete leaf type.
13-
14-
### Constructors
15-
16-
```julia
17-
Interval(a, b)
18-
a .. b
19-
```
20-
21-
### Arguments
22-
23-
* `a` : lower bound of the interval
24-
* `b` : upper bound of the interval
25-
26-
### Examples
27-
28-
```julia
29-
A = AxisArray(collect(1:20), Axis{:time}(.1:.1:2.0))
30-
A[Interval(0.2,0.5)]
31-
A[0.0 .. 0.5]
32-
```
33-
34-
""" ->
35-
immutable Interval{T}
36-
lo::T
37-
hi::T
38-
function Interval(lo, hi)
39-
lo <= hi ? new(lo, hi) : throw(ArgumentError("lo must be less than or equal to hi"))
40-
end
41-
end
42-
Interval{T}(a::T,b::T) = Interval{T}(a,b)
43-
# Allow promotion during construction, but only if it results in a leaf type
44-
function Interval{T,S}(a::T, b::S)
45-
R = promote_type(T,S)
46-
isleaftype(R) || throw(ArgumentError("cannot promote $a and $b to a common leaf type"))
47-
Interval{R}(promote(a,b)...)
48-
end
49-
const .. = Interval
50-
51-
Base.convert{T}(::Type{Interval}, x::T) = Interval{T}(x,x)
52-
Base.convert{T}(::Type{Interval{T}}, x::T) = Interval{T}(x,x)
53-
Base.convert{T,S}(::Type{Interval{T}}, x::S) = (y=convert(T, x); Interval{T}(y,y))
54-
Base.convert{T}(::Type{Interval{T}}, w::Interval) = Interval{T}(convert(T, w.lo), convert(T, w.hi))
55-
561
# Promotion rules for "promiscuous" types like Intervals and SIUnits, which both
572
# simply wrap any Number, are often ambiguous. That is, which type should "win"
58-
# -- is the promotion between an SIUnit and an Interval an SIQuantity{Interval}
59-
# or is it an Interval{SIQuantity}? For our uses in AxisArrays, though, we can
3+
# -- is the promotion between an SIUnit and an ClosedInterval an SIQuantity{ClosedInterval}
4+
# or is it an ClosedInterval{SIQuantity}? For our uses in AxisArrays, though, we can
605
# sidestep this problem by making Intervals *not* a subtype of Number. Then in
616
# order for them to plug into the promotion system, we *extend* the promoting
62-
# operator behaviors to Union{Number, Interval}. This way other types can
7+
# operator behaviors to Union{Number, ClosedInterval}. This way other types can
638
# similarly define their own extensions to the promoting operators without fear
649
# of ambiguity -- there will simply be, e.g.,
6510
#
6611
# f(x::Number, y::Number) = f(promote(x,y)...) # in base
67-
# f(x::Union{Number, Interval}, y::Union{Number, Interval}) = f(promote(x,y)...)
12+
# f(x::Union{Number, ClosedInterval}, y::Union{Number, ClosedInterval}) = f(promote(x,y)...)
6813
# f(x::Union{Number, T}, y::Union{Number, T}) = f(promote(x,y)...)
6914
#
7015
# In this way, these "promiscuous" types will never interact unless explicitly
@@ -73,78 +18,71 @@ Base.convert{T}(::Type{Interval{T}}, w::Interval) = Interval{T}(convert(T, w.lo)
7318
# could be considered as <: Number themselves. We do this in general for any
7419
# supported Scalar:
7520
typealias Scalar Union{Number, Dates.AbstractTime}
76-
Base.promote_rule{T<:Scalar}(::Type{Interval{T}}, ::Type{T}) = Interval{T}
77-
Base.promote_rule{T,S<:Scalar}(::Type{Interval{T}}, ::Type{S}) = Interval{promote_type(T,S)}
78-
Base.promote_rule{T,S}(::Type{Interval{T}}, ::Type{Interval{S}}) = Interval{promote_type(T,S)}
21+
Base.promote_rule{T<:Scalar}(::Type{ClosedInterval{T}}, ::Type{T}) = ClosedInterval{T}
22+
Base.promote_rule{T,S<:Scalar}(::Type{ClosedInterval{T}}, ::Type{S}) = ClosedInterval{promote_type(T,S)}
23+
Base.promote_rule{T,S}(::Type{ClosedInterval{T}}, ::Type{ClosedInterval{S}}) = ClosedInterval{promote_type(T,S)}
7924

8025
import Base: isless, <=, >=, ==, +, -, *, /, ^, //
8126
# TODO: Is this a total ordering? (antisymmetric, transitive, total)?
82-
isless(a::Interval, b::Interval) = isless(a.hi, b.lo)
27+
isless(a::ClosedInterval, b::ClosedInterval) = isless(a.right, b.left)
8328
# The default definition for <= assumes a strict total order (<=(x,y) = !(y < x))
84-
<=(a::Interval, b::Interval) = a.lo <= b.lo && a.hi <= b.hi
85-
==(a::Interval, b::Interval) = a.hi == b.hi && a.lo == b.lo
86-
const _interval_hash = UInt == UInt64 ? 0x1588c274e0a33ad4 : 0x1e3f7252
87-
Base.hash(a::Interval, h::UInt) = hash(a.lo, hash(a.hi, hash(_interval_hash, h)))
88-
+(a::Interval) = a
89-
+(a::Interval, b::Interval) = Interval(a.lo + b.lo, a.hi + b.hi)
90-
-(a::Interval) = Interval(-a.hi, -a.lo)
91-
-(a::Interval, b::Interval) = a + (-b)
29+
<=(a::ClosedInterval, b::ClosedInterval) = a.left <= b.left && a.right <= b.right
30+
+(a::ClosedInterval) = a
31+
+(a::ClosedInterval, b::ClosedInterval) = ClosedInterval(a.left + b.left, a.right + b.right)
32+
-(a::ClosedInterval) = ClosedInterval(-a.right, -a.left)
33+
-(a::ClosedInterval, b::ClosedInterval) = a + (-b)
9234
for f in (:(*), :(/), :(//))
9335
# For a general monotonic operator, we compute the operation over all
9436
# combinations of the endpoints and return the widest interval
95-
@eval function $(f)(a::Interval, b::Interval)
96-
w = $(f)(a.lo, b.lo)
97-
x = $(f)(a.lo, b.hi)
98-
y = $(f)(a.hi, b.lo)
99-
z = $(f)(a.hi, b.hi)
100-
Interval(min(w,x,y,z), max(w,x,y,z))
37+
@eval function $(f)(a::ClosedInterval, b::ClosedInterval)
38+
w = $(f)(a.left, b.left)
39+
x = $(f)(a.left, b.right)
40+
y = $(f)(a.right, b.left)
41+
z = $(f)(a.right, b.right)
42+
ClosedInterval(min(w,x,y,z), max(w,x,y,z))
10143
end
10244
end
10345

104-
Base.in(a, b::Interval) = b.lo <= a <= b.hi
105-
Base.in(a::Interval, b::Interval) = b.lo <= a.lo && a.hi <= b.hi
106-
Base.minimum(a::Interval) = a.lo
107-
Base.maximum(a::Interval) = a.hi
10846
# Extend the promoting operators to include Intervals. The comparison operators
10947
# (<, <=, and ==) are a pain since they are non-promoting fallbacks that call
11048
# isless, !(y < x) (which is wrong), and ===. So implementing promotion with
111-
# Union{T, Interval} causes stack overflows for the base types. This is safer:
49+
# Union{T, ClosedInterval} causes stack overflows for the base types. This is safer:
11250
for f in (:isless, :(<=), :(>=), :(==), :(+), :(-), :(*), :(/), :(//))
11351
# We don't use promote here, though, because promotions can be lossy... and
11452
# that's particularly bad for comparisons. Just make an interval instead.
115-
@eval $(f)(x::Interval, y::Scalar) = $(f)(x, y..y)
116-
@eval $(f)(x::Scalar, y::Interval) = $(f)(x..x, y)
53+
@eval $(f)(x::ClosedInterval, y::Scalar) = $(f)(x, y..y)
54+
@eval $(f)(x::Scalar, y::ClosedInterval) = $(f)(x..x, y)
11755
end
11856

11957
# And, finally, we have an Array-of-Structs to Struct-of-Arrays transform for
12058
# the common case where the interval is constant over many offsets:
12159
immutable RepeatedInterval{T,S,A} <: AbstractVector{T}
122-
window::Interval{S}
60+
window::ClosedInterval{S}
12361
offsets::A # A <: AbstractVector
12462
end
125-
RepeatedInterval{S,A<:AbstractVector}(window::Interval{S}, offsets::A) = RepeatedInterval{promote_type(Interval{S}, eltype(A)), S, A}(window, offsets)
63+
RepeatedInterval{S,A<:AbstractVector}(window::ClosedInterval{S}, offsets::A) = RepeatedInterval{promote_type(ClosedInterval{S}, eltype(A)), S, A}(window, offsets)
12664
Base.size(r::RepeatedInterval) = size(r.offsets)
12765
Base.linearindexing{R<:RepeatedInterval}(::Type{R}) = Base.LinearFast()
12866
Base.getindex(r::RepeatedInterval, i::Int) = r.window + r.offsets[i]
129-
+(window::Interval, offsets::AbstractVector) = RepeatedInterval(window, offsets)
130-
+(offsets::AbstractVector, window::Interval) = RepeatedInterval(window, offsets)
131-
-(window::Interval, offsets::AbstractVector) = RepeatedInterval(window, -offsets)
132-
-(offsets::AbstractVector, window::Interval) = RepeatedInterval(-window, offsets)
67+
+(window::ClosedInterval, offsets::AbstractVector) = RepeatedInterval(window, offsets)
68+
+(offsets::AbstractVector, window::ClosedInterval) = RepeatedInterval(window, offsets)
69+
-(window::ClosedInterval, offsets::AbstractVector) = RepeatedInterval(window, -offsets)
70+
-(offsets::AbstractVector, window::ClosedInterval) = RepeatedInterval(-window, offsets)
13371

13472
# As a special extension to intervals, we allow specifying Intervals about a
13573
# particular index, which is resolved by an axis upon indexing.
13674
immutable IntervalAtIndex{T}
137-
window::Interval{T}
75+
window::ClosedInterval{T}
13876
index::Int
13977
end
140-
atindex(window::Interval, index::Integer) = IntervalAtIndex(window, index)
78+
atindex(window::ClosedInterval, index::Integer) = IntervalAtIndex(window, index)
14179

14280
# And similarly, an AoS -> SoA transform:
14381
immutable RepeatedIntervalAtIndexes{T,A<:AbstractVector{Int}} <: AbstractVector{IntervalAtIndex{T}}
144-
window::Interval{T}
82+
window::ClosedInterval{T}
14583
indexes::A # A <: AbstractVector{Int}
14684
end
147-
atindex(window::Interval, indexes::AbstractVector) = RepeatedIntervalAtIndexes(window, indexes)
85+
atindex(window::ClosedInterval, indexes::AbstractVector) = RepeatedIntervalAtIndexes(window, indexes)
14886
Base.size(r::RepeatedIntervalAtIndexes) = size(r.indexes)
14987
Base.linearindexing{R<:RepeatedIntervalAtIndexes}(::Type{R}) = Base.LinearFast()
15088
Base.getindex(r::RepeatedIntervalAtIndexes, i::Int) = IntervalAtIndex(r.window, r.indexes[i])

src/search.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,17 @@ end
2323
# TODO: This could plug into the sorting system better, but it's fine for now
2424
# TODO: This needs to support Dates.
2525
"""
26-
unsafe_searchsorted(a::Range, I::Interval)
26+
unsafe_searchsorted(a::Range, I::ClosedInterval)
2727
2828
Return the indices of the range that fall within an interval without checking
2929
bounds, possibly extrapolating outside the range if needed.
3030
"""
31-
function unsafe_searchsorted(a::Range, I::Interval)
32-
unsafe_searchsortedfirst(a, I.lo):unsafe_searchsortedlast(a, I.hi)
31+
function unsafe_searchsorted(a::Range, I::ClosedInterval)
32+
unsafe_searchsortedfirst(a, I.left):unsafe_searchsortedlast(a, I.right)
3333
end
3434
# Base only specializes searching ranges by Numbers; so optimize for Intervals
35-
function Base.searchsorted(a::Range, I::Interval)
36-
searchsortedfirst(a, I.lo):searchsortedlast(a, I.hi)
35+
function Base.searchsorted(a::Range, I::ClosedInterval)
36+
searchsortedfirst(a, I.left):searchsortedlast(a, I.right)
3737
end
3838

3939
if VERSION > v"0.5.0-dev+4557"

src/sortedvector.jl

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Indexing that would unsort the data is prohibited. A SortedVector is a
1010
Dimensional axis, and no checking is done to ensure that the data is
1111
sorted. Duplicate values are allowed.
1212
13-
A SortedVector axis can be indexed with an Interval, with a value, or
13+
A SortedVector axis can be indexed with an ClosedInterval, with a value, or
1414
with a vector of values. Use of a SortedVector{Tuple} axis allows
1515
indexing similar to the hierarchical index of the Python Pandas
1616
package or the R data.table package.
@@ -30,7 +30,7 @@ SortedVector(x::AbstractVector)
3030
```julia
3131
v = SortedVector(collect([1.; 10.; 10:15.]))
3232
A = AxisArray(reshape(1:16, 8, 2), v, [:a, :b])
33-
A[Interval(8.,12.), :]
33+
A[ClosedInterval(8.,12.), :]
3434
A[1., :]
3535
A[10., :]
3636
@@ -44,8 +44,8 @@ A[:b, :]
4444
A[[:a,:c], :]
4545
A[(:a,:x), :]
4646
A[(:a,:x,:x), :]
47-
A[Interval(:a,:b), :]
48-
A[Interval((:a,:x),(:b,:x)), :]
47+
A[ClosedInterval(:a,:b), :]
48+
A[ClosedInterval((:a,:x),(:b,:x)), :]
4949
```
5050
5151
""" ->
@@ -102,8 +102,8 @@ _isless(t1, t2::Tuple) = _isless((t1,),t2)
102102
# only define comparisons against Numbers and Dates. We're able to do this on
103103
# our own local function... doing this directly on isless itself would be
104104
# fraught with trouble.
105-
_isless(a::Interval, b::Interval) = _isless(a.hi, b.lo)
106-
_isless(t1::Interval, t2::Tuple) = _isless(t1, Interval(t2,t2))
107-
_isless(t1::Tuple, t2::Interval) = _isless(Interval(t1,t1), t2)
108-
_isless(a::Interval, b) = _isless(a, Interval(b,b))
109-
_isless(a, b::Interval) = _isless(Interval(a,a), b)
105+
_isless(a::ClosedInterval, b::ClosedInterval) = _isless(a.right, b.left)
106+
_isless(t1::ClosedInterval, t2::Tuple) = _isless(t1, ClosedInterval(t2,t2))
107+
_isless(t1::Tuple, t2::ClosedInterval) = _isless(ClosedInterval(t1,t1), t2)
108+
_isless(a::ClosedInterval, b) = _isless(a, ClosedInterval(b,b))
109+
_isless(a, b::ClosedInterval) = _isless(ClosedInterval(a,a), b)

test/indexing.jl

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ D[1,1,1,1,1] = 10
88
@test A == A.data
99
@test A[:,:,:] == A[Axis{:row}(:)] == A[Axis{:col}(:)] == A[Axis{:page}(:)] == A.data[:,:,:]
1010
# Test UnitRange slices
11-
@test A[1:2,:,:] == A.data[1:2,:,:] == A[Axis{:row}(1:2)] == A[Axis{1}(1:2)] == A[Axis{:row}(Interval(-Inf,Inf))] == A[[true,true],:,:]
12-
@test A[:,1:2,:] == A.data[:,1:2,:] == A[Axis{:col}(1:2)] == A[Axis{2}(1:2)] == A[Axis{:col}(Interval(0.0, .25))] == A[:,[true,true,false],:]
13-
@test A[:,:,1:2] == A.data[:,:,1:2] == A[Axis{:page}(1:2)] == A[Axis{3}(1:2)] == A[Axis{:page}(Interval(-1., .22))] == A[:,:,[true,true,false,false]]
11+
@test A[1:2,:,:] == A.data[1:2,:,:] == A[Axis{:row}(1:2)] == A[Axis{1}(1:2)] == A[Axis{:row}(ClosedInterval(-Inf,Inf))] == A[[true,true],:,:]
12+
@test A[:,1:2,:] == A.data[:,1:2,:] == A[Axis{:col}(1:2)] == A[Axis{2}(1:2)] == A[Axis{:col}(ClosedInterval(0.0, .25))] == A[:,[true,true,false],:]
13+
@test A[:,:,1:2] == A.data[:,:,1:2] == A[Axis{:page}(1:2)] == A[Axis{3}(1:2)] == A[Axis{:page}(ClosedInterval(-1., .22))] == A[:,:,[true,true,false,false]]
1414
# Test scalar slices
1515
@test A[2,:,:] == A.data[2,:,:] == A[Axis{:row}(2)]
1616
@test A[:,2,:] == A.data[:,2,:] == A[Axis{:col}(2)]
@@ -40,37 +40,37 @@ D[1,1,1,1,1] = 10
4040
B = AxisArray(reshape(1:15, 5,3), .1:.1:0.5, [:a, :b, :c])
4141

4242
# Test indexing by Intervals
43-
@test B[Interval(0.0, 0.5), :] == B[Interval(0.0, 0.5)] == B[:,:]
44-
@test B[Interval(0.0, 0.3), :] == B[Interval(0.0, 0.3)] == B[1:3,:]
45-
@test B[Interval(0.15, 0.3), :] == B[Interval(0.15, 0.3)] == B[2:3,:]
46-
@test B[Interval(0.2, 0.5), :] == B[Interval(0.2, 0.5)] == B[2:end,:]
47-
@test B[Interval(0.2, 0.6), :] == B[Interval(0.2, 0.6)] == B[2:end,:]
43+
@test B[ClosedInterval(0.0, 0.5), :] == B[ClosedInterval(0.0, 0.5)] == B[:,:]
44+
@test B[ClosedInterval(0.0, 0.3), :] == B[ClosedInterval(0.0, 0.3)] == B[1:3,:]
45+
@test B[ClosedInterval(0.15, 0.3), :] == B[ClosedInterval(0.15, 0.3)] == B[2:3,:]
46+
@test B[ClosedInterval(0.2, 0.5), :] == B[ClosedInterval(0.2, 0.5)] == B[2:end,:]
47+
@test B[ClosedInterval(0.2, 0.6), :] == B[ClosedInterval(0.2, 0.6)] == B[2:end,:]
4848

4949
# Test Categorical indexing
5050
@test B[:, :a] == B[:,1]
5151
@test B[:, :c] == B[:,3]
5252
@test B[:, [:a]] == B[:,[1]]
5353
@test B[:, [:a,:c]] == B[:,[1,3]]
5454

55-
@test B[Axis{:row}(Interval(0.15, 0.3))] == B[2:3,:]
55+
@test B[Axis{:row}(ClosedInterval(0.15, 0.3))] == B[2:3,:]
5656

5757
A = AxisArray(reshape(1:256, 4,4,4,4), Axis{:d1}(.1:.1:.4), Axis{:d2}(1//10:1//10:4//10), Axis{:d3}(["1","2","3","4"]), Axis{:d4}([:a, :b, :c, :d]))
5858
ax1 = axes(A)[1]
5959
@test A[Axis{:d1}(2)] == A[ax1(2)]
60-
@test A.data[1:2,:,:,:] == A[Axis{:d1}(Interval(.1,.2))] == A[Interval(.1,.2),:,:,:] == A[Interval(.1,.2),:,:,:,1] == A[Interval(.1,.2)]
61-
@test A.data[:,1:2,:,:] == A[Axis{:d2}(Interval(1//10,2//10))] == A[:,Interval(1//10,2//10),:,:] == A[:,Interval(1//10,2//10),:,:,1] == A[:,Interval(1//10,2//10)]
60+
@test A.data[1:2,:,:,:] == A[Axis{:d1}(ClosedInterval(.1,.2))] == A[ClosedInterval(.1,.2),:,:,:] == A[ClosedInterval(.1,.2),:,:,:,1] == A[ClosedInterval(.1,.2)]
61+
@test A.data[:,1:2,:,:] == A[Axis{:d2}(ClosedInterval(1//10,2//10))] == A[:,ClosedInterval(1//10,2//10),:,:] == A[:,ClosedInterval(1//10,2//10),:,:,1] == A[:,ClosedInterval(1//10,2//10)]
6262
@test A.data[:,:,1:2,:] == A[Axis{:d3}(["1","2"])] == A[:,:,["1","2"],:] == A[:,:,["1","2"],:,1] == A[:,:,["1","2"]]
6363
@test A.data[:,:,:,1:2] == A[Axis{:d4}([:a,:b])] == A[:,:,:,[:a,:b]] == A[:,:,:,[:a,:b],1]
6464

6565
A = AxisArray(reshape(1:32, 2, 2, 2, 2, 2), .1:.1:.2, .1:.1:.2, .1:.1:.2, [:a, :b], [:c, :d])
66-
@test A[Interval(.15, .25), Interval(.05, .15), Interval(.15, .25), :a] == A.data[2:2, 1:1, 2:2, 1, :]
66+
@test A[ClosedInterval(.15, .25), ClosedInterval(.05, .15), ClosedInterval(.15, .25), :a] == A.data[2:2, 1:1, 2:2, 1, :]
6767
@test A[Axis{:dim_5}(2)] == A.data[:, :, :, :, 2]
6868

6969
# Test vectors
7070
v = AxisArray(collect(.1:.1:10.0), .1:.1:10.0)
7171
@test v[Colon()] === v
7272
@test v[:] == v.data[:] == v[Axis{:row}(:)]
73-
@test v[3:8] == v.data[3:8] == v[Interval(.25,.85)] == v[Axis{:row}(3:8)] == v[Axis{:row}(Interval(.22,.88))]
73+
@test v[3:8] == v.data[3:8] == v[ClosedInterval(.25,.85)] == v[Axis{:row}(3:8)] == v[Axis{:row}(ClosedInterval(.22,.88))]
7474

7575
# Test repeated intervals
7676
A = AxisArray([1:100 -1:-1:-100], .1:.1:10.0, [:c1, :c2])

test/intervals.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,6 @@ d[0x1 .. 0x2] = 3
8282
@test !(0.1 .. 0.2 <= 2//10)
8383

8484
# Conversion and construction:
85-
@test 1 .. 2 === Interval(1, 2) === Interval{Int}(1.0, 2.0) === Interval{Int}(1.0 .. 2.0)
86-
@test 1.0 .. 2.0 === Interval(1.0, 2) === Interval{Float64}(1, 2) === Interval{Float64}(1 .. 2)
87-
@test 1 .. 1 === Interval(1, 1) === Interval(1) === Interval{Int}(1) === Interval{Int}(1.0, 1.0) === Interval{Int}(1.0)
85+
@test 1 .. 2 === ClosedInterval(1, 2) === ClosedInterval{Int}(1.0, 2.0) === ClosedInterval{Int}(1.0 .. 2.0)
86+
@test 1.0 .. 2.0 === ClosedInterval(1.0, 2) === ClosedInterval{Float64}(1, 2) === ClosedInterval{Float64}(1 .. 2)
87+
@test 1 .. 1 === ClosedInterval(1, 1) === ClosedInterval{Int}(1.0, 1.0)

0 commit comments

Comments
 (0)