MATH40006 Practice Paper 2
English review edition prepared on 4 October 2026 from a preserved source copy. It is a later presentation, not the historical study interface. Source checks and difficulty judgements describe the original material author's own process; they do not indicate Imperial College London endorsement.
Source SHA-256: 42ce60b2004ae8b49098529d5b59aff5b99d6995d961eddb0d8a09d26eba844bSource date: 2026-08-06
Notes — cell 1
# MATH40006 Revised Historical-Coverage Mock 2 **Time allowed:** 60 minutes **Total marks:** 50 **Questions:** 3 (20 + 20 + 10) **Role:** 2026 Alternative bridge: row operations, determinants and data export Answer all questions in this Jupyter notebook. Show testing code and outputs. Unless the question explicitly requests an in-place operation, functions should return a value without changing their inputs.
Code — cell 2
import numpy as np
import sympy as sp
import matplotlib.pyplot as plt
import pandas as pd
from time import perf_counter
from copy import copy
import pickle
import ast
import math
sp.init_printing()
def row_add(mat,row_index,pivot_index,multiple):
mat[row_index,:]=mat[row_index,:]+multiple*mat[pivot_index,:]
Notes — cell 3
## Question 1 (20 marks) Use NumPy floating arrays throughout. (a) Write an in-place `row_multiply(mat,row_index,multiple)`. **[2]** (b) Write a safe in-place `row_swap(mat,i,j)`; NumPy row views must not overwrite each other. **[3]** (c) Using the supplied `row_add`, write `zero_column(mat,pivot_index)` for a non-zero pivot. **[3]** (d) Write `row_echelon_form(mat)` that copies its input and works for square, wide and tall matrices. **[6]** (e) Test on one 3 by 4 and one 4 by 3 matrix, and demonstrate that the original input remains unchanged. **[3]** (f) For an m by n matrix, state and justify the number of effective pivot columns that may need eliminating below the diagonal. **[3]**
Code — cell 4
# YOUR CODE HERE raise NotImplementedError()
Notes — cell 5
## Question 2 (20 marks) (a) Use your non-pivoting row-echelon function to write `my_det_basic(mat)`. **[3]** (b) Explain why its arithmetic work is Theta(n^3) on an n by n matrix. **[2]** (c) Briefly describe `np.argmax`. **[1]** (d) Write `zero_column_pivot(mat,pivot_index)` that chooses the largest absolute candidate in the pivot column, swaps rows when required, returns whether a swap occurred, and safely does nothing for an all-zero candidate column. **[5]** (e) Write `row_echelon_pivot(mat)` returning `(ref,sign)`, where `sign` is -1 after an odd number of swaps. **[4]** (f) Write `my_det(mat)` using the diagonal product and `sign`. **[3]** (g) Test on a zero-first-pivot matrix and a singular matrix against `np.linalg.det`. **[2]**
Code — cell 6
# YOUR CODE HERE raise NotImplementedError()
Notes — cell 7
## Question 3 (10 marks) The supplied `det_cofactor` recursively expands along the first row. (a) Create a nested timing dictionary for dimensions 3,4,5, using `np.linalg.det`, `my_det`, and `det_cofactor`. **[4]** (b) Export it to `revised_det_times.pkl`. **[2]** (c) Convert it to a DataFrame with dimensions as index. **[2]** (d) Export the DataFrame to `revised_det_times.csv` and confirm both files exist. **[2]**
Code — cell 8
def det_cofactor(mat):
if len(mat)==1: return mat[0,0]
return sum(((-1)**j)*mat[0,j]*det_cofactor(mat[1:,np.arange(len(mat))!=j]) for j in range(len(mat)))
# YOUR CODE HERE
raise NotImplementedError()