Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Towards 0.7 support #143

Merged
merged 29 commits into from
Aug 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
10cf55f
work towards 0.7 support
Evizero Aug 5, 2018
216c0d9
Use Val() syntax in tests
mbauman Aug 7, 2018
2376678
Type stable constructors
mbauman Aug 8, 2018
2e0b174
lastindex, range, and squeeze deprecations...
mbauman Aug 8, 2018
c75b67e
Core tests pass!
mbauman Aug 14, 2018
51da9a5
fixup
mbauman Aug 15, 2018
6c7f562
Try using a tuple of AxisArrays as "axes"-ish objects from reduced_in…
mbauman Aug 16, 2018
40fe310
fixup
mbauman Aug 16, 2018
5f458db
Minor ntuple and axes/indices fixes
mbauman Aug 16, 2018
71948c5
update travis yml
Evizero Aug 16, 2018
f3df570
drop 0.6 support
Evizero Aug 16, 2018
548854d
fix more deprecation warnings
Evizero Aug 16, 2018
a4a0453
More qualifications of axes
mbauman Aug 16, 2018
4f34739
Replace _nextaxistype with _default_axis
mbauman Aug 16, 2018
14d28f8
Make default_axes support different numbers of axes, move errors into…
mbauman Aug 16, 2018
42fe1a5
Indexing fixes:
mbauman Aug 16, 2018
6723577
fixup
mbauman Aug 16, 2018
d735145
Indexing tests pass!
mbauman Aug 16, 2018
65e82a7
Fix SortedVector tests (random seeding has changed)
mbauman Aug 16, 2018
cad080a
Same deal with categorical vectors
mbauman Aug 16, 2018
34accd9
find->findall, axes qualification
mbauman Aug 16, 2018
cf3409f
Combine and join fixes
mbauman Aug 16, 2018
4c83704
Disable problematic inference failures
mbauman Aug 16, 2018
8b24170
final fixes for v"1.0"
mbauman Aug 16, 2018
ec8d2de
Try deploying with 1.0; add Unitful for the example
mbauman Aug 16, 2018
b9a1d1d
Add a notice regarding the `axes` function to the README
mbauman Aug 16, 2018
e7a9f46
Test and fix String(::IOBuffer) deprecation
mbauman Aug 17, 2018
8afaac2
Re-enable ambiguity tests on 1.0
mbauman Aug 17, 2018
343d9ee
Re-enable disabled tests - just don't test at-inferred
mbauman Aug 17, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,30 @@ os:
- linux
- osx
julia:
- 0.6
- 0.7
- 1.0
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Evizero: If you do this, you also need to bump REQUIRE to 0.7. I recommend that since a lot of packages drop 0.6 support on master. (@mbauman for attention)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right

- nightly
notifications:
email: false
matrix:
allow_failures:
- julia: nightly
- julia: nightly

# uncomment the following lines to override the default test script
script:
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
- julia --check-bounds=yes -e 'Pkg.clone(pwd()); Pkg.build("AxisArrays"); Pkg.test("AxisArrays"; coverage=true)'
- julia --check-bounds=yes --color=yes -e 'import Pkg; Pkg.clone(pwd()); Pkg.build("AxisArrays"); Pkg.test("AxisArrays"; coverage=true)';

jobs:
include:
- stage: deploy
julia: 0.7
os: linux
script:
- julia -e 'import Pkg; Pkg.clone(pwd()); Pkg.build("AxisArrays")'
- julia -e 'import Pkg; Pkg.add("Documenter"); Pkg.add("Unitful")'
- julia -e 'import AxisArrays; ENV["DOCUMENTER_DEBUG"] = "true"; include(joinpath("docs","make.jl"))'

