2
votes

I am given two 2D matrices where each of the cells is a vector with three elements.

What I'm looking to do is use 2D matrix multiplication where when any of the cells are multiplied together, it takes the dot product of the three-element vectors.

My linear algebra skills are lacking so apologies if there is an answer already, I've looked over many pages relating to tensordot and einsums but I don't understand how each of these might apply to my situation.

Here is basically what I am given:

import numpy as np
ar1 = np.array([[[1,2,3],[3,4,5]],[[5,6,7],[7,8,9]]])
ar2 = np.array([[[2,3,4],[4,5,6]],[[6,7,8],[8,9,10]]])

Here is how to make what I am looking for:

final = [[0 for x in range(2)] for y in range(2)] 

final[0][0] = np.dot(ar1[0][0], ar2[0][0]) + np.dot(ar1[0][1], ar2[1][0])
final[0][1] = np.dot(ar1[0][0], ar2[0][1]) + np.dot(ar1[0][1], ar2[1][1])
final[1][0] = np.dot(ar1[1][0], ar2[0][0]) + np.dot(ar1[1][1], ar2[1][0])
final[1][1] = np.dot(ar1[1][0], ar2[0][1]) + np.dot(ar1[1][1], ar2[1][1])

final

Output: [[106, 142], [226, 310]]

In reality these matrices are going to be around 3000x40000x3 and 40000x40x3, so taking speed into account is greatly appreciated. Thanks!

2
did you try tensordot? this is basically n-D matrices multiplication function. - smerllo

2 Answers

2
votes

Here is how to do it with einsum

np.einsum('ijl,jkl',ar1,ar2)
# array([[106, 142],
#        [226, 310]])

and with tensordot

np.tensordot(ar1,ar2,((1,2),(0,2)))
# array([[106, 142],
#        [226, 310]])

and with reshaping

ar1.reshape(2,-1)@ar2.transpose(0,2,1).reshape(-1,2)
# array([[106, 142],
#        [226, 310]])
1
votes

A matrix product of two matrices A and B can be achieved byA@B. The matrix product is only performed in the last two dimensions, so you have to make sure that all dimensions before are the same (or that python can broadcast). So A could be of shape (10000,2,3,5) and B of shape (10000,2,5,7) and A@B is of shape (10000,2,3,7):

final = np.sum([email protected],axis=0).T

should do the job.