Level 1 — RecognitionScientific Computing (Python)

Scientific Computing (Python)

20 minutes30 marksprintable — key stays hidden on paper

Chapter: 5.4 Scientific Computing (Python) Level: 1 — Recognition (MCQ / Matching / True-False with Justification) Time Limit: 20 minutes Total Marks: 30


Section A — Multiple Choice (1 mark each) [10 marks]

Q1. For a NumPy array a = np.zeros((3, 4)) of dtype float64, what are its strides?

  • (a) (4, 3)
  • (b) (32, 8)
  • (c) (8, 32)
  • (d) (12, 4)

Q2. Which function creates an array of 5 evenly spaced points including both endpoints 0 and 1?

  • (a) np.arange(0, 1, 5)
  • (b) np.linspace(0, 1, 5)
  • (c) np.zeros(5)
  • (d) np.random.rand(5)

Q3. Given a = np.array([10, 20, 30, 40]), what does a[a > 15] return?

  • (a) array([20, 30, 40])
  • (b) array([False, True, True, True])
  • (c) array([10])
  • (d) array([1, 2, 3])

Q4. Adding arrays of shapes (3, 1) and (1, 4) produces a result of shape:

  • (a) (3, 4)
  • (b) (1, 1)
  • (c) error
  • (d) (4, 3)

Q5. Which SciPy function solves a linear system Ax=bAx = b and generally uses more numerically stable LAPACK routines than the NumPy equivalent?

  • (a) numpy.dot
  • (b) scipy.linalg.solve
  • (c) scipy.integrate.quad
  • (d) scipy.optimize.fsolve

Q6. scipy.integrate.quad(f, a, b) is used for:

  • (a) solving ODEs
  • (b) definite numerical integration of a 1-D function
  • (c) matrix factorization
  • (d) FFT

Q7. In the classical RK4 method, the update for one step uses a weighted average of slopes with weights:

  • (a) 14,14,14,14\tfrac{1}{4},\tfrac{1}{4},\tfrac{1}{4},\tfrac{1}{4}
  • (b) 16,13,13,16\tfrac{1}{6},\tfrac{1}{3},\tfrac{1}{3},\tfrac{1}{6}
  • (c) 12,12,0,0\tfrac{1}{2},\tfrac{1}{2},0,0
  • (d) 1,0,0,01,0,0,0

Q8. Which sparse format is most efficient for row slicing and matrix–vector products?

  • (a) CSC
  • (b) CSR
  • (c) COO
  • (d) DIA

Q9. The composite trapezoidal rule on nn equal subintervals of width hh has an error term of order:

  • (a) O(h)O(h)
  • (b) O(h2)O(h^2)
  • (c) O(h4)O(h^4)
  • (d) O(h3)O(h^3)

Q10. In Matplotlib's object-oriented architecture, the container that holds one set of axes, ticks, and plotted data is the:

  • (a) Figure
  • (b) Axes
  • (c) Canvas
  • (d) Backend

Section B — Matching (1 mark each) [10 marks]

Q11–Q15. Match each SciPy/library tool (left) to its purpose (right). Write the letter.

# Tool Purpose
Q11 scipy.optimize.curve_fit A Symbolic differentiation & ODE solving
Q12 np.fft.fft B Least-squares fitting of a model to data
Q13 sympy.diff C Fast (discrete) Fourier transform
Q14 scipy.stats.ttest_ind D LU / QR / Schur decompositions
Q15 scipy.linalg.lu E Two-sample hypothesis test

Q16–Q20. Match each array/function (left) to what it produces (right). Write the letter.

# Expression Result / Role
Q16 np.arange(0, 6, 2) A matplotlib.animation.FuncAnimation
Q17 np.linalg.eig(A) B array([0, 2, 4])
Q18 Repeatedly redraw frames for a movie C eigenvalues and eigenvectors
Q19 pandas.DataFrame.groupby D image / heatmap from a 2-D array
Q20 plt.imshow E split-apply-combine aggregation

Section C — True / False with one-line justification (2 marks each: 1 T/F + 1 justification) [10 marks]

Q21. Floating-point addition is associative, so (a + b) + c == a + (b + c) always holds exactly.

Q22. Vectorized NumPy operations are typically faster than equivalent pure-Python for loops because the loop runs in compiled C over contiguous memory.

