# ShiftedArrays

Implementation of shifted arrays.

## Shifted Arrays

A `ShiftedArray`

is a lazy view of an Array, shifted on some or all of his indexing dimensions by some constant values.

```
julia> v = reshape(1:16, 4, 4)
4×4 reshape(::UnitRange{Int64}, 4, 4) with eltype Int64:
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
julia> s = ShiftedArray(v, (2, 0))
4×4 ShiftedArray{Int64, Missing, 2, Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}}}:
missing missing missing missing
missing missing missing missing
1 5 9 13
2 6 10 14
```

The parent Array as well as the amount of shifting can be recovered with `parent`

and `shifts`

respectively.

```
julia> parent(s)
4×4 reshape(::UnitRange{Int64}, 4, 4) with eltype Int64:
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
julia> shifts(s)
(2, 0)
```

`shifts`

returns a `Tuple`

, where the n-th element corresponds to the shift on the n-th dimension of the parent `Array`

.

Use `copy`

to collect the shifted data into an `Array`

:

```
julia> copy(s)
4×4 Matrix{Union{Missing, Int64}}:
missing missing missing missing
missing missing missing missing
1 5 9 13
2 6 10 14
```

If you pass an integer, it will shift in the first dimension:

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

A custom default value (other than `missing`

) can be provided with the `default`

keyword:

```
julia> ShiftedArray([1.2, 3.1, 4.5], 1, default = NaN)
3-element ShiftedVector{Float64, Float64, Vector{Float64}}:
NaN
1.2
3.1
```

### Out of bound indexes

Accessing indexes outside the `ShiftedArray`

give a `BoundsError`

, even if the shifted index would have been valid in the parent array.

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

## Shifting the data

Using the `ShiftedArray`

type, this package provides two operations for lazily shifting vectors: `lag`

and `lead`

.

```
julia> v = [1, 3, 5, 4];
julia> ShiftedArrays.lag(v)
4-element ShiftedVector{Int64, Missing, Vector{Int64}}:
missing
1
3
5
julia> v .- ShiftedArrays.lag(v) # compute difference from previous element without unnecessary allocations
4-element Vector{Union{Missing, Int64}}:
missing
2
2
-1
julia> s = ShiftedArrays.lag(v, 2) # shift by more than one element
4-element ShiftedVector{Int64, Missing, Vector{Int64}}:
missing
missing
1
3
```

`lead`

is the analogous of `lag`

but shifts in the opposite direction:

```
julia> v = [1, 3, 5, 4];
julia> ShiftedArrays.lead(v)
4-element ShiftedVector{Int64, Missing, Vector{Int64}}:
3
5
4
missing
```

## Shifting the data circularly

Julia Base provides a function `circshift`

to shift the data circularly. However this function creates a copy of the vector, which may be unnecessary if the rotated vector is to be used only once. This package provides the `CircShiftedArray`

type, which is a lazy view of an array shifted on some or all of his indexing dimensions by some constant values.

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{}}}:
8 12 16 4
5 9 13 1
6 10 14 2
7 11 15 3
```

As usual, you can `copy`

the result to have a normal `Array`

:

```
julia> copy(s)
4×4 Matrix{Int64}:
8 12 16 4
5 9 13 1
6 10 14 2
7 11 15 3
```