Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
10d8eb5
reimplemented CircShiftedArrays adding broadcasting support
RainerHeintzmann Apr 17, 2023
9e23396
bug fixes of the rewritten circshiftedarray
RainerHeintzmann Apr 18, 2023
81d5d9f
bug fixes
RainerHeintzmann Apr 18, 2023
a12a950
improvements
RainerHeintzmann Apr 19, 2023
787feb6
removed the specialied version
RainerHeintzmann Apr 19, 2023
1988c5a
added test for @view
RainerHeintzmann Apr 19, 2023
797a031
improved show method
RainerHeintzmann Apr 19, 2023
2c674c9
bug fix in show()
RainerHeintzmann Apr 20, 2023
8de2db6
correction in .&
RainerHeintzmann Apr 20, 2023
139f7c5
increased minimum version to 1.3
RainerHeintzmann Apr 20, 2023
eda9b08
increased min version to 1.5
RainerHeintzmann Apr 20, 2023
8cdc7b8
changes towards broadcasting for both types
RainerHeintzmann Apr 22, 2023
0031596
fixed code and tests
RainerHeintzmann Apr 24, 2023
cc15c38
bug fixes. hooked into reducedim_initarray
RainerHeintzmann Apr 25, 2023
893f99f
not quite working with the broadcasting
RainerHeintzmann Apr 26, 2023
5552b84
before removing R in ShiftedArrayStyle
RainerHeintzmann Apr 27, 2023
ecdd1d5
all tests are running now
RainerHeintzmann Apr 27, 2023
9e1f19b
bug fixed to work with Cuda
RainerHeintzmann Apr 28, 2023
a450787
bug fixes with CuArray type
RainerHeintzmann Apr 29, 2023
a186b6b
added system information
RainerHeintzmann Apr 29, 2023
8c3ea6e
more system details
RainerHeintzmann Apr 29, 2023
6fe5206
added more support for reductions, but fixes
RainerHeintzmann May 1, 2023
892bf97
fixed test
RainerHeintzmann May 1, 2023
b22f4c7
added isapprox implementation
RainerHeintzmann May 4, 2023
2b08383
added reverse support
RainerHeintzmann May 9, 2023
86426c2
fixed docs
RainerHeintzmann May 9, 2023
72634d0
bug fix
RainerHeintzmann May 9, 2023
e3dddef
bug fix
RainerHeintzmann May 9, 2023
5a1d2d2
bug fix
RainerHeintzmann May 9, 2023
18e7493
doc change
RainerHeintzmann May 9, 2023
4f237fe
restricted test
RainerHeintzmann May 9, 2023
d6b8e93
doc updates
RainerHeintzmann May 9, 2023
32149b1
fixed array base type problem
RainerHeintzmann May 17, 2023
00e7047
removed S
RainerHeintzmann May 17, 2023
b4dd2c9
removed S from BroadcastStyle. Ready to merge
RainerHeintzmann May 17, 2023
05a78f4
cleaned up code and fixed docs
RainerHeintzmann May 17, 2023
ef70bc0
minor change
RainerHeintzmann Dec 13, 2023
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
fail-fast: false
matrix:
version:
- '1.0' # Replace this with the minimum Julia version that your package supports. E.g. if your package requires Julia 1.5 or higher, change this to '1.5'.
- '1.5' # Replace this with the minimum Julia version that your package supports. E.g. if your package requires Julia 1.5 or higher, change this to '1.5'.
- '1' # Leave this line unchanged. '1' will automatically expand to the latest stable 1.x release of Julia.
os: [ubuntu-latest, windows-latest, macOS-latest]
arch:
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ repo = "https://github.com/JuliaArrays/ShiftedArrays.jl.git"
version = "2.0.0"

[compat]
julia = "1"
julia = "1.5"

[extras]
AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c"
Expand Down
2 changes: 2 additions & 0 deletions docs/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,6 @@ default
```@docs
ShiftedArrays.padded_tuple
ShiftedArrays.ft_center_diff
ShiftedArrays.materialize_checkerboard!
ShiftedArrays.refine_view
```
20 changes: 10 additions & 10 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ julia> v = reshape(1:16, 4, 4)
4 8 12 16

