# Element-wise multiplication of an array and a matrix

How can I express multiplication of an array and a matrix so that

{x, y, z}*{{10, 20, 30}, {0, 1, 2}}


gives

{{10 x, 20 y, 30 z}, {0, y, 2 z}}

• {x, y, z}*# & /@ {{10, 20, 30}, {0, 1, 2}} Oct 9, 2019 at 17:23
• A vectorized method is this: {{10, 20, 30}, {0, 1, 2}}.DiagonalMatrix[{x, y, z}] Oct 9, 2019 at 17:46

I think the answers given in the comments to the question deserves being on record as a formal answer.

• Bob Hanlon
{x, y, z}*# & /@ {{10, 20, 30}, {0, 1, 2}}

• Henrik Schumacher
{{10, 20, 30}, {0, 1, 2}}.DiagonalMatrix[{x, y, z}]

• user1066
Inner[Times, {{10, 20, 30}, {0, 1, 2}}, {x,y,z}, List]


EDIT: Comparing the timings:

Clear["Global*"]

n = 20; r = 100;

var = Array[x, n];

mat = Array[m, {r, n}];

t[1] = AbsoluteTiming[prod[1] = var*# & /@ mat;][[1]]

(* 0.001768 *)

t[2] = AbsoluteTiming[prod[2] = mat.DiagonalMatrix[var];][[1]]

(* 0.027773 *)

t[3] = AbsoluteTiming[prod[3] = Inner[Times, mat, var, List];][[1]]

(* 0.001384 *)


Comparing the timings

(t /@ Range[3])/t[3]

(* {1.27746, 20.0672, 1.} *)


Verifying that the different approaches provide identical results.

Equal @@ (prod /@ Range[3])

(* True *)

• Timing tests would be useful. If no one adds this before I have a chance, I will edit with them. Oct 9, 2019 at 20:26
• You might want to compare on packed arrays of reals as well, but you will need to repack the diagonal matrix before using Dot. Oct 9, 2019 at 23:54
• In addition {{10, 20, 30}, {0, 1, 2}}.DiagonalMatrix[{x,y,z}]==Inner[Times, {{10, 20, 30}, {0, 1, 2}}, {x,y,z}, List]==Inner[Times, {{10, 20, 30}, {0, 1, 2}}, DiagonalMatrix[{x,y,z}]] but timings may be important Oct 10, 2019 at 3:28
• m.DiagonalMatrix[v] == Inner[Times, m, DiagonalMatrix[v]] == Inner[Times, m, v, List], where m is matrix, v is vector Oct 10, 2019 at 3:29
m = {{10, 20, 30}, {0, 1, 2}};

v = {x, y, z};


Using Threaded (new in 13.1}

m * Threaded[v]


{{10 x, 20 y, 30 z}, {0, y, 2 z}}

m = {{10, 20, 30}, {0, 1, 2}};

v = {x, y, z};


Using Cases:

Cases[m, x_ :> x*v]

(*{{10 x, 20 y, 30 z}, {0, y, 2 z}}*)


Or using MapThread:

MapThread[#1*#2 &, {Array[v &, Length@#], #} &@m]

(*{{10 x, 20 y, 30 z}, {0, y, 2 z}}*)


Perhaps something as simple as this, which can be more efficient for large elements:

(a*{b, c}) /. {a -> {x, y, z}, b -> {10, 20, 30}, c -> {0, 1, 2}}

(* {{10 x, 20 y, 30 z}, {0, y, 2 z}} *)
`