after_success:
- julia -e 'Pkg.add("Unitful")'
- julia -e 'cd(Pkg.dir("AxisArrays")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'
- julia -e 'Pkg.add("Documenter")'
- julia -e 'cd(Pkg.dir("AxisArrays")); include(joinpath("docs", "make.jl"))'
# - julia -e 'Pkg.add("Unitful")' ?
- julia -e 'using Pkg; Pkg.add("Coverage"); using Coverage; Coveralls.submit(process_folder())'
29 changes: 27 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,31 @@ In contrast to similar approaches in [Images.jl](https://github.com/timholy/Imag

Collaboration is welcome! This is still a work-in-progress. See [the roadmap](https://github.com/JuliaArrays/AxisArrays.jl/issues/7) for the project's current direction.

### Notice regarding `axes`

Since Julia version 0.7, the name `axes` is exported by default from `Base`
with a meaning (and behavior) that is distinct from how AxisArrays has been
using it. Since you cannot simultaneously be `using` the same name from the two
different modules, Julia will issue a warning, and it'll error if you try to
use `axes` without qualification:

```julia
julia> axes([])
WARNING: both AxisArrays and Base export "axes"; uses of it in module Main must be qualified
ERROR: UndefVarError: axes not defined
```

Packages that are upgrading to support 0.7+ and use AxisArrays should follow
this upgrade path:

* Replace all uses of the `axes` function with the fully-qualified `AxisArrays.axes`
* Replace all uses of the deprecated `indices` function with the un-qualified `axes`
* Immediately after `using AxisArrays`, add `const axes = Base.axes`

In the future, AxisArrays will be looking for a new name for its functionality.
This will allow you to use the idiomatic `Base` name and offers an easy upgrade
path to whatever the new name will be.

## Example of currently-implemented behavior:

```julia
Expand Down Expand Up @@ -97,7 +122,7 @@ And data, a 7-element Array{Float64,1}:
-0.226449
0.821446

julia> axes(ans, 1)
julia> AxisArrays.axes(ans, 1)
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)
```

Expand Down Expand Up @@ -154,7 +179,7 @@ very powerful behaviors. For example, let's threshold our data and find windows
about those threshold crossings.

```julia
julia> idxs = find(diff(A[:,:c1] .< -15) .> 0);
julia> idxs = findall(diff(A[:,:c1] .< -15) .> 0);

julia> spks = A[atindex(-200µs .. 800µs, idxs), :c1]
2-dimensional AxisArray{Float64,2,...} with axes:
Expand Down
2 changes: 1 addition & 1 deletion REQUIRE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
julia 0.6
julia 0.7
IntervalSets 0.1
IterTools
RangeArrays
Expand Down
2 changes: 1 addition & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ makedocs(
deploydocs(
deps = Deps.pip("mkdocs", "python-markdown-math"),
repo = "github.com/JuliaArrays/AxisArrays.jl.git",
julia = "0.6"
julia = "1.0"
)
4 changes: 2 additions & 2 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ And data, a 7-element Array{Float64,1}:
-0.226449
0.821446

julia> axes(ans, 1)
julia> AxisArrays.axes(ans, 1)
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)

```
Expand Down Expand Up @@ -182,7 +182,7 @@ very powerful behaviors. For example, let's threshold our data and find windows
about those threshold crossings.

```jldoctest
julia> idxs = find(diff(A[:,:c1] .< -15) .> 0);
julia> idxs = findall(diff(A[:,:c1] .< -15) .> 0);

julia> spks = A[atindex(-200µs .. 800µs, idxs), :c1]
2-dimensional AxisArray{Float64,2,...} with axes:
Expand Down
7 changes: 4 additions & 3 deletions src/AxisArrays.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__precompile__()
VERSION < v"0.7.0-beta2.199" && __precompile__()

module AxisArrays

Expand All @@ -7,8 +7,9 @@ import Base.Iterators: repeated
using RangeArrays, IntervalSets
using IterTools
using Compat
using Compat.Dates
using Compat: AbstractRange
using Dates

function axes end

export AxisArray, Axis, axisnames, axisvalues, axisdim, axes, atindex, atvalue, collapse

Expand Down
8 changes: 2 additions & 6 deletions src/categoricalvector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,13 @@ struct CategoricalVector{T, A<:AbstractVector{T}} <: AbstractVector{T}
data::A
end

function CategoricalVector(data::AbstractVector{T}) where T
CategoricalVector{T, typeof(data)}(data)
end
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the default constructor takes care of this. so this caused a redefinition warning.


Base.getindex(v::CategoricalVector, idx::Int) = v.data[idx]
Base.getindex(v::CategoricalVector, idx::AbstractVector) = CategoricalVector(v.data[idx])

Base.length(v::CategoricalVector) = length(v.data)
Base.size(v::CategoricalVector) = size(v.data)
Base.size(v::CategoricalVector, i) = size(v.data, i)
Base.indices(v::CategoricalVector) = indices(v.data)
Base.axes(v::CategoricalVector) = Base.axes(v.data)

axistrait(::Type{CategoricalVector{T,A}}) where {T,A} = Categorical
checkaxis(::CategoricalVector) = nothing
Expand All @@ -65,7 +61,7 @@ checkaxis(::CategoricalVector) = nothing
axisindexes(ax::Axis{S,CategoricalVector{T,A}}, idx) where {T<:Tuple,S,A} = axisindexes(ax, (idx,))

function axisindexes(ax::Axis{S,CategoricalVector{T,A}}, idx::Tuple) where {T<:Tuple,S,A}
collect(filter(ax_idx->_tuple_matches(ax.val[ax_idx], idx), indices(ax.val)...))
collect(filter(ax_idx->_tuple_matches(ax.val[ax_idx], idx), Base.axes(ax.val)...))
end

function _tuple_matches(element::Tuple, idx::Tuple)
Expand Down
63 changes: 33 additions & 30 deletions src/combine.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,24 @@ function equalvalued(X::NTuple)
return allequal
end #equalvalued

sizes(As::T...) where {T<:AxisArray} = tuple(zip(map(a -> map(length, indices(a)), As)...)...)
matchingdims(As::NTuple{N,T}) where {N,T<:AxisArray} = all(equalvalued, sizes(As...))
matchingdimsexcept(As::NTuple{N,T}, n::Int) where {N,T<:AxisArray} = all(equalvalued, sizes(As...)[[1:n-1; n+1:end]])
sizes(As::AxisArray...) = tuple(zip(map(a -> map(length, Base.axes(a)), As)...)...)
matchingdims(As::Tuple{Vararg{AxisArray}}) = all(equalvalued, sizes(As...))
matchingdimsexcept(As::Tuple{Vararg{AxisArray}}, n::Int) = all(equalvalued, sizes(As...)[[1:n-1; n+1:end]])

function Base.cat(n::Integer, As::AxisArray{T}...) where T
Base.cat(As::AxisArray{T}...; dims) where {T} = _cat(dims, As...)
_cat(::Val{n}, As...) where {n} = _cat(n, As...)

@inline function _cat(n::Integer, As...)
if n <= ndims(As[1])
matchingdimsexcept(As, n) || error("All non-concatenated axes must be identically-valued")
newaxis = Axis{axisnames(As[1])[n]}(vcat(map(A -> A.axes[n].val, As)...))
checkaxis(newaxis)
return AxisArray(cat(n, map(A->A.data, As)...), (As[1].axes[1:n-1]..., newaxis, As[1].axes[n+1:end]...))
return AxisArray(cat(map(A->A.data, As)..., dims=n), (As[1].axes[1:n-1]..., newaxis, As[1].axes[n+1:end]...))
else
matchingdims(As) || error("All axes must be identically-valued")
return AxisArray(cat(n, map(A->A.data, As)...), As[1].axes)
return AxisArray(cat(map(A->A.data, As)..., dims=n), As[1].axes)
end #if
end #Base.cat
end

function axismerge(method::Symbol, axes::Axis{name,T}...) where {name,T}

Expand Down Expand Up @@ -122,7 +125,7 @@ Combines AxisArrays with matching axis names into a single AxisArray. Unlike `me
If an array value in the output array is not defined in any of the input arrays (i.e. in the case of a left, right, or outer join), it takes the value of the optional `fillvalue` keyword argument (default zero).
"""
function Base.join(As::AxisArray{T,N,D,Ax}...; fillvalue::T=zero(T),
newaxis::Axis=_nextaxistype(As[1].axes)(1:length(As)),
newaxis::Axis=_default_axis(1:length(As), ndims(As[1])+1),
method::Symbol=:outer) where {T,N,D,Ax}

prejoin_resultaxes = map(as -> axismerge(method, as...), map(tuple, axes.(As)...))
Expand All @@ -141,7 +144,7 @@ function Base.join(As::AxisArray{T,N,D,Ax}...; fillvalue::T=zero(T),
end #join

function _collapse_array_axes(array_name, array_axes...)
((array_name, (idx isa Tuple ? idx : (idx,))...) for idx in product((Ax.val for Ax in array_axes)...))
((array_name, (idx isa Tuple ? idx : (idx,))...) for idx in Iterators.product((Ax.val for Ax in array_axes)...))
end

function _collapse_axes(array_names, array_axes)
Expand All @@ -150,12 +153,12 @@ function _collapse_axes(array_names, array_axes)
end))
end

function _splitall(::Type{Val{N}}, As...) where N
tuple((Base.IteratorsMD.split(A, Val{N}) for A in As)...)
function _splitall(::Val{N}, As...) where N
tuple((Base.IteratorsMD.split(A, Val(N)) for A in As)...)
end

function _reshapeall(::Type{Val{N}}, As...) where N
tuple((reshape(A, Val{N}) for A in As)...)
function _reshapeall(::Val{N}, As...) where N
tuple((reshape(A, Val(N)) for A in As)...)
end

function _check_common_axes(common_axis_tuple)
Expand All @@ -174,36 +177,36 @@ function _collapsed_axis_eltype(LType, trailing_axes)
return typejoin(eltypes...)
end

function collapse(::Type{Val{N}}, As::Vararg{AxisArray, AN}) where {N, AN}
collapse(Val{N}, ntuple(identity, Val{AN}), As...)
function collapse(::Val{N}, As::Vararg{AxisArray, AN}) where {N, AN}
collapse(Val(N), ntuple(identity, AN), As...)
end

function collapse(::Type{Val{N}}, ::Type{NewArrayType}, As::Vararg{AxisArray, AN}) where {N, AN, NewArrayType<:AbstractArray}
collapse(Val{N}, NewArrayType, ntuple(identity, Val{AN}), As...)
function collapse(::Val{N}, ::Type{NewArrayType}, As::Vararg{AxisArray, AN}) where {N, AN, NewArrayType<:AbstractArray}
collapse(Val(N), NewArrayType, ntuple(identity, AN), As...)
end

@generated function collapse(::Type{Val{N}}, labels::NTuple{AN, LType}, As::Vararg{AxisArray, AN}) where {N, AN, LType}
@generated function collapse(::Val{N}, labels::NTuple{AN, LType}, As::Vararg{AxisArray, AN}) where {N, AN, LType}
collapsed_dim_int = Int(N) + 1
new_eltype = Base.promote_eltype(As...)

quote
collapse(Val{N}, Array{$new_eltype, $collapsed_dim_int}, labels, As...)
collapse(Val(N), Array{$new_eltype, $collapsed_dim_int}, labels, As...)
end
end

"""
collapse(::Type{Val{N}}, As::AxisArray...) -> AxisArray
collapse(::Type{Val{N}}, labels::Tuple, As::AxisArray...) -> AxisArray
collapse(::Type{Val{N}}, ::Type{NewArrayType}, As::AxisArray...) -> AxisArray
collapse(::Type{Val{N}}, ::Type{NewArrayType}, labels::Tuple, As::AxisArray...) -> AxisArray
collapse(::Val{N}, As::AxisArray...) -> AxisArray
collapse(::Val{N}, labels::Tuple, As::AxisArray...) -> AxisArray
collapse(::Val{N}, ::Type{NewArrayType}, As::AxisArray...) -> AxisArray
collapse(::Val{N}, ::Type{NewArrayType}, labels::Tuple, As::AxisArray...) -> AxisArray

Collapses `AxisArray`s with `N` equal leading axes into a single `AxisArray`.
All additional axes in any of the arrays are collapsed into a single additional
axis of type `Axis{:collapsed, CategoricalVector{Tuple}}`.

### Arguments

* `::Type{Val{N}}`: the greatest common dimension to share between all input
* `::Val{N}`: the greatest common dimension to share between all input
arrays. The remaining axes are collapsed. All `N` axes must be common
to each input array, at the same dimension. Values from `0` up to the
minimum number of dimensions across all input arrays are allowed.
Expand Down Expand Up @@ -247,7 +250,7 @@ And data, a 10×2 Array{Float64,2}:
0.650277 0.135061
0.688773 0.513845

julia> collapsed = collapse(Val{1}, (:price, :size), price_data, size_data)
julia> collapsed = collapse(Val(1), (:price, :size), price_data, size_data)
2-dimensional AxisArray{Float64,2,...} with axes:
:time, 2016-01-01:1 day:2016-01-10
:collapsed, Tuple{Symbol,Vararg{Symbol,N} where N}[(:price,), (:size, :area), (:size, :volume)]
Expand All @@ -268,7 +271,7 @@ true
```

"""
@generated function collapse(::Type{Val{N}},
@generated function collapse(::Val{N},
::Type{NewArrayType},
labels::NTuple{AN, LType},
As::Vararg{AxisArray, AN}) where {N, AN, LType, NewArrayType<:AbstractArray}
Expand All @@ -285,10 +288,10 @@ true
))
end

collapsed_dim = Val{N + 1}
collapsed_dim = Val(N + 1)
collapsed_dim_int = Int(N) + 1

common_axes, trailing_axes = zip(_splitall(Val{N}, axisparams.(As)...)...)
common_axes, trailing_axes = zip(_splitall(Val(N), axisparams.(As)...)...)

foreach(_check_common_axes, zip(common_axes...))

Expand All @@ -300,7 +303,7 @@ true
new_eltype = Base.promote_eltype(As...)

quote
common_axes, trailing_axes = zip(_splitall(Val{N}, axes.(As)...)...)
common_axes, trailing_axes = zip(_splitall(Val(N), axes.(As)...)...)

for common_axis_tuple in zip(common_axes...)
if !isempty(common_axis_tuple)
Expand All @@ -316,7 +319,7 @@ true
end
end

array_data = cat($collapsed_dim, _reshapeall($collapsed_dim, As...)...)
array_data = cat(_reshapeall($collapsed_dim, As...)..., dims=$collapsed_dim)

axis_array_type = AxisArray{
$new_eltype,
Expand Down
Loading