Checkpoint: Numerical Computing

Reviewed & published by Brayan K

This checkpoint consolidates the numerical computing skills you just learned — coordinate grids, axis manipulation, dates, polynomial fitting, vectorization, and einsum — into one recap, a multi-step build challenge, and a short quiz.

Part of the free NumPy course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

Work through the build challenge from the starter code, reveal the full solution to check yourself, then test your recall with the checkpoint quiz before moving on to the capstone.

What You've Learned in This Block

1 Quick Recap — The Tools at a Glance

Here is the whole block condensed into one reference table. Skim it, then put it to work in the build challenge below.

GoalCode
Build a coordinate gridX, Y = np.meshgrid(x, y)
Repeat a whole patternnp.tile(arr, 3)
Repeat each elementnp.repeat(arr, 3)
Make a column vectorarr[:, np.newaxis]
Transpose a matrixm.T
Move an axisnp.moveaxis(a, 0, -1)
A range of datesnp.arange(d0, d1, dtype="datetime64[D]")
Fit a polynomialnp.polyfit(x, y, deg)
Vectorize a functionnp.vectorize(func)
Matrix multiply with einsumnp.einsum("ij,jk->ik", A, B)

2 Warm-up: Recall the Patterns

Run this quick warm-up to refresh several tools from the block in one place before the bigger challenge.

import numpy as np

# Grid
x = np.array([0, 1, 2])
y = np.array([0, 1])
X, Y = np.meshgrid(x, y)
print(X.shape)                       # (2, 3)

# Repeat vs tile
print(np.repeat([1, 2], 2))          # [1 1 2 2]
print(np.tile([1, 2], 2))            # [1 2 1 2]

# Column vector + transpose
v = np.array([1, 2, 3])
print(v[:, np.newaxis].shape)        # (3, 1)

# einsum trace
M = np.array([[1, 2], [3, 4]])
print(np.einsum("ii->", M))          # 5

# ✅ Expected output:
# (2, 3)
# [1 1 2 2]
# [1 2 1 2]
# (3, 1)
# 5

🏗️ Build Challenge: From Grid to Trend to einsum

Put four tools from this block together in a single program:

Start from the scaffold, fill in the blanks, and run it. Then open the solution to compare.

import numpy as np

# --- Step 1: coordinate grid and a surface ---
x = np.linspace(-1, 1, 3)
y = np.linspace(-1, 1, 3)
X, Y = np.___(x, y)          # fill in: build the grid
Z = X**2 + Y**2
print("Grid surface shape:", Z.shape)   # (3, 3)

# --- Step 2: fit a trend to noisy data ---
rng = np.random.default_rng(42)
xs = np.linspace(0, 10, 40)
ys = 4 * xs + 1 + rng.normal(0, 1, size=xs.size)
coeffs = np.polyfit(xs, ys, ___)        # fill in: degree for a line
print("Recovered slope ~", round(coeffs[0], 1))   # ~ 4.0

# --- Step 3: weighted total with einsum ---
scores = np.array([[2, 4],
                   [1, 3]])
weights = np.array([10, 1])
totals = np.einsum("ij,j->i", scores, weights)
print("Weighted totals:", totals)       # [24 13]
import numpy as np

# --- Step 1: coordinate grid and a surface ---
x = np.linspace(-1, 1, 3)
y = np.linspace(-1, 1, 3)
X, Y = np.meshgrid(x, y)           # build the grid
Z = X**2 + Y**2
print("Grid surface shape:", Z.shape)   # (3, 3)
print(Z)
# [[2. 1. 2.]
#  [1. 0. 1.]
#  [2. 1. 2.]]

# --- Step 2: fit a trend to noisy data ---
rng = np.random.default_rng(42)
xs = np.linspace(0, 10, 40)
ys = 4 * xs + 1 + rng.normal(0, 1, size=xs.size)
coeffs = np.polyfit(xs, ys, 1)     # degree 1 -> straight line
slope, intercept = coeffs
print("Recovered slope ~", round(slope, 1))       # ~ 4.0
print("Recovered intercept ~", round(intercept))  # ~ 1

trend = np.poly1d(coeffs)
print("Predicted at x=5:", round(float(trend(5))))   # ~ 21

# --- Step 3: weighted total with einsum ---
scores = np.array([[2, 4],
                   [1, 3]])
weights = np.array([10, 1])
totals = np.einsum("ij,j->i", scores, weights)
print("Weighted totals:", totals)  # [24 13]
print("Matches matvec:", np.array_equal(totals, scores @ weights))  # True

