matmul works with transposition in B , so its second to last dim corresponds to the last of A
In [1019]: A=np.random.rand(K,M,N) In [1021]: B=np.random.rand(K,L,N) In [1023]: C=np.einsum('kmn,kln->kml',A,B) In [1024]: C.shape Out[1024]: (2, 4, 3) In [1026]: D=A@B.transpose (0,2,1) In [1027]: D.shape Out[1027]: (2, 4, 3) In [1028]: np.allclose(C,D) Out[1028]: True
For this small example, timeit same.
[np.dot(x,yT) for x, y in zip(A, B)] does the same; match the second last dull y with the symbol x and iterate over the 1st dull A and B
source share