Is there diff() method for other operations?

For example:

``````a = [ 2 , 4 , 8 , 16 , 32 ]

diff(a)
=> [ 2 , 4 , 8 , 16 ]
``````

How do you do this for other operations? This might include something like:

``````a = [ 2 , 4 , 8 , 16 , 32 ]

average(a)
=>  [ 3 , 6 , 12 , 24 ]
``````

// for vectors this always reduces the length by one

1 Like

To evaluate `f(x,y)` for each two consecutive elements of `a` you can do

``````f.(@view(a[1:end-1]), @view(a[2:end]))
``````
2 Likes

Alternatively, you could define a generic `consecutive` function

``````function consecutive(f, A::AbstractVector)
[ f(A[i+1], A[i]) for i = 1:length(A)-1 ]
end

a = [ 2 , 4 , 8 , 16 , 32 ]
consecutive(-, a)    # diff
consecutive(+, a)
consecutive(max, a)
consecutive((x,y)->(x+y)/2, a)    #average
``````
3 Likes

Weâ€™ve talked about this some on the GitHub issue tracker: check out https://github.com/JuliaLang/julia/issues/26361. There wasnâ€™t enough of a consensus or drive to actually implement any of the proposed options.

1 Like

This package was created to solve that, and similar, problems

1 Like
``````using IterTools, Statistics
a = 2 .^ (1:5)
map(xs -> middle(xs...), partition(a, 2, 1))
``````
1 Like

Note that the impetus for having such a function â€śbuilt-inâ€ť in Julia is pretty low because writing an explicit comprehension or loop is easy and fast, and the impulse to use a `consecutive(+, a)` largely arises in Matlab-style vectorized code that is unnecessary (and usually awkward and suboptimal) in Julia.

Another generalization of this concept would be a convolution of a long sequence with a short sequence (in this case convolving `A` with `[1,1]`, while `diff` corresponds to convolving with `[1,-1]`). This is nontrivial to implement extremely efficient code for in the general case of a length-`m` filter, so a mature library is helpful. Packages for this sort of thing include `LocalFilters.jl` and `ImageFiltering.jl`.

3 Likes