🎯 YOUR TURN: Fill in the Blank

Combine a column and a row vector to broadcast a full addition table by filling in the indexing token.

import numpy as np

a = np.array([1, 2, 3])
b = np.array([10, 20, 30])

# Make 'a' a COLUMN by adding a new axis at the end
table = a[:, np.___] + b[np.newaxis, :]

print(table)
# Expected output:
# [[11 21 31]
#  [12 22 32]
#  [13 23 33]]

Answer: newaxis (so a[:, np.newaxis]). A column plus a row broadcasts into a 2D grid.

! Common Errors Across This Block

❌ Confusing tile with repeat

They produce very different layouts from the same input:

np.tile([1, 2], 3)     # [1 2 1 2 1 2]
np.repeat([1, 2], 3)   # [1 1 1 2 2 2]

✅ Fix: tile stamps the whole block; repeat duplicates each element. Pick by the layout you need.

❌ Reading polyfit coefficients backwards

polyfit returns highest power first, so for a line it is [slope, intercept].

✅ Fix: unpack as slope, intercept = coeffs for a degree-1 fit.

❌ Wrong einsum subscripts for matrix multiply

The shared axis must reuse a letter so it is contracted.

✅ Fix: matrix multiply is "ij,jk->ik" — the repeated j is summed away.

🎯 Mini Challenge: Distance Grid with a Trend

Build a grid, measure distance to a center, then summarize each row — mixing meshgrid, broadcasting, and axis sums.

import numpy as np

# 5x5 grid of coordinates
coords = np.linspace(0, 4, 5)
X, Y = np.meshgrid(coords, coords)

# Distance from the center (2, 2) at every point
dist = np.sqrt((X - 2)**2 + (Y - 2)**2)
print("Grid shape:", dist.shape)        # Grid shape: (5, 5)
print("Closest:", round(float(dist.min()), 1))   # Closest: 0.0

# Average distance per row (axis=1)
row_means = dist.mean(axis=1)
print("Row means shape:", row_means.shape)   # Row means shape: (5,)

# Transpose check: distances are symmetric about the center grid
print("Symmetric:", np.allclose(dist, dist.T))   # Symmetric: True

# ✅ Expected output:
# Grid shape: (5, 5)
# Closest: 0.0
# Row means shape: (5,)
# Symmetric: True

📝 Checkpoint Quiz

Answer each in your head, then expand to check.

Two 2D arrays, X and Y. X holds the x-coordinate of every grid point and Y holds the y-coordinate, so X[i, j] paired with Y[i, j] is one (x, y) point — letting you evaluate f(x, y) over the whole grid at once.

np.tile([1, 2], 3) repeats the whole block to give [1, 2, 1, 2, 1, 2]. np.repeat([1, 2], 3) duplicates each element to give [1, 1, 1, 2, 2, 2].

Add a trailing axis with v[:, np.newaxis] (or v[:, None], or v.reshape(-1, 1)). np.expand_dims(v, axis=1) does the same thing.

No. .T and np.transpose return a view that shares the original data, so it is cheap — but writing into the transpose also writes into the original. Use .copy() for an independent array.

Highest power first, so [slope, intercept]. In general np.polyfit returns coefficients from the highest power down to the constant term.

np.einsum("ii->", M). The repeated i with no output letter selects the diagonal and sums it. To keep the diagonal as a vector instead, use "ii->i".

❓ Frequently Asked Questions

Checkpoint complete — numerical computing mastered!

You recapped meshgrid, tile and repeat, newaxis, transpose and swapaxes, datetime64, polynomials, vectorize, and einsum, and you wired several of them together in a build challenge.

Practice quiz

What does np.meshgrid(x, y) return?

  • A single flattened array of coordinates
  • One 2D array of distances
  • Two 2D arrays X and Y holding the x and y coordinate of every grid point
  • A list of (x, y) tuples

Answer: Two 2D arrays X and Y holding the x and y coordinate of every grid point. meshgrid returns two 2D arrays. X[i, j] paired with Y[i, j] is one (x, y) point, so you can evaluate f(x, y) over the whole grid at once.

How do np.tile and np.repeat differ on [1, 2] with count 3?

  • tile gives [1, 2, 1, 2, 1, 2]; repeat gives [1, 1, 1, 2, 2, 2]
  • tile gives [1, 1, 1, 2, 2, 2]; repeat gives [1, 2, 1, 2, 1, 2]
  • Both give [1, 2, 1, 2, 1, 2]
  • Both give [1, 1, 1, 2, 2, 2]

