11
$\begingroup$

I have a 2x2 matrix of lists. For example, the matrix I am working with looks like

matrix = {{{a,b,c}, {e,f,g}}, {{h,i,j}, {k,l,m}}}

I want to define a function such that when I pass this matrix to it, it gives me

{a+e+h+k,b+f+i+l,c+g+j+m}

Obviously a bruteforce way I could do this is to just take

matrix[[1, 1]] + matrix[[1, 2]] + matrix[[2, 1]] + matrix[[2, 2]]

But is there a more elegant approach to doing this using some built in functions in Mathematica? I tried looking around but I could not find one.

$\endgroup$
0

8 Answers 8

16
$\begingroup$

Dimensions[matrix] is {2, 2, 3} so you can use dot on the left side:

matrix = {{{a, b, c}, {e, f, g}}, {{h, i, j}, {k, l, m}}};

func = {1, 1}.({1, 1}.#) &;
func[matrix]
(* {a + e + h + k, b + f + i + l, c + g + j + m} *)

Or alternatively specify which levels to sum in Total

Total[matrix, {1, 2}]
(* {a + e + h + k, b + f + i + l, c + g + j + m} *)
$\endgroup$
14
$\begingroup$
matrix ~ Total ~ 2
{a + e + h + k, b + f + i + l, c + g + j + m}

And, for fun:

☺ = +## & @@ +## & @@ # &;

☺ @ matrix
{a + e + h + k, b + f + i + l, c + g + j + m}
$\endgroup$
1
10
$\begingroup$

you can flatten then MapThread

{{{a,b,c}, {e,f,g}}, {{h,i,j}, {k,l,m}}} //
Flatten[#,1]& //
MapThread[Plus]

(* {a + e + h + k, b + f + i + l, c + g + j + m} *)

$\endgroup$
1
  • 1
    $\begingroup$ MapThread[Plus] @ MapThread[Plus, matrix, 2] is another option. $\endgroup$ Commented Apr 8, 2022 at 19:23
6
$\begingroup$

We grab the matrix from the OP

matrix = {{{a, b, c}, {e, f, g}}, {{h, i, j}, {k, l, m}}}

0. Using Total + Query + Developer`ToPackedArray

The code is:

Total[Developer`ToPackedArray@matrix // Query[Total, All], {1}]

1. Using Flatten + Transpose + Plus

The code is

Plus @@@ Transpose[Flatten[matrix, 1]]

2. Using Thread + Transpose + Plus

The code is

Plus @@@ Thread[Flatten[matrix, 1]]

3. Using Total

The code is

Total@matrix[[All ;;]]~Total~1

4. Using Sum

The code is

Sum[matrix[[xx1, xx2]], {xx1, 1, (Dimensions@matrix)[[1]]}, {xx2, 
  1, (Dimensions@matrix)[[2]]}]

The above is an automated approach of the following

matrix[[1, 1]] + matrix[[1, 2]] + matrix[[2, 1]] + matrix[[2, 2]]

that was explicitly mentioned in the OP.

All of the above give


list1


$\endgroup$
5
$\begingroup$
func = Apply[Plus, Plus @@ #] &;
func[matrix]

(* {a + e + h + k, b + f + i + l, c + g + j + m} *)

Or:

func = Map[Plus @@ # &, #, {0, 1}] &;
func[matrix]

(* {a + e + h + k, b + f + i + l, c + g + j + m} *)

$\endgroup$
1
  • 1
    $\begingroup$ very nicely done! $\endgroup$
    – bmf
    Commented Apr 9, 2022 at 0:03
3
$\begingroup$
matrix = {{{a, b, c}, {e, f, g}}, {{h, i, j}, {k, l, m}}};

A variant of bmf's 2nd answer using MapApply (new in 13.1)

MapApply[Plus] @ Transpose @ Apply[Join] @ matrix

{a + e + h + k, b + f + i + l, c + g + j + m}

$\endgroup$
3
$\begingroup$
matrix = {{{a, b, c}, {e, f, g}}, {{h, i, j}, {k, l, m}}};

Using ArrayRules and GatherBy:

Total@*Values /@ GatherBy[Most@ArrayRules[matrix], #[[1, 3]] &]

{a + e + h + k, b + f + i + l, c + g + j + m}

$\endgroup$
2
$\begingroup$
Plus @@ ArrayFlatten[matrix, 1]

(* {a + e + h + k, b + f + i + l, c + g + j + m} *) 
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.