julia> s = ShiftedArray(v, (2, 0))
4×4 ShiftedArray{Int64, Missing, 2, Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}}}:
4×4 ShiftedArray{Int64, 2, Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}}, Tuple{2, 0}, Missing}:
missing missing missing missing
missing missing missing missing
1 5 9 13
2 6 10 14
2 6 10 14
```

The parent Array as well as the amount of shifting can be recovered with `parent` and `shifts` respectively.
Expand Down Expand Up @@ -53,7 +53,7 @@ If you pass an integer, it will shift in the first dimension:

```julia
julia> ShiftedArray(v, 1)
4×4 ShiftedArray{Int64, Missing, 2, Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}}}:
4×4 ShiftedArray{Int64, 2, Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}}, Tuple{1, 0}, Missing}:
missing missing missing missing
1 5 9 13
2 6 10 14
Expand All @@ -64,7 +64,7 @@ A custom default value (other than `missing`) can be provided with the `default`

```julia
julia> ShiftedArray([1.2, 3.1, 4.5], 1, default = NaN)
3-element ShiftedVector{Float64, Float64, Vector{Float64}}:
3-element ShiftedVector{Float64, Vector{Float64}, Tuple{1}, Val{NaN}}:
NaN
1.2
3.1
Expand All @@ -76,7 +76,7 @@ Accessing indexes outside the `ShiftedArray` give a `BoundsError`, even if the s

```julia
julia> ShiftedArray([1, 2, 3], 1)[4]
ERROR: BoundsError: attempt to access 3-element ShiftedVector{Int64, Missing, Vector{Int64}} at index [4]
ERROR: BoundsError: attempt to access 3-element ShiftedVector{Int64, Vector{Int64}, Tuple{1}, Missing} at index [4]
```

## Shifting the data
Expand All @@ -87,11 +87,11 @@ Using the `ShiftedArray` type, this package provides two operations for lazily s
julia> v = [1, 3, 5, 4];

julia> ShiftedArrays.lag(v)
4-element ShiftedVector{Int64, Missing, Vector{Int64}}:
4-element ShiftedVector{Int64, Vector{Int64}, Tuple{1}, Missing}:
missing
1
3
5
5

julia> v .- ShiftedArrays.lag(v) # compute difference from previous element without unnecessary allocations
4-element Vector{Union{Missing, Int64}}:
Expand All @@ -101,7 +101,7 @@ julia> v .- ShiftedArrays.lag(v) # compute difference from previous element with
-1

julia> s = ShiftedArrays.lag(v, 2) # shift by more than one element
4-element ShiftedVector{Int64, Missing, Vector{Int64}}:
4-element ShiftedVector{Int64, Vector{Int64}, Tuple{2}, Missing}:
missing
missing
1
Expand All @@ -114,7 +114,7 @@ julia> s = ShiftedArrays.lag(v, 2) # shift by more than one element
julia> v = [1, 3, 5, 4];

julia> ShiftedArrays.lead(v)
4-element ShiftedVector{Int64, Missing, Vector{Int64}}:
4-element ShiftedVector{Int64, Vector{Int64}, Tuple{-1}, Missing}:
3
5
4
Expand All @@ -134,7 +134,7 @@ Our implementation of `circshift` relies on them to avoid copying:
julia> w = reshape(1:16, 4, 4);

julia> s = ShiftedArrays.circshift(w, (1, -1))
4×4 CircShiftedArray{Int64, 2, Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}}}:
4×4 CircShiftedArray{Int64, 2, Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}}, Tuple{1, 3}}:
8 12 16 4
5 9 13 1
6 10 14 2
Expand Down
1 change: 1 addition & 0 deletions src/ShiftedArrays.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module ShiftedArrays
import Base: checkbounds, getindex, setindex!, parent, size, axes
export ShiftedArray, ShiftedVector, shifts, default
export CircShiftedArray, CircShiftedVector
export CircShift

include("shiftedarray.jl")
include("circshiftedarray.jl")
Expand Down
4 changes: 2 additions & 2 deletions src/circshift.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ remaining dimensions is assumed to be `0`.
julia> v = [1, 3, 5, 4];

julia> ShiftedArrays.circshift(v, 1)
4-element CircShiftedVector{Int64, Vector{Int64}}:
4-element ShiftedArray{Int64, 1, Vector{Int64}, Tuple{1}, CircShift}:
4
1
3
Expand All @@ -21,7 +21,7 @@ julia> ShiftedArrays.circshift(v, 1)
julia> w = reshape(1:16, 4, 4);

julia> ShiftedArrays.circshift(w, (1, -1))
4×4 CircShiftedArray{Int64, 2, Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}}}:
4×4 CircShiftedArray{Int64, 2, Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}}, Tuple{1, 3}}:
8 12 16 4
5 9 13 1
6 10 14 2
Expand Down
72 changes: 33 additions & 39 deletions src/circshiftedarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

Custom `AbstractArray` object to store an `AbstractArray` `parent` circularly shifted
by `shifts` steps (where `shifts` is a `Tuple` with one `shift` value per dimension of `parent`).
Use `copy` to collect the values of a `CircShiftedArray` into a normal `Array`.
Use `copy` or `collect` to collect the values of a `ShiftedArray` into a normal `Array`.

!!! note
`shift` is modified with a modulo operation and does not store the passed value
Expand All @@ -19,7 +19,7 @@ Use `copy` to collect the values of a `CircShiftedArray` into a normal `Array`.
julia> v = [1, 3, 5, 4];

julia> s = CircShiftedArray(v, (1,))
4-element CircShiftedVector{Int64, Vector{Int64}}:
4-element ShiftedArray{Int64, 1, Vector{Int64}, CircShift}:
4
1
3
Expand All @@ -33,57 +33,51 @@ julia> copy(s)
5
```
"""
struct CircShiftedArray{T, N, S<:AbstractArray} <: AbstractArray{T, N}
parent::S
# the field `shifts` stores the circular shifts modulo the size of the parent array
shifts::NTuple{N, Int}
function CircShiftedArray(p::AbstractArray{T, N}, n = ()) where {T, N}
shifts = map(mod, padded_tuple(p, n), size(p))
return new{T, N, typeof(p)}(p, shifts)
const CircShiftedArray{T, N, A<:AbstractArray} = ShiftedArray{T, N, A, CircShift}
CircShiftedArray(p::AbstractArray, n=()) = ShiftedArray(p, map(mod, padded_tuple(p, n), size(p)); default=CircShift())
function CircShiftedArray(p::ShiftedArray, n=())
ns = map(mod, padded_tuple(p, n) .+ shifts(p), size(p))
if all(ns.==0)
return p.parent
else
return ShiftedArray(p.parent, ns; default=CircShift())
end
end

function CircShiftedArray(c::CircShiftedArray, n = ())
shifts = map(+, ShiftedArrays.shifts(c), padded_tuple(c, n))
return CircShiftedArray(parent(c), shifts)
end

"""
CircShiftedVector{T, S<:AbstractArray}
CircShiftedVector{T, A<:AbstractArray}

