Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficient way to sum an array of integers in Julia

Tags:

julia

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?

like image 270
cerremony Avatar asked Apr 03 '16 22:04

cerremony


People also ask

How do I add to an array in Julia?

Julia allows adding new elements in an array with the use of push! command. Elements in an array can also be added at a specific index by passing the range of index values in the splice! function.

How do you sum a vector in Julia?

Sum of vector elements can be calculated with the use of Julia's predefined function sum().

How do you sum data in an array?

You can find the sum of all elements in an array by following the approach below: Initialize a variable sum to store the total sum of all elements of the array. Traverse the array and add each element of the array with the sum variable. Finally, return the sum variable.


2 Answers

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
like image 159
rcpinto Avatar answered Oct 19 '22 19:10

rcpinto


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.

like image 39
tlnagy Avatar answered Oct 19 '22 17:10

tlnagy