From 37412de50ec714a3a05ca9184100bcd3320fae06 Mon Sep 17 00:00:00 2001 From: piever Date: Tue, 13 Feb 2018 20:19:10 +0000 Subject: [PATCH 1/5] remove kw --- src/circshift.jl | 32 ++++++---------------------- src/circshiftedarray.jl | 34 +++++------------------------ src/lag.jl | 33 +++++++++++++++++++++++------ src/shiftedarray.jl | 47 +++++++++++++++++------------------------ test/runtests.jl | 11 +++++----- 5 files changed, 63 insertions(+), 94 deletions(-) diff --git a/src/circshift.jl b/src/circshift.jl index 5d07e21..0de146b 100644 --- a/src/circshift.jl +++ b/src/circshift.jl @@ -1,15 +1,16 @@ """ - circshift(v::AbstractArray, n::Int = 1; dim = 1) + circshift(v::AbstractArray, n) -Return a `ShiftedArray` object, with underlying data `v`, circularly shifted by `n` steps -along dimension `dim` +Return a `CircShiftedArray` object, with underlying data `v`. The second argument gives the amount +to circularly shift in each dimension. If it is an integer, it is assumed to refer to the +first dimension. # Examples ```jldoctest circshift julia> v = [1, 3, 5, 4]; -julia> ShiftedArrays.circshift(v) +julia> ShiftedArrays.circshift(v, 1) 4-element ShiftedArrays.CircShiftedArray{Int64,1,Array{Int64,1}}: 4 1 @@ -18,27 +19,6 @@ julia> ShiftedArrays.circshift(v) julia> w = reshape(1:16, 4, 4); -julia> ShiftedArrays.circshift(w, -1, dim = 2) -4×4 ShiftedArrays.CircShiftedArray{Int64,2,Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}}}: - 5 9 13 1 - 6 10 14 2 - 7 11 15 3 - 8 12 16 4 -``` -""" -circshift(v::AbstractArray, n::Int = 1; dim = 1) = CircShiftedArray(v, n; dim = dim) - -""" - circshift(v::AbstractArray{T, N}, n::NTuple{N, Int}) where {T, N} - -Return a `ShiftedArray` object, with underlying data `v`, circularly shifted by `n` steps, -where `n` is a `Tuple` denoting the shift in each dimension. - -# Examples - -```jldoctest circshift -julia> w = reshape(1:16, 4, 4); - julia> ShiftedArrays.circshift(w, (1, -1)) 4×4 ShiftedArrays.CircShiftedArray{Int64,2,Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}}}: 8 12 16 4 @@ -47,4 +27,4 @@ julia> ShiftedArrays.circshift(w, (1, -1)) 7 11 15 3 ``` """ -circshift(v::AbstractArray{T, N}, n::NTuple{N, Int}) where {T, N} = CircShiftedArray(v, n) +circshift(v::AbstractArray, n) = CircShiftedArray(v, n) diff --git a/src/circshiftedarray.jl b/src/circshiftedarray.jl index f7a689a..8bef785 100644 --- a/src/circshiftedarray.jl +++ b/src/circshiftedarray.jl @@ -30,33 +30,11 @@ struct CircShiftedArray{T, N, S<:AbstractArray} <: AbstractArray{T, N} shifts::NTuple{N, Int64} end -CircShiftedArray(v::AbstractArray{T, N}, n = Tuple(0 for i in 1:N)) where {T, N} = CircShiftedArray{T, N, typeof(v)}(v, n) +CircShiftedArray(v::AbstractArray{T, N}, n::NTuple{N, Int} = Tuple(0 for i in 1:N)) where {T, N} = + CircShiftedArray{T, N, typeof(v)}(v, n) -""" - CircShiftedArray(parent::AbstractArray, n::Int; dim = 1) - -Auxiliary method to create a `CircShiftedArray` shifted of `n` steps on dimension `dim`. - -# Examples - -```jldoctest circshiftedarray -julia> v = reshape(1:16, 4, 4); - -julia> s = CircShiftedArray(v, 2; dim = 1) -4×4 ShiftedArrays.CircShiftedArray{Int64,2,Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}}}: - 3 7 11 15 - 4 8 12 16 - 1 5 9 13 - 2 6 10 14 - -julia> shifts(s) -(2, 0) -``` -""" -function CircShiftedArray(v::AbstractArray{T, N}, n::Int; dim = 1) where {T, N} - tup = Tuple(i == dim ? n : 0 for i in 1:N) - CircShiftedArray(v, tup) -end +CircShiftedArray(v::AbstractArray{T, N}, n) where {T, N} = + CircShiftedArray(v, _padded_tuple(n, N)) """ CircShiftedVector{T, S<:AbstractArray} @@ -65,9 +43,7 @@ Shorthand for `CircShiftedArray{T, 1, S}`. """ const CircShiftedVector{T, S<:AbstractArray} = CircShiftedArray{T, 1, S} -CircShiftedVector(v::AbstractVector{T}, n = (0,)) where {T} = CircShiftedArray(v, n) -CircShiftedVector(v::AbstractVector{T}, n::Int; dim = 1) where {T} = - CircShiftedArray(v, n::Int; dim = 1) +CircShiftedVector(v::AbstractVector, n = (0,)) = CircShiftedArray(v, n) Base.size(s::CircShiftedArray) = Base.size(parent(s)) diff --git a/src/lag.jl b/src/lag.jl index 1f4a83c..6cf5dd6 100644 --- a/src/lag.jl +++ b/src/lag.jl @@ -1,8 +1,8 @@ """ - lag(v::AbstractArray, n = 1; dim = 1) + lag(v::AbstractArray, n = 1) -Return a `ShiftedArray` object, with underlying data `v`, shifted by `n` steps -along dimension `dim` +Return a `ShiftedArray` object, with underlying data `v`. The second argument gives the amount +to shift in each dimension. If it is an integer, it is assumed to refer to the first dimension. # Examples @@ -34,14 +34,26 @@ julia> copy(s) 1 3 5 + +julia> v = reshape(1:16, 4, 4); + +julia> s = lag(v, (0, 2)) +4×4 ShiftedArrays.ShiftedArray{Int64,2,Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}}}: + missing missing 1 5 + missing missing 2 6 + missing missing 3 7 + missing missing 4 8 ``` """ -lag(v::AbstractArray, n = 1; dim = 1) = ShiftedArray(v, n; dim = dim) +lag(v::AbstractArray, n = 1) = ShiftedArray(v, n) """ lead(v::AbstractArray, n = 1; dim = 1) -Return a `ShiftedArray` object, with underlying data `v`, shifted by `-n` steps. +Return a `ShiftedArray` object, with underlying data `v`. The second argument gives the amount +to shift negatively in each dimension. If it is an integer, it is assumed to refer +to the first dimension. + # Examples @@ -73,6 +85,15 @@ julia> copy(s) 9 missing missing + +julia> v = reshape(1:16, 4, 4); + +julia> s = lag(v, (0, 2)) +4×4 ShiftedArrays.ShiftedArray{Int64,2,Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}}}: + missing missing 1 5 + missing missing 2 6 + missing missing 3 7 + missing missing 4 8 ``` """ -lead(v::AbstractArray, n = 1; dim = 1) = ShiftedArray(v, -n; dim = dim) +lead(v::AbstractArray, n = 1) = ShiftedArray(v, map(-, n)) diff --git a/src/shiftedarray.jl b/src/shiftedarray.jl index 1a0670a..481a06e 100644 --- a/src/shiftedarray.jl +++ b/src/shiftedarray.jl @@ -1,3 +1,6 @@ +_padded_tuple(n, N) = Tuple(i <= length(n) ? n[i] : 0 for i in 1:N) +_padded_tuple(n::Int, N) = _padded_tuple((n,), N) + """ ShiftedArray(parent::AbstractArray, shifts) @@ -34,41 +37,31 @@ julia> copy(s) 1 3 5 -``` -""" -struct ShiftedArray{T, N, S<:AbstractArray} <: AbstractArray{Union{T, Missing}, N} - parent::S - shifts::NTuple{N, Int64} -end - -ShiftedArray(v::AbstractArray{T, N}, n = Tuple(0 for i in 1:N)) where {T, N} = ShiftedArray{T, N, typeof(v)}(v, n) - -""" - ShiftedArray(parent::AbstractArray, n::Int; dim = 1) -Auxiliary method to create a `ShiftedArray` shifted of `n` steps on dimension `dim`. - -# Examples - -```jldoctest shiftedarray julia> v = reshape(1:16, 4, 4); -julia> s = ShiftedArray(v, 2; dim = 1) +julia> s = ShiftedArray(v, (0, 2)) 4×4 ShiftedArrays.ShiftedArray{Int64,2,Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}}}: - missing missing missing missing - missing missing missing missing - 1 5 9 13 - 2 6 10 14 + missing missing 1 5 + missing missing 2 6 + missing missing 3 7 + missing missing 4 8 julia> shifts(s) -(2, 0) +(0, 2) ``` """ -function ShiftedArray(v::AbstractArray{T, N}, n::Int; dim = 1) where {T, N} - tup = Tuple(i == dim ? n : 0 for i in 1:N) - ShiftedArray(v, tup) +struct ShiftedArray{T, N, S<:AbstractArray} <: AbstractArray{Union{T, Missing}, N} + parent::S + shifts::NTuple{N, Int64} end +ShiftedArray(v::AbstractArray{T, N}, n::NTuple{N, Int} = Tuple(0 for i in 1:N)) where {T, N} = + ShiftedArray{T, N, typeof(v)}(v, n) + +ShiftedArray(v::AbstractArray{T, N}, n) where {T, N} = + ShiftedArray(v, _padded_tuple(n, N)) + """ ShiftedVector{T, S<:AbstractArray} @@ -76,9 +69,7 @@ Shorthand for `ShiftedArray{T, 1, S}`. """ const ShiftedVector{T, S<:AbstractArray} = ShiftedArray{T, 1, S} -ShiftedVector(v::AbstractVector{T}, n = (0,)) where {T} = ShiftedArray(v, n) -ShiftedVector(v::AbstractVector{T}, n::Int; dim = 1) where {T} = - ShiftedArray(v, n::Int; dim = 1) +ShiftedVector(v::AbstractVector, n = (0,)) = ShiftedArray(v, n) Base.size(s::ShiftedArray) = Base.size(parent(s)) diff --git a/test/runtests.jl b/test/runtests.jl index d976cfe..a844dad 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,7 +4,7 @@ using Compat.Test @testset "ShiftedVector" begin v = [1, 3, 5, 4] sv = ShiftedVector(v, -1) - @test isequal(sv, ShiftedVector(v, -1; dim = 1)) + @test isequal(sv, ShiftedVector(v, -1)) @test isequal(sv, ShiftedVector(v, (-1,))) @test length(sv) == 4 @test sv[2] == 5 @@ -23,7 +23,7 @@ end @test ismissing(sv[3,3]) @test shifts(sv) == (-2,0) @test isequal(sv, ShiftedArray(v, -2)) - @test isequal(ShiftedArray(v, (0, 2)), ShiftedArray(v, 2; dim = 2)) + @test isequal(ShiftedArray(v, (2,)), ShiftedArray(v, 2)) s = ShiftedArray(v, (0, -2)) @test isequal(collect(s), [ 9 13 missing missing; 10 14 missing missing; @@ -34,7 +34,7 @@ end @testset "CircShiftedVector" begin v = [1, 3, 5, 4] sv = CircShiftedVector(v, -1) - @test isequal(sv, CircShiftedVector(v, -1; dim = 1)) + @test isequal(sv, CircShiftedVector(v, -1)) @test isequal(sv, CircShiftedVector(v, (-1,))) @test length(sv) == 4 @test sv[2] == 5 @@ -55,7 +55,7 @@ end @test sv[1, 3] == 11 @test shifts(sv) == (-2,0) @test isequal(sv, CircShiftedArray(v, -2)) - @test isequal(CircShiftedArray(v, (0, 2)), CircShiftedArray(v, 2; dim = 2)) + @test isequal(CircShiftedArray(v, 2), CircShiftedArray(v, (2,))) s = CircShiftedArray(v, (0, 2)) @test isequal(collect(s), [ 9 13 1 5; 10 14 2 6; @@ -66,7 +66,8 @@ end @testset "circshift" begin v = reshape(1:16, 4, 4) @test all(circshift(v, (1, -1)) .== ShiftedArrays.circshift(v, (1, -1))) - @test all(circshift(v, (0, -1)) .== ShiftedArrays.circshift(v, -1, dim = 2)) + @test all(circshift(v, (1,)) .== ShiftedArrays.circshift(v, (1,))) + @test all(circshift(v, 3) .== ShiftedArrays.circshift(v, 3)) end @testset "laglead" begin From 7c1a10ede2a00e2509cb292e808c04e5db352635 Mon Sep 17 00:00:00 2001 From: piever Date: Tue, 13 Feb 2018 20:25:47 +0000 Subject: [PATCH 2/5] docs --- README.md | 9 +++++++-- deps/build.jl | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2d67c0d..2aece45 100644 --- a/README.md +++ b/README.md @@ -53,10 +53,15 @@ julia> copy(s) 2 6 10 14 ``` -If you only need to shift in one dimension, you can use the commodity method: +If you pass an integer, it will shift in the first dimension: ```julia -ShiftedArray(v, n; dim = 1) +julia> ShiftedArray(v, 1) +4×4 ShiftedArrays.ShiftedArray{Int64,2,Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}}}: + missing missing missing missing + 1 5 9 13 + 2 6 10 14 + 3 7 11 15 ``` ## Shifting the data diff --git a/deps/build.jl b/deps/build.jl index db28d2d..bc05afd 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -4,6 +4,9 @@ if !isfile(joinpath(@__DIR__, "already_showed")) The shift index convention has changed to be in agreement with Julia's function `circshift`. Now a positive shift shits to the right, i.e. `ShiftedVector(v, 1)[2] == v[2-1] == v[1]`. Similarly `copy(CircShiftedVector(v, 1)) == circshift(v, 1)`. + In agreement with the Base function `circshift`, the `dim` keyword argument is no longer + supported. If the shift vector is too short (or if you input an integer) only the first + few dimensions will be shifted. For more details see https://github.com/piever/ShiftedArrays.jl """) touch("already_showed") From 1f92d2212e22cf078758b55328b82ea0f09eafca Mon Sep 17 00:00:00 2001 From: piever Date: Tue, 13 Feb 2018 20:27:25 +0000 Subject: [PATCH 3/5] docstring --- src/lag.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lag.jl b/src/lag.jl index 6cf5dd6..d9f9c52 100644 --- a/src/lag.jl +++ b/src/lag.jl @@ -48,7 +48,7 @@ julia> s = lag(v, (0, 2)) lag(v::AbstractArray, n = 1) = ShiftedArray(v, n) """ - lead(v::AbstractArray, n = 1; dim = 1) + lead(v::AbstractArray, n = 1) Return a `ShiftedArray` object, with underlying data `v`. The second argument gives the amount to shift negatively in each dimension. If it is an integer, it is assumed to refer From 09ca7b6bf7bc42a719829a423e4b300498fd1d45 Mon Sep 17 00:00:00 2001 From: piever Date: Tue, 13 Feb 2018 20:57:09 +0000 Subject: [PATCH 4/5] clean tests --- test/runtests.jl | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index a844dad..63106cd 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,14 +4,12 @@ using Compat.Test @testset "ShiftedVector" begin v = [1, 3, 5, 4] sv = ShiftedVector(v, -1) - @test isequal(sv, ShiftedVector(v, -1)) @test isequal(sv, ShiftedVector(v, (-1,))) @test length(sv) == 4 - @test sv[2] == 5 + @test all(sv[1:3] .== [3, 5, 4]) @test ismissing(sv[4]) diff = v .- sv - @test diff[1:3] == [-2, -2, 1] - @test ismissing(diff[4]) + @test isequal(diff, [-2, -2, 1, missing]) @test shifts(sv) == (-1,) end @@ -34,11 +32,9 @@ end @testset "CircShiftedVector" begin v = [1, 3, 5, 4] sv = CircShiftedVector(v, -1) - @test isequal(sv, CircShiftedVector(v, -1)) @test isequal(sv, CircShiftedVector(v, (-1,))) @test length(sv) == 4 - @test sv[2] == 5 - @test sv[4] == 1 + @test all(sv .== [3, 5, 4, 1]) diff = v .- sv @test diff == [-2, -2, 1, 3] @test shifts(sv) == (-1,) @@ -46,6 +42,9 @@ end diff = v .- sv2 @test copy(sv2) == [4, 1, 3, 5] @test all(CircShiftedVector(v, 1) .== circshift(v,1)) + sv[2] = 0 + @test collect(sv) == [3, 0, 4, 1] + @test v == [1, 3, 0, 4] end @testset "CircShiftedArray" begin @@ -73,20 +72,16 @@ end @testset "laglead" begin v = [1, 3, 8, 12] diff = v .- lag(v) - @test diff[2:4] == [2, 5, 4] - @test ismissing(diff[1]) + @test isequal(diff, [missing, 2, 5, 4]) diff2 = v .- lag(v, 2) - @test diff2[3:4] == [7, 9] - @test ismissing(diff2[1]) && ismissing(diff2[2]) + @test isequal(diff2, [missing, missing, 7, 9]) diff = v .- lead(v) - @test diff[1:3] == [-2, -5, -4] - @test ismissing(diff[4]) + @test isequal(diff, [-2, -5, -4, missing]) diff2 = v .- lead(v, 2) - @test diff2[1:2] == [-7, -9] - @test ismissing(diff2[3]) && ismissing(diff2[4]) + @test isequal(diff2, [-7, -9, missing, missing]) end @testset "reduce" begin From ac4751b5b66f73d0455261882e5f15a57323f3d4 Mon Sep 17 00:00:00 2001 From: piever Date: Thu, 15 Feb 2018 20:06:17 +0000 Subject: [PATCH 5/5] added news --- NEWS.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 NEWS.md diff --git a/NEWS.md b/NEWS.md new file mode 100644 index 0000000..6a63677 --- /dev/null +++ b/NEWS.md @@ -0,0 +1,11 @@ +## ShiftedArrays 0.3 release notes + +### Breaking changes + +- Removed the `dim` keyword: instead of e.g. `lag(v, 3, dim = 2)` write `lag(v, (0, 3))` (in agreement with `circshift` from Julia Base) +- Changed direction of shifting for `ShiftedArray` and `CircShiftedArray` constructors. For example `CircShiftedArray(v, n)` with a positive `n` shifts to the right (in agreement with `circshift(v, n)` from Julia Base). + +## New features + +- `CircShiftedArray` type to shift arrays circularly. +- A lazy version of `circshift`: `ShiftedArray.circshift`