Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Numpy - row-wise outer product of two matrices

I have two numpy arrays: A of shape (b, i) and B of shape (b, o). I would like to compute an array R of shape (b, i, o) where every line l of R contains the outer product of the row l of A and the row l of B. So far what i have is:

import numpy as np

A = np.ones((10, 2))
B = np.ones((10, 6))
R = np.asarray([np.outer(a, b) for a, b in zip(A, B)])
assert R.shape == (10, 2, 6)

I think this method is too slow, because of the zip and the final transformation into a numpy array.

Is there a more efficient way to do it ?

like image 814
Marvin Lerousseau Avatar asked Jan 29 '18 10:01

Marvin Lerousseau


People also ask

What is the outer product of two matrices?

In linear algebra, the outer product of two coordinate vectors is a matrix. If the two vectors have dimensions n and m, then their outer product is an n × m matrix. More generally, given two tensors (multidimensional arrays of numbers), their outer product is a tensor.

How do you do NumPy element-wise multiplication?

Use NumPy.multiply() function on 2-D arrays. This multiplies every element of the first matrix by the equivalent element in the second matrix using element-wise multiplication, or Hadamard Product. Make sure that the dimensions of both matrices have the same in order to multiply.

How do you get a NumPy array output in which every element is an element-wise sum of the two NumPy arrays?

add() function is used when we want to compute the addition of two array. It add arguments element-wise. If shape of two arrays are not same, that is arr1.


1 Answers

That is possible with numpy.matmul, which can do multiplication of "matrix stacks". In this case we want to multiply a stack of column vectors with a stack of row vectors. First bring matrix A to shape (b, i, 1) and B to shape (b, 1, o). Then use matmul to perform b times the outer product:

import numpy as np

i, b, o = 3, 4, 5

A = np.ones((b, i))
B = np.ones((b, o))

print(np.matmul(A[:, :, np.newaxis], B[:, np.newaxis, :]).shape)  # (4, 3, 5)

An alternative could be to use numpy.einsum, which can directly represent your index notation:

np.einsum('bi,bo->bio', A, B)
like image 138
MB-F Avatar answered Oct 04 '22 02:10

MB-F