Verify a Numerical Pipeline
Detect a wrong-but-running orientation by checking shapes, named axes, finite values, centered means, and one expected score.
A numerical pipeline can run without raising an exception and still answer the wrong question. Shape checks catch some mistakes. Finite-value checks catch others. Neither can prove that an operation used the intended axis. We need checks for values, shapes, and meaning together.
We will verify this complete calculation:
The intended axes are:
raw,calibrated, andcentered: observations, sensors;weights: sensors;scores: observations.
State the Pipeline Contract
Before checking particular numbers, record the required shapes:
These checks establish that the pipeline has three observations, two sensors,
one preserved summary row, and one score per observation. The variable names
record what the sizes mean. An assertion such as centered.shape == (3, 2) is
weaker when nobody has said which axis is observations and which is sensors.
Check that every numerical stage contains ordinary finite values:
np.isfinite rejects NaN, positive infinity, and negative infinity. It does
not say whether a finite number is correct. That requires checks tied to the
calculation.
Q1. Choose checks for different failures
Which set of statements assigns a distinct job to shape, finite-value, and meaning checks?
Select one choice, then check.
HintAsk what each check can observe
A shape does not contain axis meaning, and a finite number is not necessarily the intended number.
SolutionUse complementary checks
Shape checks verify layout. np.isfinite detects non-finite values. A
calculation-specific invariant, such as near-zero per-sensor means, checks
whether centering used the intended axis.
Catch a Wrong Operation That Still Runs
This alternative uses axis=1:
It runs. wrong_centered still has shape (3, 2), wrong_scores still has
shape (3,), and every value is finite. Yet axis 1 means sensors, so the code
subtracts one mean from each observation row. The requirement was to subtract
one mean from each sensor column.
The wrong result is:
[[-2.0, 2.0],
[-2.5, 2.5],
[-3.0, 3.0]]
Its row means are zero, but its per-sensor means are [-2.5, 2.5]. The
pipeline needs a per-sensor invariant:
assert np.allclose(centered.mean(axis=0), np.zeros(sensor_count))
For the correct centered table,
[[-1.0, -2.0],
[ 0.0, 0.0],
[ 1.0, 2.0]]
the per-sensor means are both zero. np.allclose allows for the small rounding
differences that can appear in floating-point calculations. Here the expected
values are exactly zero, but the same check remains appropriate when the input
does not produce exact binary results.
Q2. Identify the wrong-but-running axis
The program uses calibrated.mean(axis=1, keepdims=True) and returns a
(3, 2) centered table. Which evidence exposes the mistake?
Select one choice, then check.
HintTest the stated centering question
Correct per-sensor centering leaves each sensor column with a mean near zero.
SolutionThe per-sensor invariant fails
wrong_centered.mean(axis=0) returns [-2.5, 2.5]. The expected per-sensor
means are [0.0, 0.0], so the axis choice is wrong.
Hand-Check One Output Boundary
The correct first centered row is [-1.0, -2.0]. Its score should be:
(-1.0 × 1.0) + (-2.0 × 0.5) = -2.0
Check that known value and the complete score array:
The first assertion links code to a calculation we can inspect without NumPy. The second checks that all three observations produce the accepted result. Together with the shape, finite-value, and centering checks, this gives more evidence than any one assertion alone.
A reversed input needs the same semantic care. If an incoming table is known
to have axes (sensors, observations) and shape (2, 3), recover the required
layout with incoming.T. Do not use reshape(3, 2): reshape regroups entries,
while transpose exchanges the two named axes. Chapter 10 established that
distinction; here it is one checked pipeline boundary rather than a new topic.
Q3. Repair and verify the complete pipeline
Repair the centering axis, then add the missing checks for finite output, near-zero per-sensor means, and the hand-checked score array.
Editable Python
Ready to run.
HintCheck the intended axes and known values
Center with axis=0. Use np.isfinite(scores).all(), compare the per-sensor
means with np.zeros(2), and compare scores with [-2.0, 0.0, 2.0].
SolutionCombine shape, finite, invariant, and value evidence
A trustworthy numerical pipeline states its axis meanings, checks every expected shape, rejects non-finite values, tests a calculation-specific invariant, and compares at least one output with visible arithmetic. These checks catch operations that crash and operations that run while answering the wrong question.
References
- NumPy documentation:
numpy.isfinite— identifying finite numerical entries. - NumPy documentation:
numpy.allclose— tolerance-aware comparison of numerical arrays.