pythonnumpymatrix4d

How can I multiply matrices of matrices elementwise using numpy (and not for loops)?


I have some 4-dimensional numpy arrays for which the easiest visualisation is a matrix of arbitrary size (not necessarily square) in which each element is a 2x2 square matrix. I would like to standard matrix multiply (@) the 2x2 matrices of the large matrices elementwise (producing another matrix of the same dimension of 2x2 matrices). The eventual hope is to parallelize this process using CuPy so I want to do this without resorting to looping over every element of the bigger matrix.

Any help would be appreciated.

Example of what I mean:

x = np.array([[  [[1,0], [0, 1]], [[2,2], [2, 1]]  ]])
y = np.array([[  [[1,3], [0, 1]], [[2,0], [0, 2]]  ]])
xy = np.array([[  [[1,3], [0, 1]], [[4,4], [4, 2]]  ]])


[[ [[1, 0],            [[2, 2]          x         [[ [[1, 3],            [[2, 0]
    [0, 1]]      ,      [2, 1]] ]]                    [0, 1]]      ,      [0, 2]] ]]




=> [[ [[1, 3],            [[4, 4]
       [0, 1]]      ,      [4, 2]] ]]

In this example the 2 'large' matrices are 1x2 matrices where each of the 2 elements are 2x2 matrices. I have tried to lay it out in a manner that makes it clear what is going on as well as using standard 4d numpy arrays.

Edited in line with comments.


Solution

  • As Homer512 stated in a comment, np.matmul, aka the @ operator, will handle this scenario (see the numpy docs). You will need to make sure your 2 x 2 matrices are in the last dimensions.

    import numpy as np
    
    a1 = np.array([[1, 0], [0, 1]])
    a2 = np.array([[2, 2], [2, 1]])
    a = np.array([a1, a2])
    
    b1 = [[1, 3], [0, 1]]
    b2 = [[2, 0], [0, 2]]
    b = np.array([b1, b2])
    
    x = np.array([a, b])
    
    print(a @ b)
    

    Output:

    [[[1 3]
      [0 1]]
    
     [[4 4]
      [4 2]]]