MATH40006 Practice Paper B Questions
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. This material's source date is 2026-08-30; it is later than the recorded activity ending 21 August 2026 and is not evidence of use during that period.
Source SHA-256: 9edd7acf80ae9c8c253a3cfe2c6142f6768698d687ac34eda725d65eee4274d5Source date: 2026-08-30
Notes — cell 1
# MATH40006 - Introduction to Computation ## Practice Paper Paper B - Candidate question notebook **REVIEW CANDIDATE - NOT PUBLISHED** - Practice duration: 90 minutes - Total: 75 marks; answer all three questions - Work in this single Jupyter notebook. - Use code cells for programs, tests, figures and requested output. - Use Markdown answer cells for explanations, invariants, derivations and comments. - No external files, network access, `input()` or package installation are required. - Before submission, restart the kernel and run all cells from top to bottom. The 90-minute/75-mark structure is a review assumption based on the nearest alternative-assessment precedent and must be checked against Tony's own notice.
Code — cell 2
%matplotlib inline
import sys
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import sympy as sp
import pandas as pd
print('Environment ready:', sys.version.split()[0], 'NumPy', np.__version__, 'Matplotlib', matplotlib.__version__)
print('SymPy', sp.__version__, 'pandas', pd.__version__)
Notes — cell 3
## Question 1 (30 marks): Vectorised absorbing random walks
A walk occupies an integer in `{0,1,...,L}`. From an interior point it moves
right with probability `p` and left otherwise, stopping at `0` or `L`. The
valid contract requires positive integer `n_walks,L`, integer `x0` in `[0,L]`,
`p` in `[0,1]`, and non-negative integer `max_steps`.
**(a) [3]** With `np.random.default_rng(seed)`, demonstrate a Boolean array
encoding right/left moves for several walkers.
**(b) [10]** Write
`absorbing_walks(n_walks,L,x0,p=0.5,max_steps=10000,seed=0)`. Vectorise over
walkers and loop only over time. Return Boolean `hit_right` and integer
absorption times. Raise a clear error if active walks remain at `max_steps`.
**(c) [5]** Test shapes, fixed-seed reproducibility, non-negative times,
immediate absorption at `x0=0,L`, and invalid inputs.
**(d) [5]** For 50000 fair walks with `L=20,x0=7,seed=20260829`, estimate the
right-hit probability and mean absorption time. Compare with `x0/L` and
`x0*(L-x0)`.
**(e) [4]** Construct the stated normal-approximation 95% interval. In
Markdown, check whether `7/20` lies inside and interpret cautiously. Random
agreement must not be a pass/fail assertion.
**(f) [3]** Plot an absorption-time histogram. In Markdown, comment on its
shape and explain the `max_steps` safety contract.Notes — cell 4
### Q1 code answers for parts (a)-(f)
Code — cell 5
# YOUR CODE HERE raise NotImplementedError()
Notes — cell 6
### Q1 written answers for parts (d)-(f) **YOUR ANSWER HERE**
Notes — cell 7
## Question 2 (35 marks): Horner evaluation, derivatives and Newton iteration `[c0,...,cn]` represents `p(x)=c0*x**n+...+cn` in descending powers. **(a) [6]** Write `horner(coefficients,x)` using `value=value*x+c`. Accept a real scalar or real NumPy array, reject an empty list and do not mutate input. **(b) [5]** Test a constant polynomial, vector `x`, repeated/zero coefficients and agreement with `np.polyval`. **(c) [4]** In Markdown, give the exact multiplication/addition counts and Theta time; contrast with rebuilding every power by repeated multiplication. **(d) [8]** Derive in Markdown and implement `horner_with_derivative(coefficients,x)`, using the old polynomial accumulator when updating the derivative. **(e) [6]** For coefficients `[1,1,-7,-1,6]` and 601 points on `[-3,3]`, verify `p` with `np.polyval`, verify `p'` with SymPy `diff` and `lambdify`, and plot both. **(f) [6]** Write guarded Newton iteration using extended Horner. Stop on a step below `tol`; reject a near-zero derivative and exhausted `max_iter`. Starting at `0.8`, verify the root and residual.
Notes — cell 8
### Q2 code answers for parts (a), (b), (d), (e) and (f)
Code — cell 9
# YOUR CODE HERE raise NotImplementedError()
Notes — cell 10
### Q2 written answers for parts (c) and (d) **YOUR ANSWER HERE**
Notes — cell 11
## Question 3 (10 marks): A pandas report for a supplied simulation log Run the non-assessed **GIVEN SETUP** cell below unchanged. It creates a reproducible synthetic run log, so this question has no external-file or Question 1 dependency. **(a) [3]** Build a DataFrame with one row per record and columns `side` (`'left'/'right'`) and `steps`. **(b) [4]** With `groupby` and `agg`, report count, mean, median and maximum duration for each side. Verify counts total `report_n`. **(c) [3]** Find the 99th percentile of `steps`, use `query` to select records at or above it, and count by side. In Markdown, explain why this conditional subset cannot estimate the unconditional right-side probability.
Code — cell 12
import numpy as np import pandas as pd # GIVEN SETUP - run this cell unchanged before Question 3. report_rng = np.random.default_rng(4000603) report_n = 50000 report_hit_right = report_rng.random(report_n) < 0.35 report_durations = report_rng.geometric(1 / 91.0, size=report_n)
Notes — cell 13
### Q3 code answers for parts (a)-(c)
Code — cell 14
# YOUR CODE HERE raise NotImplementedError()
Notes — cell 15
### Q3 written answer for part (c) **YOUR ANSWER HERE**