Given an $n_1 \times \cdots \times n_k \times g \times g$ tensor $A$ (i.e. a collection of $g \times g$ matrices) and an $n_1 \times \cdots \times n_k \times g$ tensor $b$ (i.e. a collection of vectors of length $g$) I want to use Numpy to compute the $n_1 \times \cdots \times n_k \times g$ tensor $c$ where each element is the matrix-vector product
$$c_{i_1,\ldots,i_k} = A_{i_1,\ldots,i_k}b_{i_1,\ldots,i_k}.$$
I found a way to do this using numpy.einsum
but was curious if there was another way to do this or if there is a particular name for this operation? If there is an alternative how does the performance of this alternative compare to using einsum
?
Below is an example:
from numpy import dot, einsum, zeros_like
from numpy.linalg import norm
from numpy.random import randn
n = 10
g = 4
matrices = randn(n,n,g,g)
vectors = randn(n,n,g)
# "manual" mat-vec multiplication (slow)
out1 = zeros_like(vectors)
for i in range(n):
for j in range(n):
out1[i,j] = dot(matrices[i,j], vectors[i,j])
# using numpy.ensum (faster)
out2 = zeros_like(vectors)
out2 = einsum('...ij,...j->...i', matrices, vectors)
numpy.isclose(out1, out2).all() # outputs `True`