Search code examples
pythonmatrixmatrix-multiplicationmultiplication

Matrix multiplication throwing an error when second matrix has only one column


First off, it's kind of exciting to be asking a question on Stack Overflow as I've long-time wanted to get into coding but haven't really been able to start.

I'm trying to make a matrix multiplication function in Python without using NumPy. I've almost finished my code, but I'm getting an error whenever I try to multiply matrix "A" by a matrix "B" with only one column.

My code is as follows:

import numpy as np

def matrix_multiply(A,B):
row_A = len(A)
col_A = len(A[0])
row_B = len(B)
col_B = len(B[0])
if col_A != row_B:
    return("Invalid matrices")
else:
    result = np.zeros((col_B,row_A))
    for i in range(row_A): # iterate through columns of Y
        for j in range(col_B): # iterate through rows of Y
            for k in range(col_A):
                result[i][j] += A[i][k]*B[k][j]
    return result

My error is:

Traceback (most recent call last): File "<stdin>", line 1, in <module>
File "<stdin>", line 13, in matrix_multiply
IndexError: index 1 is out of bounds for axis 0 with size 1

I assume this is a problem with the "result[i][j] += A[i][k]*B[k][j]" part.

My code works perfectly for any other-sized matrix, but when there's one column I get this index error. What's going on?

Here's an example:

A = np.array([[1,2,3],[2,3,4]])
B = np.array([[2,3],[4,5],[5,6]])

matrix_multiply(A,B)

array([[25., 31.],
   [36., 45.]])

But when I do...

v = np.array([[4,3,1],[6,7,2]])
g = np.array([[3],[1],[4]])

matrix_multiply(v,g)

I get the error.


Solution

  • As I said in my comments, you need to swap the order of indices while filling up your result matrix and then take the transpose of the final array

    Problem: Your index i runs on the length of row_A as for i in range(row_A) and index j runs on the length of col_B as for j in range(col_B): BUT while defining empty result array you swap the dimensions because you use result = np.zeros((col_B,row_A)), i.e., you first define column dimension and then row dimension. Hence either you swap i and j inside your for loop as I did below OR you swap the variables while initializing the result and then use [i][j] as you were doing. Then you won't need a transpose.

    import numpy as np
    
    def matrix_multiply(A,B):
        row_A = len(A)
        col_A = len(A[0])
        row_B = len(B)
        col_B = len(B[0])
        print (row_B, col_B)
        if col_A != row_B:
            return("Invalid matrices")
        else:
            result = np.zeros((col_B,row_A))
            for i in range(row_A): # iterate through columns of Y
                for j in range(col_B): # iterate through rows of Y
                    for k in range(col_A):
                        result[j][i] += A[i][k]*B[k][j]
            return result
    

    Example 1

    A = np.array([[1,2,3],[2,3,4]])
    B = np.array([[2,3],[4,5],[5,6]])
    
    result = matrix_multiply(A,B).T
    print (result)
    
    # array([[25., 31.],
    #    [36., 45.]])
    

    Example 2

    v = np.array([[4,3,1],[6,7,2]])
    g = np.array([[3],[1],[4]])
    
    result = matrix_multiply(v,g)
    print (result)
    # [[19. 33.]]