Shorthand for `CircShiftedArray{T, 1, S}`.
Shorthand for `CircShiftedArray{T, 1, A}`.
"""
const CircShiftedVector{T, S<:AbstractArray} = CircShiftedArray{T, 1, S}
const CircShiftedVector{T, A<:AbstractArray} = ShiftedVector{T, A, CircShift}

CircShiftedVector(v::AbstractVector, n = ()) = CircShiftedArray(v, n)

size(s::CircShiftedArray) = size(parent(s))
axes(s::CircShiftedArray) = axes(parent(s))
has_circ_type(a::CircShiftedArray) = true

@inline function bringwithin(ind_with_offset::Int, ranges::AbstractUnitRange)
return ifelse(ind_with_offset < first(ranges), ind_with_offset + length(ranges), ind_with_offset)

# mod1 avoids first subtracting one and then adding one
@inline function Base.getindex(csa::CircShiftedArray{T,N,A}, i::Vararg{Int,N}) where {T,N,A}
getindex(csa.parent, (mod1(i[j]-shifts(csa)[j], size(csa.parent, j)) for j in 1:N)...)
end

@inline function getindex(s::CircShiftedArray{T, N}, x::Vararg{Int, N}) where {T, N}
@boundscheck checkbounds(s, x...)
v, ind = parent(s), offset(shifts(s), x)
i = map(bringwithin, ind, axes(s))
return @inbounds v[i...]
@inline function Base.setindex!(csa::CircShiftedArray{T,N,A}, v, i::Int) where {T,N,A}
# @show "si circ"
setindex!(csa.parent, v, i)
end

@inline function setindex!(s::CircShiftedArray{T, N}, el, x::Vararg{Int, N}) where {T, N}
@boundscheck checkbounds(s, x...)
v, ind = parent(s), offset(shifts(s), x)
i = map(bringwithin, ind, axes(s))
@inbounds v[i...] = el
return s
@inline function Base.setindex!(csa::CircShiftedArray{T,N,A}, v, i::Vararg{Int,N}) where {T,N,A}
setindex!(csa.parent, v, (mod1(i[j]-shifts(csa)[j], size(csa.parent, j)) for j in 1:N)...)
csa
end

parent(s::CircShiftedArray) = s.parent
# for speed reasons use the optimized version in Base for actually perfoming the circshift in this case:
Base.collect(csa::CircShiftedArray{T,N,A}) where {T,N,A} = Base.circshift(csa.parent, shifts(csa))

"""
shifts(s::CircShiftedArray)