Q23. Broadcasting requires both arrays to have identical shapes.

Q24. np.linalg.det of a singular matrix is exactly 0.0 in floating point.

Q25. The Newton–Raphson method requires the derivative f(x)f'(x) and generally converges faster (quadratically) than bisection near a simple root.


Answer keyMark scheme & solutions

Section A

Q1 — (b) (32, 8). (1) Row-major float64 (8 bytes). Moving one column = 8 bytes; one row = 4 columns × 8 = 32 bytes → strides (32, 8).

Q2 — (b) np.linspace(0, 1, 5). (1) linspace includes both endpoints by default and takes a count, not a step. Gives [0, .25, .5, .75, 1].

Q3 — (a) array([20, 30, 40]). (1) Boolean mask a>15 = [F,T,T,T]; indexing selects the True elements.

Q4 — (a) (3, 4). (1) Broadcasting stretches each size-1 dimension: (3,1) and (1,4)(3,4).

Q5 — (b) scipy.linalg.solve. (1) scipy.linalg wraps LAPACK and is generally preferred for stability over numpy.linalg.

Q6 — (b) definite numerical integration of a 1-D function. (1) quad performs adaptive Gaussian quadrature.

Q7 — (b) 16,13,13,16\tfrac16,\tfrac13,\tfrac13,\tfrac16. (1) Classical RK4: yn+1=yn+h6(k1+2k2+2k3+k4)y_{n+1}=y_n+\tfrac h6(k_1+2k_2+2k_3+k_4).

Q8 — (b) CSR. (1) Compressed Sparse Row is optimized for row access and fast SpMV.

Q9 — (b) O(h2)O(h^2). (1) Composite trapezoidal global error is O(h2)O(h^2).

Q10 — (b) Axes. (1) A Figure can hold multiple Axes; the Axes holds the actual plot region, ticks, and data.

Section B

Q11 → B (curve_fit = least-squares model fitting). (1) Q12 → C (fft = fast Fourier transform). (1) Q13 → A (sympy.diff = symbolic calculus). (1) Q14 → E (ttest_ind = two-sample hypothesis test). (1) Q15 → D (lu = LU decomposition). (1)

Q16 → B (np.arange(0,6,2) = [0,2,4]). (1) Q17 → C (eig returns eigenvalues & eigenvectors). (1) Q18 → A (FuncAnimation redraws frames). (1) Q19 → E (groupby = split-apply-combine). (1) Q20 → D (imshow = image/heatmap of 2-D array). (1)

Section C

Q21 — FALSE. (1) Justification (1): Rounding at each step means association order changes the result; classic example (0.1+0.2)+0.3 ≠ 0.1+(0.2+0.3) in double precision.

Q22 — TRUE. (1) Justification (1): The inner loop executes in optimized C on contiguous memory, avoiding per-element Python object overhead.

Q23 — FALSE. (1) Justification (1): Broadcasting only needs compatible dimensions (equal or one of them 1); shapes need not be identical.

Q24 — FALSE. (1) Justification (1): Floating-point rounding usually yields a tiny nonzero determinant (e.g. 1e-16), not exact 0; check via condition number/rank instead.

Q25 — TRUE. (1) Justification (1): Newton uses xn+1=xnf(xn)/f(xn)x_{n+1}=x_n-f(x_n)/f'(x_n); near a simple root it converges quadratically, faster than bisection's linear (halving) rate.

[
  {"claim":"Q1 strides for float64 (3,4) C-order are (32,8)","code":"import numpy as _np; a=_np.zeros((3,4),dtype='float64'); result = a.strides==(32,8)"},
  {"claim":"Q3 boolean mask returns [20,30,40]","code":"import numpy as _np; a=_np.array([10,20,30,40]); result = list(a[a>15])==[20,30,40]"},
  {"claim":"Q4 broadcasting (3,1)+(1,4) -> (3,4)","code":"import numpy as _np; r=_np.ones((3,1))+_np.ones((1,4)); result = r.shape==(3,4)"},
  {"claim":"Q16 np.arange(0,6,2) equals [0,2,4]","code":"import numpy as _np; result = list(_np.arange(0,6,2))==[0,2,4]"},
  {"claim":"Q21 float addition not associative for 0.1,0.2,0.3","code":"result = ((0.1+0.2)+0.3 != 0.1+(0.2+0.3))"}
]