The suspension computer of an electric car reads a ride-height sensor 100 times a second. The raw readings x jump about on every pebble, so the firmware passes them through a small digital filter. Like most digital systems, the filter is a difference equation: each new output is a weighted sum of the last two outputs, the newest input and the input before it,
y[k] = a1 * y[k-1] + a2 * y[k-2] + b0 * x[k] + b1 * x[k-1]
The coefficients a1, a2, b0, b1 are fixed numbers chosen by the designer. Because the filter remembers its own past outputs, a single reading keeps echoing through it for a while: that memory is what makes it smooth.
The first outputs need values from before the log started. These initial conditions are given as y_init = (y[-2], y[-1]), the two outputs just before sample 0, in time order. The input before the log was zero: x[-1] = 0.
Write filter_output(a1, a2, b0, b1, x, y_init) that returns the list of outputs y[0], y[1], ..., y[n-1], one for every input sample. Press Run with plot(x, kind="stem") and plot(filter_output(...), kind="stem") to compare the input with the output.
Examples
Input: a1 = 1.2, a2 = -0.5, b0 = 0.1, b1 = 0.2, x = [1, 1, 1, 1], y_init = (0, 0)
Output: [0.1, 0.42, 0.754, 0.9948]
Explanation: y[0] = 1.2*0 - 0.5*0 + 0.1*1 + 0.2*0 = 0.1
y[1] = 1.2*0.1 - 0.5*0 + 0.1*1 + 0.2*1 = 0.42
y[2] = 1.2*0.42 - 0.5*0.1 + 0.1 + 0.2 = 0.754
Input: a1 = 0.5, a2 = 0, b0 = 1, b1 = 0, x = [0, 0, 0], y_init = (0, 4)
Output: [2.0, 1.0, 0.5]
Explanation: no input at all: the output left over from before the log halves every sample.
Constraints
- answers are compared with a tolerance of
1e-6; do not round
Goals
- Compute the output of a difference equation one sample at a time
- Keep the last two outputs and the last input as the state of the system
- Use initial conditions for the samples before the log starts