Answer: tile gives [1, 2, 1, 2, 1, 2]; repeat gives [1, 1, 1, 2, 2, 2]. tile stamps the whole block, giving [1, 2, 1, 2, 1, 2]. repeat duplicates each element in place, giving [1, 1, 1, 2, 2, 2].

How do you turn a shape-(3,) vector v into a column vector of shape (3, 1)?

  • v[np.newaxis, :]
  • v.flatten()
  • np.tile(v, 1)
  • v[:, np.newaxis]

Answer: v[:, np.newaxis]. Adding a trailing axis with v[:, np.newaxis] (or v.reshape(-1, 1)) makes a (3, 1) column. Putting newaxis first would give a (1, 3) row instead.

Does transposing an array with .T copy its data?

  • Yes, it always makes a copy
  • No, it returns a view that shares the original data
  • Only for arrays larger than 1000 elements
  • Only for integer arrays

Answer: No, it returns a view that shares the original data. .T and np.transpose return a view that shares memory, so it is cheap — but writing into the transpose also writes into the original. Use .copy() for an independent array.

For a degree-1 np.polyfit, in what order are the returned coefficients?

  • [slope, intercept]
  • [intercept, slope]
  • Alphabetical by name
  • Random unless you sort them

Answer: [slope, intercept]. polyfit returns coefficients highest power first, so a line gives [slope, intercept]. Unpack as slope, intercept = coeffs.

Which einsum string computes the trace of a square matrix M?

  • np.einsum('ij->ji', M)
  • np.einsum('ii->i', M)
  • np.einsum('ii->', M)
  • np.einsum('ij,jk->ik', M, M)

Answer: np.einsum('ii->', M). The repeated i with no output letter selects the diagonal and sums it, giving the trace. 'ii->i' would keep the diagonal as a vector instead.

What does np.einsum('ij,jk->ik', A, B) compute?

  • Element-wise product of A and B
  • Standard matrix multiplication of A and B
  • The transpose of A
  • The sum of every element

Answer: Standard matrix multiplication of A and B. The shared index j is repeated and summed away, while i and k remain — exactly the definition of matrix multiplication.

Is np.vectorize a true performance optimization?

  • Yes, it compiles the function to machine code
  • Yes, it always runs on the GPU
  • Only for string functions
  • No, it is mainly a convenience wrapper and is not a real speed-up

Answer: No, it is mainly a convenience wrapper and is not a real speed-up. np.vectorize wraps a Python function so it broadcasts over arrays, but it still loops in Python under the hood — it is for convenience, not speed.

Which dtype lets you create a range of calendar dates with np.arange?

  • 'float64'
  • 'datetime64[D]'
  • 'int32'
  • 'object'

Answer: 'datetime64[D]'. np.arange(d0, d1, dtype='datetime64[D]') steps day by day between two dates. datetime64 also supports date subtraction and other date math.

After building X, Y = np.meshgrid(x, y) with len(x)=3 and len(y)=2, what is X.shape?

  • (3, 2)
  • (3,)
  • (2, 3)
  • (6,)

Answer: (2, 3). With the default indexing, the output rows follow y and the columns follow x, so X has shape (len(y), len(x)) = (2, 3).

Continue this course

Frequently asked questions

What does this checkpoint cover?

It reviews the numerical computing block of the NumPy course: building coordinate grids with meshgrid, repeating arrays with tile and repeat, adding and removing axes with newaxis and squeeze, transposing and reordering axes, working with datetime64 dates, fitting and evaluating polynomials, vectorizing Python functions, and expressing operations with einsum. The build challenge ties several of these together in one program.

How should I use the build challenge?

Try writing it yourself first from the starter code, running it and checking the printed shapes and values as you go. Only open the Show solution panel once you have made a genuine attempt. Comparing your version against the full solution is where most of the learning happens, because you will see which steps you had right and which conventions you missed.

I got a broadcasting or shape error. What now?

Print the .shape of each array right before the line that fails. Most errors in this material come from a missing axis or a transpose, so check whether you need newaxis to make a column, whether a transpose put the axes in the order you expect, and whether two shapes line up under the broadcasting rules (equal or one of them is 1).

What comes after this checkpoint?

The capstone project, Image as an Array, where you treat a picture as a NumPy array and apply many of the tools from the whole course at once: indexing, broadcasting, axis operations, and reshaping. This checkpoint is the last stop before you put everything together on a single realistic project.