The Range Finder Meets the Tape Measure

calibration · bias · standard deviation · median · outliers

Before a robot trusts its new range finder, an engineer points it at a wall exactly true_d metres away (measured with a tape) and logs a batch of readings. Two numbers describe the sensor:

  • its bias: how far its readings are off on average, mean - true_d (positive means it reads long);
  • its spread: the sample standard deviation of the readings, \sqrt{\sum (r - \bar r)^2 / (n - 1)}.

Now and then the sensor picks up a stray echo (a person walking past, a reflection from the floor). Such readings must not spoil the two numbers, so the engineer uses this rule:

  1. Find the median of all the readings (for an even count, the mean of the two middle values).
  2. A reading is an outlier when it differs from the median by more than tol metres. A reading exactly tol away is kept.
  3. Compute the bias and the spread from the kept readings only.

Write calibrate_range(readings, true_d, tol) that returns a tuple (bias, spread, outliers), where outliers is the list of the positions (indices) of the outliers in readings, in increasing order. If no reading is kept, bias is None; if fewer than two are kept, spread is None.

Examples

Input:  readings = [2.04, 2.06, 1.98, 2.03, 3.10, 2.05, 2.01], true_d = 2.0, tol = 0.2
Output: (0.02833333333333332, 0.029268868558020272, [4])
Explanation: the median is 2.04, and 3.10 is 1.06 away from it. The six kept readings
average 2.02833, so the sensor reads 2.8 cm long, with a spread of 2.9 cm.

Input:  readings = [1.52, 0.40, 1.47, 1.55], true_d = 1.5, tol = 0.1
Output: (0.01333333333333342, 0.040414518843273836, [1])
Explanation: the median is (1.47 + 1.52) / 2 = 1.495; the echo at 0.40 is dropped.

Input:  readings = [5.0], true_d = 4.9, tol = 0.1
Output: (0.09999999999999964, None, [])

Constraints

  • answers are compared with a tolerance of 1e-6; do not round

Goals

  • Measure a sensor's bias against a known distance and its spread from repeated readings
  • Use the median to spot stray readings that would spoil the mean
  • Compute the sample standard deviation of the readings that remain
Starting Python…