Sum elements of an array over a given dimension

Viewed 4964

I am quite new to Julia and learning the stuff by doing some projects.

I am stuck at at part of summing all matrix array by element.

I nave 2 * 2 * 1000 3-dimensional array. Basically, its about find the average variance-covariance matrix of 1000 samples. It iterates over the 1 to 1000.

I tried to use the Sum command but it gave me scalar. I need [2,2,1] + [2,2,2] + [2,2,3] + ... [2,2,100] = (2 by 2 matrix)

Is there easy way without using loop?

1 Answers

As has already been pointed out in the comments, if you have a 3-dimensional array,

julia> x = rand(2,2,1000);

you can sum over any dimension by using (taken from ?sum)

sum(A::AbstractArray; dims)

Sum elements of an array over the given dimensions.

In your case,

julia> result = sum(x, dims=3);

Note, however, that the result will still have 3 dimensions, as can be checked by ndims or by checking the type with typeof:

julia> ndims(result)
3

julia> typeof(result)
Array{Float64,3}

The reason for this behavior is type stability. The third dimension, which we summed over, will be a singleton dimension,

julia> size(result)
(2, 2, 1)

which can be dropped to give the desired 2x2 matrix result

julia> dropdims(result, dims=3)
2×2 Array{Float64,2}:
 510.444  503.893
 489.592  480.065

In total, dropdims(sum(x, dims=3), dims=3).

Remark (update)

Loops are fast in Julia. So if it's not just for convenience you can get the result faster by using a loop implementation, e.g.

julia> function f(x::AbstractArray{<:Number, 3})
           nrows, ncols, n = size(x)
           result = zeros(eltype(x), nrows, ncols)
           for k in 1:n
               for j in 1:ncols
                   for i in 1:nrows
                       result[i,j] += x[i,j,k]
                   end
               end
           end
           result
       end
f (generic function with 1 method)

julia> @btime dropdims(sum($x, dims=3), dims=3);
  7.034 μs (19 allocations: 592 bytes)

julia> @btime f($x);
  5.205 μs (1 allocation: 112 bytes)
Related