Python Programming Challenge 2: Multiplying Matrices without numpy


Today, I have another Math programming challenge for you.. we are going to code a simple program to multiply two matrices together.

Remember matrices from your high school math? Here’s a quick recap.

Matrices are made of rows and columns of numbers. The matrix below has 2 rows and 3 columns. This is known as a 2 by 3 matrix.

2x3 Matrix

The second matrix below is a 3 by 4 matrix (i.e. it has 3 rows and 4 columns).

3x4 Matrix

In order to multiply two matrices, the number of columns in the first matrix must match the number of rows in the second matrix.

Matrix Multiplication

In the example above, the resulting matrix is a 2 by 4 matrix.

To multiply two matrices, we multiply the elements in each row of the first matrix with the elements in each column of the second matrix.

After multiplying the elements, we sum the products. For instance, the diagram below shows how we get the number 38 by multiplying the first row (2, 3, 6) in the first matrix with the first column (1, 2, 5) in the second matrix.

Matrix Multiplication

Clear? If you are lost, you can refer to the YouTube video below for a more detailed explanation:


For those of you who are familiar with using Python for data science, you have probably used the numpy module to multiply matrices before. We are not going to do that today. Instead, we’ll be coding our own matrix multiplication program. Ready?

The task today is to write a program in Python that does the following:

First, prompt users to enter the rows of the first matrix one by one.
Next, prompt users to enter the rows of the second matrix.
After that, check if the two matrices can be multiplied.
If they can, multiply the two matrices and display the result.

Here’s a video showing how the program works.


The suggested solution and a run-through of it can be found below.

Suggested Solution:

def getMatrix(name):
    matrixCreated = []
    i = 0    
    while True:
        i += 1
        row = input('\nEnter elements in row %s of Matrix %s (separated by commas)\nOr -1 to exit: ' %(i, name))
        if row == '-1':
            break
        else:
            strList = row.split(',')
            matrixCreated.append(list(map(int, strList)))
    return matrixCreated

def getColAsList(matrixToManipulate, col):
    myList = []
    numOfRows = len(matrixToManipulate)
    for i in range(numOfRows):
        myList.append(matrixToManipulate[i][col])
    return myList

def getCell(matrixA, matrixB, r, c):
    matrixBCol = getColAsList(matrixB, c)
    lenOfList = len(matrixBCol)
    productList = [matrixA[r][i]*matrixBCol[i] for i in range(lenOfList)]
    return sum(productList)
    

matrixA = getMatrix('A')
matrixB = getMatrix('B')

rowA = len(matrixA)
colA = len(matrixA[0])
rowB = len(matrixB)
colB = len(matrixB[0])

result = [[0 for p in range(colB)] for q in range(rowA)]
       
if (colA != rowB):
    print('The two matrices cannot be multiplied')
else:
    print('\nThe result is')
    for i in range(rowA):
        for j in range(colB):
            result[i][j] = getCell(matrixA, matrixB, i, j)
        print(result[i])


Main Concepts Used:

  • Control flow statements like if, while, for loops etc
  • Python built-in functions, including map(), list(), sum(), split(), append() etc

Run Through:

First, we define a function called getMatrix that has one parameter: name.

The name parameter allows us to pass in the name of the matrix that we want to create.

Within the function, we first declare an empty list called matrixCreated. This list will be used to store the matrix that the function creates. The matrix will be stored as a list of lists. For instance, if the matrix is

Matrix As List Of Lists

it’ll be stored as [ [2, 1, 4] , [5, 3, 1] ]

Next, we declare a variable i which is used to store the row number.

After declaring the two variables, we use a while True loop to repeatedly prompt users to enter the row of the matrix or enter -1 to exit the function.

Suppose the user enters 2, 1, 4 for the first row.

We then use the built-in split() function to split the input into a list of strings and store it into a variable called strList. We’ll get strList = ['2', '1', '4'] as the result.

Next, we use the map() function to cast all the elements in strList into integers.

The map() function is a built-in Python function that applies a function to all the elements of an iterable (such as a list). It accepts the names of the function and the iterable as arguments and returns the result as a map object.

Here, we use the map() function (map(int, strList))) to apply the int() function to all elements in strList.

As the map() function returns a map object, we use the built-in list() function to convert it into a list.

We’ll get [2, 1, 4] as the result.

We then use the append() method to append this list to matrixCreated.

After getting the first row, the getMatrix function prompts users to enter the next row (using the while True loop). This is done repeatedly until the user enters -1.

Once the user enters -1, we use the break keyword to exit the while True loop. With that, the function is complete and we simply need to return matrixCreated.

