Search code examples
pythonmatrixmultiplication

Multiplying many square matrices


I have a problem where I want to multiply many 2x2 square matrices. The elements in the matrix are of the from a+ib (complex number)

Here's how the code looks like:

Final_list=[]

for x in list_x:
         
         Matrix=np.array([[1,0],[0,1]])

         for y in list_y:

              Matrix_y=[....] #create a 2x2 matrix from values x and y

              Matrix= Matrix.dot(Matrix_y)
         
         value= 5/(Matrix[0,0] + Matrix[1,0]....) #something like this

         Final_list.append(abs(value))

Final_list is what I need.

My code works but it takes a while and I feel like there must be a better way to write this. If length of list_x=30000 and list_y=300 it takes a while to compute ~ a minute or so.

I was able to create a large matrix of shape (300,30000,2,2). I did that by array broadcasting and using np.shape. I hoped to multiply all matrices in a column to get an array of matrices of shape (30000,2,2). I am thinking that might help in the computation but havent figured out a way to do it.

Is there a better way to write this instead of using multiple for loops?

Thanks


Solution

  • I don't know a fully vectorized solution. Initially I thought that np.matmul.reduce might work, but reduce seems to be unsupported for non-commutative operations according to the old docs. There is also np.linalg.multi_dot, but it seems like an overkill for 2 by 2 matrices.

    Here is a answer that runs in 1.5 seconds on my machine; it is similar to the approach here.

    arr = np.random.rand(300, 30_000, 2, 2)
    
    def my_mul(mats):
      if len(mats) == 1:
        return mats[0,...]
      elif len(mats) == 2:
        return mats[0,...] @ mats[1,...]
      else:
        mid = len(mats) // 2
        return my_mul(mats[:mid,...]) @ my_mul(mats[mid:,...])
    
    result = my_mul(arr) # 1.53 s