Reputation: 223
I have an 2D array which I want to modify so as to sum a given element in a row with all the elements before it, so for example, if I have an array:
[1 2; 3 6; 4 7; 4 8]
I want to be able to transform it to
[1 2; 4 8; 8 15; 12 23]
I can do so using the following snippet in julia:
for i in 1:10,
for k in 2:size(d,1),
d([k,i] += d[k-1,i)];
end
end
But I assume there must be a more efficient way to do this?
Upvotes: 6
Views: 2790
Reputation: 3474
As per @tholy's comment, the awesome thing about julia is that built-in functions aren't special and aren't magically faster than user-defined ones. They are both fast. I modified your function and I got it to perform about the same as the built-in cumsum
:
function testA!(arr)
@inbounds for i in 1:size(arr, 2)
tmp = arr[1, i]
for k in 2:size(arr,1)
tmp += arr[k, i]
arr[k,i] = tmp
end
end
arr
end
function testB!(arr)
cumsum!(arr, arr)
end
I constructed test arrays:
arr = rand(1:100, 10^5, 10^2)
arr2 = copy(arr)
and I got the following timings:
@time testA!(arr)
0.007645 seconds (4 allocations: 160 bytes)
@time testB!(arr2)
0.007704 seconds (4 allocations: 160 bytes)
which are basically equivalent.
Upvotes: 8
Reputation: 4308
Yes, there is: cumsum
julia> d = [1 2; 3 6; 4 7; 4 8]
4x2 Array{Int64,2}:
1 2
3 6
4 7
4 8
julia> cumsum(d)
4x2 Array{Int64,2}:
1 2
4 8
8 15
12 23
Upvotes: 16