DSKim - 6 months ago 42

Python Question

Suppose that the matrix A has the size m x r and that B has n x r. In numpy, how can I do column-wise outer-product between A and B?

That is, I want a matrix, C (size: m x n x r), where C[:, :, i] is the outer product of A[:, i] and B[:, i].

Of course, I can use a for-loop over the columns but I am wondering if there is a vectorized way to make the computation fast.

Answer

I usually call on `einsum`

for easy vectorization in cases like this:

```
>>> m,n,r = 30,50,70
>>> A = np.random.random((m,r))
>>> B = np.random.random((n,r))
>>> C = np.einsum('ik,jk->ijk', A, B)
>>> C2 = np.dstack([np.outer(A[:,i], B[:,i]) for i in range(r)])
>>> C.shape
(30, 50, 70)
>>> np.allclose(C, C2)
True
```

This way we can be explicit about what we want to happen to each coordinate, while still being faster than a loop:

```
>>> %timeit C = np.einsum('ik,jk->ijk', A, B)
The slowest run took 4.83 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 216 µs per loop
>>> %timeit C2 = np.dstack([np.outer(A[:,i], B[:,i]) for i in range(r)])
100 loops, best of 3: 2.08 ms per loop
```