1. Write a Python function with the following interface that computes the matrix multiplication of two input matrices.
def matmul(matA, matB):
...

such that it returns the following result for the given input matrices.

matA =  [ [12, 7, 3]
, [4 , 4, 6]
, [5 , 3, 3]
]
matB =  [ [0, 1, 1, 7]
, [6, 7, 3, 1]
, [2, 5, 8, 3]
]
print(matmul(matA, matB))

[[ 48.  76.  57. 100.]
[ 36.  62.  64.  50.]
[ 24.  41.  38.  47.]]

2. Now, confirm the results of your function with the numpy library’s matmul function.
3. Now, benchmark the performance of the numpy matmul with the one you implemented for square matrices of rank: 2, 4, 16, 32, 64, 128, 256, 512, 1024.
To make the benchmark accurate and fair, we will have to first fill these matrices with random values.
You can do so via numpy as the following code snippet,
import numpy as np
matA = np.random.rand(len(matA), len(matA[0]))
matB = np.random.rand(len(matB), len(matB[0]))

Note that the matrix initializations must occur out of the timing sections of your benchmark.
To measure time, you can either use the Jupyter notebook’s %%timeit magic if you are with Jupyter environment or use the perf_counter function from the Python module time.
There are also many other ways to time your code. Feel free use any method that best suits your needs.
If you use the perf_counter function, remember to perform many matrix multiplications for small matrix ranks and gradually decrease the number of multiplications in your benchmark for larger matrix ranks.
Then you will have to properly normalize the timing for each matrix rank by the number repetitions of the matrix multiplication to ensure the numbers are comparable.
Repetitions are essential to capture the tiny time it takes to multiply small rank matrices.

4. Store the timing results for matrix multiplication for the two methods in an array.
Then use matplotlib python library to plot the two timing vectors vs. matrix ranks with which you did the benchmark.
Seek help from our lecture notes on plotting if you do not know how to make line/scatter plots in Python.