5

Let's assume we have a bunch of 3 by 3 matrices along with a bunch of 3-dimensional vectors:

N = 100
matrices = np.random.rand(N, 3, 3) # shape: (100, 3, 3)
vectors = np.random.rand(N, 3)     # shape: (100, 3)

How can I perform an "element-wise" matrix/vector multiplication, so that e.g. result[0] is the 3-dimensional vector resulting from the matrix/vector multiplication of matrices[0] with vector[0].

Using np.dot, np.matmul, or np.prod directly fails due to the non-matching shapes. Is there a broadcasting trick to make this work?

bluenote10
  • 23,414
  • 14
  • 122
  • 178
  • 2
    This seems like a very basic question, which I expected to be on SO, but I couldn't find anything. – bluenote10 Jul 23 '18 at 12:49
  • @Divakar This is not a duplicate of the marked question, because the other question has the special constraint that it must not use `np.matmul` or `np.einsum`. I'm looking for the most basic standard solution without such specific constraints. – bluenote10 Jul 23 '18 at 13:03
  • So, are you saying you don't need a solution with `einsum` or `matmul`? – Divakar Jul 23 '18 at 13:06
  • @Divakar I'm fine with any solution, but the other question isn't. That's why it doesn't have an accepted answer. In fact the other answer answers my question but not the one it was written for ;). – bluenote10 Jul 23 '18 at 13:13
  • 1
    No worries, added a better dup :) – Divakar Jul 23 '18 at 13:14

1 Answers1

1
np.sum(matrices * vectors[:,:,None], axis=(0,1))

None adds a dummy axis to the vector that will match the third axis of matrices. The einsum method linked in the OP seems faster:

np.einsum('ijk,ij->k', matrices, vectors)
user2653663
  • 2,818
  • 1
  • 18
  • 22