Return amount by which `s` is shifted compared to `parent(s)`.
"""
shifts(s::CircShiftedArray) = s.shifts
# this is not really fully in place, but the only way to emulate the reverse! function
function Base.reverse!(csa::CircShiftedArray; dims=:)
tmp = Base.reverse(csa.parent; dims=dims)
# keep the old shift but compensate by an appropriate circshift
Base.circshift!(csa.parent, tmp, -2 .* shifts(csa))
return csa
end
12 changes: 6 additions & 6 deletions src/lag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ remaining dimensions is assumed to be `0`.
julia> v = [1, 3, 5, 4];

julia> ShiftedArrays.lag(v)
4-element ShiftedVector{Int64, Missing, Vector{Int64}}:
4-element ShiftedVector{Int64, Vector{Int64}, Missing}:
missing
1
3
Expand All @@ -23,7 +23,7 @@ julia> w = 1:2:9
1:2:9

julia> s = ShiftedArrays.lag(w, 2)
5-element ShiftedVector{Int64, Missing, StepRange{Int64, Int64}}:
5-element ShiftedVector{Int64, StepRange{Int64, Int64}, Missing}:
missing
missing
1
Expand All @@ -41,7 +41,7 @@ julia> copy(s)
julia> v = reshape(1:16, 4, 4);

julia> s = ShiftedArrays.lag(v, (0, 2))
4×4 ShiftedArray{Int64, Missing, 2, Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}}}:
4×4 ShiftedArray{Int64, 2, Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}}, Missing}:
missing missing 1 5
missing missing 2 6
missing missing 3 7
Expand All @@ -67,7 +67,7 @@ remaining dimensions is assumed to be `0`.
julia> v = [1, 3, 5, 4];

julia> ShiftedArrays.lead(v)
4-element ShiftedVector{Int64, Missing, Vector{Int64}}:
4-element ShiftedVector{Int64, Vector{Int64}, Missing}:
3
5
4
Expand All @@ -77,7 +77,7 @@ julia> w = 1:2:9
1:2:9

julia> s = ShiftedArrays.lead(w, 2)
5-element ShiftedVector{Int64, Missing, StepRange{Int64, Int64}}:
5-element ShiftedVector{Int64, StepRange{Int64, Int64}, Missing}:
5
7
9
Expand All @@ -95,7 +95,7 @@ julia> copy(s)
julia> v = reshape(1:16, 4, 4);

julia> s = ShiftedArrays.lead(v, (0, 2))
4×4 ShiftedArray{Int64, Missing, 2, Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}}}:
4×4 ShiftedArray{Int64, 2, Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}}, Missing}:
9 13 missing missing
10 14 missing missing
11 15 missing missing
Expand Down
Loading