From a672abbda8616def0ece0040e6749f07cf5bfe8f Mon Sep 17 00:00:00 2001
From: Peter Deffebach
Date: Tue, 5 Oct 2021 07:07:18 -0400
Subject: [PATCH] initial commit
---
docs/src/api.md | 1 +
docs/src/index.md | 17 +++++++++++++++-
src/ShiftedArrays.jl | 1 +
src/lag.jl | 46 ++++++++++++++++++++++++++++++++++++++++++++
test/runtests.jl | 4 ++++
5 files changed, 68 insertions(+), 1 deletion(-)
diff --git a/docs/src/api.md b/docs/src/api.md
index 0ce5e97..e485a53 100644
--- a/docs/src/api.md
+++ b/docs/src/api.md
@@ -15,6 +15,7 @@ CircShiftedVector
lag
lead
ShiftedArrays.circshift
+ShiftedArrays.diff
```
## FFT shifts
diff --git a/docs/src/index.md b/docs/src/index.md
index 2245371..c598dbd 100644
--- a/docs/src/index.md
+++ b/docs/src/index.md
@@ -87,7 +87,9 @@ julia> ShiftedArray([1.2, 3.1, 4.5], 1, default = NaN)[-2:3]
## Shifting the data
-Using the `ShiftedArray` type, this package provides two operations for lazily shifting vectors: `lag` and `lead`.
+Using the `ShiftedArray` type, this package provides two operations for lazily shifting arrays: `lag` and `lead`. It also provides
+the function `ShiftedArrays.diff` for calculating the differences
+between elements in arrays.
```julia
julia> v = [1, 3, 5, 4];
@@ -127,6 +129,19 @@ julia> lead(v)
missing
```
+`diff` is an analogue for `v .- lag(v)`
+
+```julia
+julia> v = [1, 3, 5, 4];
+
+julia> ShiftedArrays.diff(v)
+4-element Vector{Union{Missing, Int64}}:
+ missing
+ 2
+ 2
+ -1
+```
+
## Shifting the data circularly
Julia Base provides a function `circshift` to shift the data circularly. However this function
diff --git a/src/ShiftedArrays.jl b/src/ShiftedArrays.jl
index a97c814..6f9022a 100644
--- a/src/ShiftedArrays.jl
+++ b/src/ShiftedArrays.jl
@@ -4,6 +4,7 @@ import Base: checkbounds, getindex, setindex!, parent, size
export ShiftedArray, ShiftedVector, shifts, default
export CircShiftedArray, CircShiftedVector
export lag, lead
+# ShiftedArrays.diff unexported due to collision
include("shiftedarray.jl")
include("circshiftedarray.jl")
diff --git a/src/lag.jl b/src/lag.jl
index b9aa558..6c2e96a 100644
--- a/src/lag.jl
+++ b/src/lag.jl
@@ -97,3 +97,49 @@ julia> s = lead(v, (0, 2))
```
"""
lead(v::AbstractArray, n = 1; default = missing) = ShiftedArray(v, map(-, n); default = default)
+
+
+"""
+ ShiftedArrays.diff(v::AbstractArray, n = 1; default = missing)
+
+Return a freshly allocated array of the differences between elements
+in the array. 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.
+`default` specifies a default value when you are out of bounds.
+
+## Examples
+
+```jldoctest diff
+julia> v = [1, 3, 5, 4];
+
+julia> ShiftedArrays.diff(v)
+4-element Vector{Union{Missing, Int64}}:
+ missing
+ 2
+ 2
+ -1
+
+julia> w = 1:2:9
+1:2:9
+
+julia> s = ShiftedArrays.diff(w, 2)
+5-element Vector{Union{Missing, Int64}}:
+ missing
+ missing
+ 4
+ 4
+ 4
+
+julia> v = reshape(1:16, 4, 4);
+
+julia> s = ShiftedArrays.diff(v, (0, 2))
+4×4 Matrix{Union{Missing, Int64}}:
+ missing missing 8 8
+ missing missing 8 8
+ missing missing 8 8
+ missing missing 8 8
+"""
+function diff(v::AbstractArray, n = 1; default = missing)
+ l = lag(v, n; default = default)
+ v .- l
+end
diff --git a/test/runtests.jl b/test/runtests.jl
index 2155778..b1eb455 100644
--- a/test/runtests.jl
+++ b/test/runtests.jl
@@ -126,9 +126,13 @@ end
diff = v .- lag(v)
@test isequal(diff, [missing, 2, 5, 4])
+ @test isequal(diff, ShiftedArrays.diff(v))
+
diff2 = v .- lag(v, 2)
@test isequal(diff2, [missing, missing, 7, 9])
+ @test isequal(diff2, ShiftedArrays.diff(v))
+
@test all(lag(v, 2, default = -100) .== coalesce.(lag(v, 2), -100))
diff = v .- lead(v)