Next, we create another function called getColAsList. This function has two parameters – matrixToManipulate and col.

The function is used to get the specified column (col) of matrixToManipulate as a list. For instance, suppose

matrixToManipulate = [[1, 2, 5], [3, 4, 6]]

and

col = 0

the function returns [1, 3] as the result.

Getting Column of Matrix

(Note that this function uses 0 to represent the first column.)

In order to do that, we first declare an empty list called myList.

Next, we determine the number of rows that matrixToManipulate has and store it in a variable called numOfRows.

Recall the matrixToManipulate is a list of lists? Suppose
matrixToManipulate = [[1, 2, 5], [3, 4, 6]]

It has two elements [1, 2, 5] and [3, 4, 6].

Hence, len(matrixToManipulate) (which is equal to 2) essentially gives us the number of rows of the matrix.

After getting the number of rows of the matrix, we use a for loop to loop through each row and extract the element at index col. After doing that, we return the list.

Next, we move on to the getCell function. This function has 4 parameters, matrixA, matrixB, r and c.

It multiplies each element in row r of matrixA with the corresponding element in column c of matrixB and returns the sum of all the products.

For instance, if

matrixA = [ [1, 2, 5], [3, 4, 6] ]
matrixB = [ [3, 4], [1, 1], [2, 0] ]

r = 0 (corresponds to the first row)
c = 1 (corresponds to the second column)

matrixA_new
matrixB_new

The function first converts the second column of matrixB into a list and store it into a variable called matrixBCol.

We’ll get matrixBCol = [4, 1, 0] as a result.

After getting the column as a list, we use the len() function to get the number of elements in matrixBCol and store it in a variable called lenOfList.

Next, we use a for loop to multiply each element in row r of matrixA with the corresponding element in col c of matrixB and store the result in a list called productList.

Line 24

productList = [matrixA[r][i]*matrixBCol[i] for i in range(lenOfList)]

is basically a simplified way of writing

productList = []
for i in range(lenOfList):

    productList.append(matrixA[r][i]*matrixBCol[i])

In our example, r = 0.

As lenOfList = 3 (i.e. there are three elements in matrixBCol), we get

productList[0] = matrixA[0][0]*matrixBCol[0] = 1*4
productList[1] = matrixA[0][1]*matrixBCol[1] = 2*1
productList[2] = matrixA[0][2]*matrixBCol[2] = 5*0

This means we are multiplying each element in the first row of matrixA with each corresponding element in the second column of matrixB.

Once that is done, we use the built-in Python function sum() to add up all the elements in productList and return the result.

With that, the three functions that we need are complete.

Now, we are ready to get our user inputs. We use the getMatrix function to prompt users to enter the data for the two matrices and store them inside the variables matrixA and matrixB.

We also use the built-in len() function to get the number of rows and columns in both matrices.

Suppose matrixA and matrixB are as shown below:

matrixA2
matrixB2

In that case, rowA = 2, colA = 3, rowB = 3 and colB = 4.

Hence, we should get a 2×4 matrix after we multiply the two matrices.

To store this resulting matrix, we initialize a list called result as follows:

result = [ [0, 0, 0, 0], [0, 0, 0, 0] ]

We’ll update the elements in result after we multiply matrixA with matrixB.

To multiply the two matrices, we use an if statement.

If colA does not equal rowB, the two matrices cannot be multiplied and we simply inform the user.

On the other hand, if the two matrices can be multiplied, we use the getCell function to get each cell for the resulting matrix.

When i = 0, the inner for loop (for j in range(colB)) gives us the results for result[0][0], result[0][1], result[0][2] and result[0][3].

This corresponds to the first row in the resulting matrix.

Using matrixA and matrixB shown above,

result[0][0] = 1*7 + 2*11 + 3*15 = 74
result[0][1] = 1*8 + 2*12 + 3*16 = 80
result[0][2] = 1*9 + 2*13 + 3*17 = 86
result[0][3] = 1*10 + 2*14 + 3*18 = 92

Hence, result[0] = [74, 80, 86, 92]

Once that is done, we print result[0]. Next, we use the outer for loop to move i to the next row to get the value of result[1].

This gives us
result[1] = [173, 188, 203, 218]

We then print this value. Once that is done, the outer for loop is complete and the program ends.

If you run this program for the 2×3 matrixA and 3×4 matrixB above, you’ll get

The result is
[74, 80, 86, 92]
[173, 188, 203, 218]

as the output.

Written by Jamie | Last Updated September 6, 2019

Recent Posts