Sum rows of a matrix to create new array

Is there a way to sum all elements in a row of a matrix and output a new single column array?

For ex. if I have a matrix:

1 0 1 1
0 0 0 0
0 1 1 0

I want to sum each row to output a new array:

3
0
2

And then I want to use the maximum() function to give me the max value in the array = 3

2 Likes

This is a pretty simple question… The documentation for sum explicitly answers it.

  Sum elements of an array over the given dimensions.

     Examples
    ≡≡≡≡≡≡≡≡≡≡

  julia> A = [1 2; 3 4]
  2×2 Array{Int64,2}:
   1  2
   3  4

  julia> sum(A, 1)
  1×2 Array{Int64,2}:
   4  6

  julia> sum(A, 2)
  2×1 Array{Int64,2}:
   3
   7
6 Likes

In Julia 0.7,

using Random
srand(0)
obj = rand(4, 4)
maximum(sum(obj, dims = 2))
3 Likes

Please note that this does not work in Julia 1.0

**julia>** A = [1 2; 3 4]

2×2 Array{Int64,2}:
1 2
3 4

**julia>** sum(A, 1)
**ERROR:** MethodError: objects of type Array{Int64,2} are not callable
Use square brackets [] for indexing an Array.

Stacktrace:
  [1] **mapreduce_first(** ::Array{Int64,2}, ::Function, ::Int64 **)** at **./reduce.jl:295**
  [2] **mapreduce(** ::Array{Int64,2}, ::Function, ::Int64 **)** at **./reduce.jl:322**
  [3] **sum(** ::Array{Int64,2}, ::Int64 **)** at **./reduce.jl:397**
  [4] top-level scope at **none:0**

But this does

**julia>** sum(A, dims=1)

1×2 Array{Int64,2}:
4 6
9 Likes

I remember this has been changed since version 0.7, but TBH, I don’t know why this was decided? Why Julia sometimes choose verbosity over brevity when there is no real ambiguity. When I read sum(A,1) what else should I assume? Nothing other than summing array elements over the first dimension. For those who used Fortran, MATLAB, or even Python (Numpy) for years, making dims=1 a mandatory argument is really weird.

Brevity is crucial in dynamic languages with a REPL like Julia. Your’e trying to make the clear thing clearer, even if it’s not so clear to a beginner (someone who didn’t use a programming language before), they will learn it once and write it a million times in the REPL. It could’ve been made optional at most like in other languages. Also, why dims and not just dim as in Fortran? Only rare cases will include nD arrays, n > 2. Yes, clarity is a good thing, but also choosing a sensible default is very important especially for dynamic coding in the REPL.

PS: I can’t find the issue number for the discussion about this change, I appreciate if someone can provide it here.

I think it is this issue #25989. On the question on why dims and not dim, you have answered your own question I guess as sum(rand(3,3,3), dims = (1,2)) works just as well.

There actually was an ambiguity in the case of sum(x, y). It’s not clear if x is a callable function to be applied to the elements of y or if x is the data and y is the dimension. If you were to try to use a function-like-object there, it’d fail on 0.6 but work on 1.0.

2 Likes

This solution seems to be depreciated, when I try it i get the following error :

ERROR: MethodError: objects of type Array{Int64,2} are not callable
Use square brackets [] for indexing an Array
3 Likes

Have you by any chance called an array sum? If so, that definition is shadowing the function.

This is because the dimension is now a keyword argument. sum(A, 2) will throw that error but sum(A, dims=2) works.

3 Likes

In

Julia Version 1.8.0
Commit 5544a0fab76 (2022-08-17 13:38 UTC)
Platform Info:
  OS: macOS (arm64-apple-darwin21.3.0)
  CPU: 10 × Apple M1 Max
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-13.0.1 (ORCJIT, apple-m1)
  Threads: 1 on 8 virtual cores

Your example leads to the following behavior:

julia> A = [1 2; 3 4]
2×2 Matrix{Int64}:
 1  2
 3  4

julia> sum(A, 1)
ERROR: MethodError: objects of type Matrix{Int64} are not callable
Use square brackets [] for indexing an Array.
Stacktrace:
 [1] mapreduce_first(f::Matrix{Int64}, op::Function, x::Int64)
   @ Base ./reduce.jl:411
 [2] mapreduce(f::Matrix{Int64}, op::Function, a::Int64)
   @ Base ./reduce.jl:438
 [3] sum(f::Matrix{Int64}, a::Int64; kw::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ Base ./reduce.jl:520
 [4] sum(f::Matrix{Int64}, a::Int64)
   @ Base ./reduce.jl:520
 [5] top-level scope
   @ REPL[32]:1

What changed and how to we get back to the desired behavior?

Again, the documentation for sum explicitly answers this question (even almost 4 years later).

sum(A; dims=1) is now the proper syntax.

1 Like