Skip to content

Commit 4d2f8cc

Browse files
authored
Merge pull request #57 from JuliaArrays/teh/0.6
Fix 0.6 breakages and depwarns
2 parents 65263db + e4238b9 commit 4d2f8cc

File tree

12 files changed

+77
-47
lines changed

12 files changed

+77
-47
lines changed

README.md

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ Collaboration is welcome! This is still a work-in-progress. See [the roadmap](ht
1414

1515
```julia
1616
julia> Pkg.clone("https://github.com/JuliaArrays/AxisArrays.jl")
17-
using AxisArrays, SIUnits
18-
import SIUnits.ShortUnits: s, ms, µs
17+
using AxisArrays, Unitful
18+
import Unitful: s, ms, µs
1919

2020
julia> fs = 40000 # Generate a 40kHz noisy signal, with spike-like stuff added for testing
2121
y = randn(60*fs+1)*3
22-
for spk = (sin(0.8:0.2:8.6) .* [0:0.01:.1; .15:.1:.95; 1:-.05:.05] .* 50,
23-
sin(0.8:0.4:8.6) .* [0:0.02:.1; .15:.1:1; 1:-.2:.1] .* 50)
22+
for spk = (sin.(0.8:0.2:8.6) .* [0:0.01:.1; .15:.1:.95; 1:-.05:.05] .* 50,
23+
sin.(0.8:0.4:8.6) .* [0:0.02:.1; .15:.1:1; 1:-.2:.1] .* 50)
2424
i = rand(round(Int,.001fs):1fs)
2525
while i+length(spk)-1 < length(y)
2626
y[i:i+length(spk)-1] += spk
@@ -54,16 +54,15 @@ indices in *any* order, just so long as we annotate them with the axis name:
5454

5555
```jl
5656
julia> A[Axis{:time}(4)]
57-
2-dimensional AxisArray{Float64,2,...} with axes:
58-
:time, 7.5e-5 s:2.5e-5 s:7.5e-5 s
59-
:chan, [:c1,:c2]
60-
And data, a 1x2 SubArray{Float64,2,Array{Float64,2},Tuple{UnitRange{Int64},Colon},2}:
57+
2-dimensional AxisArray{Float64,1,...} with axes:
58+
:chan, Symbol[:c1,:c2]
59+
And data, a 2-element Array{Float64,1}:
6160
-1.4144 -2.82879
6261

6362
julia> A[Axis{:chan}(:c2), Axis{:time}(1:5)]
6463
1-dimensional AxisArray{Float64,1,...} with axes:
6564
:time, 0.0 s:2.5e-5 s:0.0001 s
66-
And data, a 5-element SubArray{Float64,1,Array{Float64,2},Tuple{UnitRange{Int64},Int64},2}:
65+
A[Axis{:chan}(:c2), Axis{:time}(1:5)]:
6766
-6.12181
6867
0.304668
6968
15.7366
@@ -80,7 +79,7 @@ still has the correct time information for those datapoints!
8079
julia> A[40µs .. 220µs, :c1]
8180
1-dimensional AxisArray{Float64,1,...} with axes:
8281
:time, 5.0e-5 s:2.5e-5 s:0.0002 s
83-
And data, a 7-element SubArray{Float64,1,Array{Float64,2},Tuple{UnitRange{Int64},Int64},2}:
82+
And data, a 7-element Array{Float64,1}:
8483
7.86831
8584
-1.4144
8685
-2.02881
@@ -90,7 +89,7 @@ And data, a 7-element SubArray{Float64,1,Array{Float64,2},Tuple{UnitRange{Int64}
9089
-1.97716
9190

9291
julia> axes(ans, 1)
93-
AxisArrays.Axis{:time,SIUnits.SIRange{FloatRange{Float64},Float64,0,0,1,0,0,0,0,0,0}}(5.0e-5 s:2.5e-5 s:0.0002 s)
92+
AxisArrays.Axis{:time,StepRangeLen{Quantity{Float64, Dimensions:{𝐓}, Units:{s}},Base.TwicePrecision{Quantity{Float64, Dimensions:{𝐓}, Units:{s}}},Base.TwicePrecision{Quantity{Float64, Dimensions:{𝐓}, Units:{s}}}}}(5.0e-5 s:2.5e-5 s:0.0002 s)
9493
```
9594

9695
Sometimes, though, what we're really interested in is a window of time about a
@@ -125,7 +124,7 @@ julia> idxs = find(diff(A[:,:c1] .< -15) .> 0)
125124
julia> spks = A[atindex(-200µs .. 800µs, idxs), :c1]
126125
2-dimensional AxisArray{Float64,2,...} with axes:
127126
:time_sub, -0.000175 s:2.5e-5 s:0.000775 s
128-
:time_rep, SIUnits.SIQuantity{Float64,0,0,1,0,0,0,0,0,0}[0.178725 s,0.806825 s,0.88305 s,1.47485 s,1.50465 s,1.53805 s,1.541025 s,2.16365 s,2.368425 s,2.739 s 57.797925 s,57.924075 s,58.06075 s,58.215125 s,58.6403 s,58.96215 s,58.990225 s,59.001325 s,59.48395 s,59.611525 s]
127+
:time_rep, Quantity{Float64, Dimensions:{𝐓}, Units:{s}}[0.178725 s,0.806825 s,0.88305 s,1.47485 s,1.50465 s,1.53805 s,1.541025 s,2.16365 s,2.368425 s,2.739 s 57.797925 s,57.924075 s,58.06075 s,58.215125 s,58.6403 s,58.96215 s,58.990225 s,59.001325 s,59.48395 s,59.611525 s]
129128
And data, a 39x242 Array{Float64,2}:
130129
-1.53038 4.72882 5.8706 -0.231564 0.624714 3.44076
131130
-2.24961 2.12414 5.69936 7.00179 2.30993 5.20432

REQUIRE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ julia 0.5
22
IntervalSets
33
Iterators
44
RangeArrays
5+
Compat 0.19

src/AxisArrays.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module AxisArrays
44

55
using Base: tail
66
using RangeArrays, Iterators, IntervalSets
7+
using Compat
78

89
export AxisArray, Axis, axisnames, axisvalues, axisdim, axes, atindex
910

src/combine.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ sizes{T<:AxisArray}(As::T...) = tuple(zip(map(size, As)...)...)
1313
matchingdims{N,T<:AxisArray}(As::NTuple{N,T}) = all(equalvalued, sizes(As...))
1414
matchingdimsexcept{N,T<:AxisArray}(As::NTuple{N,T}, n::Int) = all(equalvalued, sizes(As[[1:n-1; n+1:end]]...))
1515

16-
function Base.cat{T<:AxisArray}(n::Integer, As::T...)
16+
function Base.cat{T}(n::Integer, As::AxisArray{T}...)
1717
if n <= ndims(As[1])
1818
matchingdimsexcept(As, n) || error("All non-concatenated axes must be identically-valued")
1919
newaxis = Axis{axisnames(As[1])[n]}(vcat(map(A -> A.axes[n].val, As)...))

src/core.jl

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ else
88
using Base: @pure
99
end
1010

11-
typealias Symbols Tuple{Symbol,Vararg{Symbol}}
11+
const Symbols = Tuple{Symbol,Vararg{Symbol}}
1212

1313
@doc """
1414
Type-stable axis-specific indexing and identification with a
@@ -158,17 +158,17 @@ A[ClosedInterval(0.,.3), [:a, :c]] # select an interval and two columns
158158
immutable AxisArray{T,N,D,Ax} <: AbstractArray{T,N}
159159
data::D # D <:AbstractArray, enforced in constructor to avoid dispatch bugs (https://github.com/JuliaLang/julia/issues/6383)
160160
axes::Ax # Ax<:NTuple{N, Axis}, but with specialized Axis{...} types
161-
AxisArray(data::AbstractArray, axs) = new{T,N,D,Ax}(data, axs)
161+
(::Type{AxisArray{T,N,D,Ax}}){T,N,D,Ax}(data::AbstractArray{T,N}, axs::Tuple{Vararg{Axis,N}}) = new{T,N,D,Ax}(data, axs)
162162
end
163163
#
164164
_defaultdimname(i) = i == 1 ? (:row) : i == 2 ? (:col) : i == 3 ? (:page) : Symbol(:dim_, i)
165165

166166
default_axes(A::AbstractArray) = _default_axes(A, indices(A), ())
167-
_default_axes{T,N}(A::AbstractArray{T,N}, inds, axs::NTuple{N}) = axs
168-
@inline _default_axes{T,N,M}(A::AbstractArray{T,N}, inds, axs::NTuple{M}) =
167+
_default_axes{T,N}(A::AbstractArray{T,N}, inds, axs::NTuple{N,Axis}) = axs
168+
@inline _default_axes{T,N,M}(A::AbstractArray{T,N}, inds, axs::NTuple{M,Axis}) =
169169
_default_axes(A, inds, (axs..., _nextaxistype(A, axs)(inds[M+1])))
170170
# Why doesn't @pure work here?
171-
@generated function _nextaxistype{T,M}(A::AbstractArray{T}, axs::NTuple{M})
171+
@generated function _nextaxistype{T,M}(A::AbstractArray{T}, axs::NTuple{M,Axis})
172172
name = _defaultdimname(M+1)
173173
:(Axis{$(Expr(:quote, name))})
174174
end
@@ -245,7 +245,6 @@ Base.size{Ax<:Axis}(A::AxisArray, ::Type{Ax}) = size(A.data, axisdim(A, Ax))
245245
Base.indices(A::AxisArray) = indices(A.data)
246246
Base.indices(A::AxisArray, Ax::Axis) = indices(A.data, axisdim(A, Ax))
247247
Base.indices{Ax<:Axis}(A::AxisArray, ::Type{Ax}) = indices(A.data, axisdim(A, Ax))
248-
Base.linearindexing(A::AxisArray) = Base.linearindexing(A.data)
249248
Base.convert{T,N}(::Type{Array{T,N}}, A::AxisArray{T,N}) = convert(Array{T,N}, A.data)
250249
# Similar is tricky. If we're just changing the element type, it can stay as an
251250
# AxisArray. But if we're changing dimensions, there's no way it can know how
@@ -308,7 +307,7 @@ function permutation(to::Symbols, from::Symbols)
308307
li = linearindices(from)
309308
d = Dict(from[i]=>i for i in li)
310309
covered = similar(dims->falses(length(li)), li)
311-
ind = Array(Int, max(n, nf))
310+
ind = Array{Int}(max(n, nf))
312311
for (i,toi) in enumerate(to)
313312
j = get(d, toi, 0)
314313
ind[i] = j
@@ -421,7 +420,7 @@ axes(A::AbstractArray) = default_axes(A)
421420
axes(A::AbstractArray, dim::Int) = default_axes(A)[dim]
422421

423422
### Axis traits ###
424-
abstract AxisTrait
423+
@compat abstract type AxisTrait end
425424
immutable Dimensional <: AxisTrait end
426425
immutable Categorical <: AxisTrait end
427426
immutable Unsupported <: AxisTrait end

src/indexing.jl

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
typealias Idx Union{Real,Colon,AbstractArray{Int}}
1+
const Idx = Union{Real,Colon,AbstractArray{Int}}
22

3-
using Base: ViewIndex, linearindexing, unsafe_getindex, unsafe_setindex!
3+
using Base: ViewIndex, unsafe_getindex, unsafe_setindex!
44

5-
# Defer linearindexing to the wrapped array
6-
Base.linearindexing{T,N,D}(::AxisArray{T,N,D}) = linearindexing(D)
5+
# Defer IndexStyle to the wrapped array
6+
@compat Base.IndexStyle{T,N,D,Ax}(::Type{AxisArray{T,N,D,Ax}}) = IndexStyle(D)
77

88
# Simple scalar indexing where we just set or return scalars
99
@inline Base.getindex(A::AxisArray, idxs::Int...) = A.data[idxs...]
@@ -26,16 +26,24 @@ Base.setindex!(A::AxisArray, v, idx::Base.IteratorsMD.CartesianIndex) = (A.data[
2626
end
2727
names = axisnames(A)
2828
newaxes = Expr[]
29-
for d=1:lastnonscalar-droplastaxis
29+
drange = 1:lastnonscalar-droplastaxis
30+
for d=drange
3031
if I[d] <: AxisArray
3132
# Indexing with an AxisArray joins the axis names
3233
idxnames = axisnames(I[d])
3334
for i=1:ndims(I[d])
3435
push!(newaxes, :($(Axis{Symbol(names[d], "_", idxnames[i])})(I[$d].axes[$i].val)))
3536
end
3637
elseif I[d] <: Real
37-
elseif I[d] <: Union{AbstractVector,Colon}
38+
elseif I[d] <: AbstractVector
3839
push!(newaxes, :($(Axis{names[d]})(A.axes[$d].val[Base.to_index(I[$d])])))
40+
elseif I[d] <: Colon
41+
if d < length(I) || d <= ndims(A)
42+
push!(newaxes, :($(Axis{names[d]})(A.axes[$d].val)))
43+
else
44+
dimname = _defaultdimname(d)
45+
push!(newaxes, :($(Axis{dimname})(Base.OneTo(Base.trailingsize(A, $d)))))
46+
end
3947
elseif I[d] <: AbstractArray
4048
for i=1:ndims(I[d])
4149
# When we index with non-vector arrays, we *add* dimensions.
@@ -117,6 +125,12 @@ end
117125
return :($meta; to_index(A, $(idxs...)))
118126
end
119127

128+
function Base.reshape{N}(A::AxisArray, ::Type{Val{N}})
129+
# axN, _ = Base.IteratorsMD.split(axes(A), Val{N})
130+
# AxisArray(reshape(A.data, Val{N}), reaxis(A, Base.fill_to_length(axN, :, Val{N})...))
131+
AxisArray(reshape(A.data, Val{N}), reaxis(A, ntuple(d->Colon(), Val{N})...))
132+
end
133+
120134
### Indexing along values of the axes ###
121135

122136
# Default axes indexing throws an error

src/intervals.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# downside is that Intervals are not as useful as they could be; they really
1818
# could be considered as <: Number themselves. We do this in general for any
1919
# supported Scalar:
20-
typealias Scalar Union{Number, Dates.AbstractTime}
20+
const Scalar = Union{Number, Dates.AbstractTime}
2121
Base.promote_rule{T<:Scalar}(::Type{ClosedInterval{T}}, ::Type{T}) = ClosedInterval{T}
2222
Base.promote_rule{T,S<:Scalar}(::Type{ClosedInterval{T}}, ::Type{S}) = ClosedInterval{promote_type(T,S)}
2323
Base.promote_rule{T,S}(::Type{ClosedInterval{T}}, ::Type{ClosedInterval{S}}) = ClosedInterval{promote_type(T,S)}
@@ -62,7 +62,7 @@ immutable RepeatedInterval{T,S,A} <: AbstractVector{T}
6262
end
6363
RepeatedInterval{S,A<:AbstractVector}(window::ClosedInterval{S}, offsets::A) = RepeatedInterval{promote_type(ClosedInterval{S}, eltype(A)), S, A}(window, offsets)
6464
Base.size(r::RepeatedInterval) = size(r.offsets)
65-
Base.linearindexing{R<:RepeatedInterval}(::Type{R}) = Base.LinearFast()
65+
@compat Base.IndexStyle(::Type{<:RepeatedInterval}) = IndexLinear()
6666
Base.getindex(r::RepeatedInterval, i::Int) = r.window + r.offsets[i]
6767
+(window::ClosedInterval, offsets::AbstractVector) = RepeatedInterval(window, offsets)
6868
+(offsets::AbstractVector, window::ClosedInterval) = RepeatedInterval(window, offsets)
@@ -84,5 +84,5 @@ immutable RepeatedIntervalAtIndexes{T,A<:AbstractVector{Int}} <: AbstractVector{
8484
end
8585
atindex(window::ClosedInterval, indexes::AbstractVector) = RepeatedIntervalAtIndexes(window, indexes)
8686
Base.size(r::RepeatedIntervalAtIndexes) = size(r.indexes)
87-
Base.linearindexing{R<:RepeatedIntervalAtIndexes}(::Type{R}) = Base.LinearFast()
87+
@compat Base.IndexStyle(::Type{<:RepeatedIntervalAtIndexes}) = IndexLinear()
8888
Base.getindex(r::RepeatedIntervalAtIndexes, i::Int) = IntervalAtIndex(r.window, r.indexes[i])

src/search.jl

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,30 @@ function Base.searchsorted(a::Range, I::ClosedInterval)
3636
searchsortedfirst(a, I.left):searchsortedlast(a, I.right)
3737
end
3838

39-
if VERSION > v"0.5.0-dev+4557"
40-
# When running with "--check-bounds=yes" (like on Travis), the bounds-check isn't elided
41-
@inline function Base.unsafe_getindex{T}(v::Range{T}, i::Integer)
42-
convert(T, first(v) + (i-1)*step(v))
43-
end
39+
# When running with "--check-bounds=yes" (like on Travis), the bounds-check isn't elided
40+
@inline function Base.unsafe_getindex{T}(v::Range{T}, i::Integer)
41+
convert(T, first(v) + (i-1)*step(v))
42+
end
43+
@inline function Base.unsafe_getindex{T<:Integer}(r::StepRange, s::Range{T})
44+
st = oftype(r.start, r.start + (first(s)-1)*step(r))
45+
range(st, step(r)*step(s), length(s))
46+
end
47+
if VERSION < v"0.6.0-dev.2390"
48+
include_string("""
4449
@inline function Base.unsafe_getindex{T}(r::FloatRange{T}, i::Integer)
4550
convert(T, (r.start + (i-1)*r.step)/r.divisor)
4651
end
47-
@inline function Base.unsafe_getindex{T<:Integer}(r::StepRange, s::Range{T})
48-
st = oftype(r.start, r.start + (first(s)-1)*step(r))
49-
range(st, step(r)*step(s), length(s))
50-
end
5152
@inline function Base.unsafe_getindex(r::FloatRange, s::OrdinalRange)
5253
FloatRange(r.start + (first(s)-1)*r.step, step(s)*r.step, length(s), r.divisor)
5354
end
55+
""")
56+
else
57+
include_string("""
58+
@inline function Base.unsafe_getindex(r::StepRangeLen, s::OrdinalRange)
59+
vfirst = unsafe_getindex(r, first(s))
60+
StepRangeLen(vfirst, r.step*step(s), length(s))
61+
end
62+
""")
5463
end
5564

5665
function unsafe_searchsortedlast{T<:Number}(a::Range{T}, x::Number)

test/REQUIRE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
OffsetArrays
2-
SIUnits
2+
Unitful

test/indexing.jl

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,13 @@ D[1,1,1,1,1] = 10
3737

3838
# Linear indexing across multiple dimensions drops tracking of those dims
3939
@test A[:].axes[1].val == 1:length(A)
40-
@test A[1:2,:].axes[1].val == A.axes[1].val[1:2]
41-
@test A[1:2,:].axes[2].val == 1:Base.trailingsize(A,2)
40+
B = A[1:2,:]
41+
@test B.axes[1].val == A.axes[1].val[1:2]
42+
@test B.axes[2].val == 1:Base.trailingsize(A,2)
43+
B2 = reshape(A, Val{2})
44+
B = B2[1:2,:]
45+
@test B.axes[1].val == A.axes[1].val[1:2]
46+
@test B.axes[2].val == 1:Base.trailingsize(A,2)
4247

4348
B = AxisArray(reshape(1:15, 5,3), .1:.1:0.5, [:a, :b, :c])
4449

0 commit comments

Comments
 (0)