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

2 Answers 2

8
$\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$
4
  • $\begingroup$ Timing tests would be useful. If no one adds this before I have a chance, I will edit with them. $\endgroup$ Oct 9, 2019 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, 2019 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, 2019 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, 2019 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 and acknowledge that you have read and understand our privacy policy and code of conduct.

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