Back to courses

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: 42ce60b2004ae8b49098529d5b59aff5b99d6995d961eddb0d8a09d26eba844b
Source 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()