5
$\begingroup$

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}}
$\endgroup$
  • 5
    $\begingroup$ {x, y, z}*# & /@ {{10, 20, 30}, {0, 1, 2}} $\endgroup$ – Bob Hanlon Oct 9 at 17:23
  • 6
    $\begingroup$ A vectorized method is this: {{10, 20, 30}, {0, 1, 2}}.DiagonalMatrix[{x, y, z}] $\endgroup$ – Henrik Schumacher Oct 9 at 17:46
7
$\begingroup$

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 *)
$\endgroup$
  • $\begingroup$ Timing tests would be useful. If no one adds this before I have a chance, I will edit with them. $\endgroup$ – CA Trevillian Oct 9 at 20:26
  • $\begingroup$ You might want to compare on packed arrays of reals as well, but you will need to repack the diagonal matrix before using Dot. $\endgroup$ – Carl Woll Oct 9 at 23:54
  • $\begingroup$ 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 $\endgroup$ – user1066 Oct 10 at 3:28
  • $\begingroup$ m.DiagonalMatrix[v] == Inner[Times, m, DiagonalMatrix[v]] == Inner[Times, m, v, List], where m is matrix, v is vector $\endgroup$ – user1066 Oct 10 at 3:29
0
$\begingroup$

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}} *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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