# Operation acting on arbitrary number of matrices, element-wise

I have a certain number of $$N \times M$$ matrices:

$$M_1 = \begin{pmatrix} a_{11} & a_{12} & ... & a_{1M} \\ a_{21} & & & \\ \vdots & & \ddots & \\ a_{N1} & & & a_{NM} \end{pmatrix}$$

$$M_2 = \begin{pmatrix} b_{11} & b_{12} & ... & b_{1M} \\ b_{21} & & & \\ \vdots & & \ddots & \\ b_{N1} & & & b_{NM} \end{pmatrix}$$

and I want to create a new matrix, applying a certain operation $$f$$ element by element, obtaining something like

$$M = \begin{pmatrix} f(a_{11},b_{11},...) & f(a_{12},b_{12},...) & ... & f(a_{1M},b_{1M},...) \\ f(a_{21},b_{21},...) & & & \\ \vdots & & \ddots & \\ f(a_{N1},b_{N1},...) & & & f(a_{NM},b_{NM},...) \end{pmatrix}$$

where the $$f$$ takes as many arguments as the number of matrices.

As of now I am implementing this using a Table[],

With[{dims = Dimensions[dataA]}, Table[f[dataA[[x, y]], dataB[[x, y]], dataC[[x, y]]], {x, 1, dims[[1]]}, {y, 1, dims[[2]]}]]]


I was wondering if there's some more idiomatic Mathematica way of doing this.

MapThread is designed to do exactly this. Example:

A = {{a11, a12}, {a21, a22}};
B = {{b11, b12}, {b21, b22}};
MapThread[f, {A, B}, 2]


Gives

{{f[a11, b11], f[a12, b12]}, {f[a21, b21], f[a22, b22]}}


The 2 is because you want to apply to elements of lists of lists. The arguments to "f" are 2 levels deep.

• Exactly what I was looking for! Thanks!
– zakk
Commented Jan 22, 2019 at 17:10
m1 = Array[a, {3, 3}];
m2 = Array[b, {3, 3}];
SetAttributes[foo, Listable]
foo[m1, m2] // MatrixForm // TeXForm


$$\left( \begin{array}{ccc} \text{foo}(a(1,1),b(1,1)) & \text{foo}(a(1,2),b(1,2)) & \text{foo}(a(1,3),b(1,3)) \\ \text{foo}(a(2,1),b(2,1)) & \text{foo}(a(2,2),b(2,2)) & \text{foo}(a(2,3),b(2,3)) \\ \text{foo}(a(3,1),b(3,1)) & \text{foo}(a(3,2),b(3,2)) & \text{foo}(a(3,3),b(3,3)) \\ \end{array} \right)$$

• Thank you very much!
– zakk
Commented Jan 22, 2019 at 17:11