v715
July 10, 2022, 9:23pm
1
I want to return the sum of adjacent elements in an array, ie, a function sumadj
that produces
julia> a = [2, 3, 4]
julia> sumadj(a)
2-element Vector{Int64}:
5
7
diff
computes the difference between adjacent pairs of elements in an array, but I want an analog that computes the sum.
Also looking for a solution that doesn’t use a for
loop because I need it to work on a GPU with CUDA.jl, which doesn’t allow indexing.
jling
July 10, 2022, 9:31pm
2
julia> function adjsum(ary)
ary1 = @view ary[begin:end-1]
ary2 = @view ary[begin+1:end]
ary1 + ary2
end
adjsum (generic function with 1 method)
julia> adjsum([2, 3, 4])
2-element Vector{Int64}:
5
7
1 Like
v715
July 10, 2022, 9:40pm
4
Awesome, thank you! Didn’t know about view
s, cool tip
More compact to write:
@views adjsum(a) = a[begin:end-1] + a[begin+1:end]
Using the @views
macro you can opt-in to views for slices for a whole function at once.
8 Likes
I couldn’t resist:
julia> struct AddOnly{T}
x::T
end
julia> Base.:(-)(x::AddOnly, y::AddOnly) = x.x + y.x
julia> a = AddOnly.([2, 3, 4])
3-element Vector{AddOnly{Int64}}:
AddOnly{Int64}(2)
AddOnly{Int64}(3)
AddOnly{Int64}(4)
julia> diff(a)
2-element Vector{Int64}:
5
7
(note this is a bad idea: defining a method of -
that has a different meaning from that of the overall function is bad practice and can lead to bugs).
1 Like
DNF
July 11, 2022, 12:23pm
7
You could also just write a loop.
jling
July 11, 2022, 12:44pm
8
Did you read the OP? don’t want an explicit loop because they want to use it on CUDA areay
DNF
July 11, 2022, 12:50pm
9
I read it, but that was yesterday, so I forgot.
Taking into account that the addition operation is associative, it might make sense to deal with the more general case of the sum of n adjacent elements.
using IterTools
a = [2, 3, 4]
sumadj(v,n) = sum.(partition(v,n,1))
sumadj(a,2)
1 Like
using DSP
conv(a,[1,1])[2:end-1]
2 Likes