FA-91561 / Digital signal filters / Open access
Polyphase interpolator reads wrapped input history · case 01
The first outputs include contributions from the last input samples.
ROOT CAUSE
The m - j >= 0 guard is missing, so negative indices wrap to the end of the input.
VERIFIED REPAIR
Only use x[m - j] for m - j >= 0.
Unsuccessful approach: The attempted repair requires m - j > 0, dropping the first input sample.
Case contract
Input [h, L, samples] (integers). Zero-stuff by L and filter with h, scaled by gain L: y[mL + p] = L sum_j h[jL + p] x[m - j]; return len(samples) * L outputs in time order.
Why this case matters
Interpolators feed DACs and sample-rate converters; gain and phase-indexing slips cause level errors and imaging.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
h, L, xs = x
out = []
for m in range(len(xs)):
for p in range(L):
acc = 0
j = 0
while j * L + p < len(h):
acc += h[j * L + p] * xs[m - j]
j += 1
out.append(L * acc)
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: partial phase tail', [[1, 2, 3], 2, [1, 1]], [2, 4, 8, 4]], ['regression: L=3 taps 7', [[1, 1, 1, 1, 1, 1, 1], 3, [1, 2]], [3, 3, 3, 9, 9, 9]], ['repair check: impulse L=2', [[1, 2, 3, 4], 2, [1, 0, 0]], [2, 4, 6, 8, 0, 0]], ['control: random interpolator 5', [[0], 3, [2, 0]], [0, 0, 0, 0, 0, 0]], ['control: random interpolator 11', [[2, 4, -1, -3], 4, [0, -4, 1]], [0, 0, 0, 0, -32, -64, 16, 48, 8, 16, -4, -12]], ['regression: random interpolator 0', [[3, -1, -1, 2, 3], 3, [-4, -4, 2]], [-36, 12, 12, -60, -24, 12, -6, -42, -6]], ['regression: random interpolator 1', [[3, -2, 3, -3, 2, 2], 4, [3]], [36, -24, 36, -36]]], [['regression: random interpolator 1', [[3, -2, 3, -3, 2, 2], 4, [3]], [36, -24, 36, -36]], ['regression: random interpolator 4', [[-3, 3, 2, -1, 1], 4, [1]], [-12, 12, 8, -4]], ['regression: L=3 taps 7', [[1, 1, 1, 1, 1, 1, 1], 3, [1, 2]], [3, 3, 3, 9, 9, 9]], ['control: random interpolator 5', [[0], 3, [2, 0]], [0, 0, 0, 0, 0, 0]], ['control: random interpolator 11', [[2, 4, -1, -3], 4, [0, -4, 1]], [0, 0, 0, 0, -32, -64, 16, 48, 8, 16, -4, -12]], ['regression: random interpolator 0', [[3, -1, -1, 2, 3], 3, [-4, -4, 2]], [-36, 12, 12, -60, -24, 12, -6, -42, -6]], ['regression: random interpolator 8', [[0, -2, 3, 3, -2, 4, -3], 3, [4, 2]], [0, -24, 36, 36, -36, 66]]], [['regression: random interpolator 13', [[-2, 3, 3, -1, -1], 3, [1, 2, 3, -2, -2]], [-6, 9, 9, -15, 15, 18, -24, 21, 27, 3, -27, -18, 18, -12, -18]], ['regression: random interpolator 14', [[4, -1, 3, -1, 0, -2, 4], 3, [1, 3, 5]], [12, -3, 9, 33, -9, 21, 63, -15, 27]], ['regression: random interpolator 1', [[3, -2, 3, -3, 2, 2], 4, [3]], [36, -24, 36, -36]], ['control: random interpolator 5', [[0], 3, [2, 0]], [0, 0, 0, 0, 0, 0]], ['control: random interpolator 11', [[2, 4, -1, -3], 4, [0, -4, 1]], [0, 0, 0, 0, -32, -64, 16, 48, 8, 16, -4, -12]], ['regression: random interpolator 4', [[-3, 3, 2, -1, 1], 4, [1]], [-12, 12, 8, -4]], ['regression: random interpolator 8', [[0, -2, 3, 3, -2, 4, -3], 3, [4, 2]], [0, -24, 36, 36, -36, 66]]], [['regression: random interpolator 17', [[4, 4, 3, 1, -3, 2, 1], 4, [4]], [64, 64, 48, 16]], ['regression: random interpolator 18', [[-2, -1, -2, 0, 2], 2, [-4, 3, 1, 5, 1]], [16, 8, 4, -6, -32, -2, -12, -10, -20, -2]], ['repair check: random interpolator 3', [[-3], 4, [2, 2, 4, -3, -2]], [-24, 0, 0, 0, -24, 0, 0, 0, -48, 0, 0, 0, 36, 0, 0, 0, 24, 0, 0, 0]], ['control: random interpolator 5', [[0], 3, [2, 0]], [0, 0, 0, 0, 0, 0]], ['control: random interpolator 11', [[2, 4, -1, -3], 4, [0, -4, 1]], [0, 0, 0, 0, -32, -64, 16, 48, 8, 16, -4, -12]], ['regression: random interpolator 4', [[-3, 3, 2, -1, 1], 4, [1]], [-12, 12, 8, -4]], ['regression: random interpolator 8', [[0, -2, 3, 3, -2, 4, -3], 3, [4, 2]], [0, -24, 36, 36, -36, 66]]], [['regression: random interpolator 23', [[3, 2, 1, -1, 3, -1], 2, [-3, -1]], [-18, -12, -12, 2]], ['regression: random interpolator 26', [[4, -3, 2, -2], 3, [2, -4, 0, 4, -3]], [24, -18, 12, -60, 36, -24, 24, 0, 0, 48, -36, 24, -60, 27, -18]], ['repair check: random interpolator 6', [[2, -3, 2, -3], 4, [1, 5]], [8, -12, 8, -12, 40, -60, 40, -60]], ['control: random interpolator 5', [[0], 3, [2, 0]], [0, 0, 0, 0, 0, 0]], ['control: random interpolator 11', [[2, 4, -1, -3], 4, [0, -4, 1]], [0, 0, 0, 0, -32, -64, 16, 48, 8, 16, -4, -12]], ['regression: random interpolator 8', [[0, -2, 3, 3, -2, 4, -3], 3, [4, 2]], [0, -24, 36, 36, -36, 66]], ['regression: random interpolator 13', [[-2, 3, 3, -1, -1], 3, [1, 2, 3, -2, -2]], [-6, 9, 9, -15, 15, 18, -24, 21, 27, 3, -27, -18, 18, -12, -18]]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: partial phase tail | [8, 4, 8, 4] | [2, 4, 8, 4] | Failed |
| regression: L=3 taps 7 | [12, 9, 9, 15, 9, 9] | [3, 3, 3, 9, 9, 9] | Failed |
| repair check: impulse L=2 | [2, 4, 6, 8, 0, 0] | [2, 4, 6, 8, 0, 0] | Passed |
| control: random interpolator 5 | [0, 0, 0, 0, 0, 0] | [0, 0, 0, 0, 0, 0] | Passed |
| control: random interpolator 11 | [0, 0, 0, 0, -32, -64, 16, 48, 8, 16, -4, -12] | [0, 0, 0, 0, -32, -64, 16, 48, 8, 16, -4, -12] | Passed |
| regression: random interpolator 0 | [-24, 30, 12, -60, -24, 12, -6, -42, -6] | [-36, 12, 12, -60, -24, 12, -6, -42, -6] | Failed |
| regression: random interpolator 1 | [60, 0, 36, -36] | [36, -24, 36, -36] | Failed |
SHA-256 / 035476609a18ec226c88bec05bf2b890b76b36af7f9861a8e517f95d515b0ea5
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
h, L, xs = x
out = []
for m in range(len(xs)):
for p in range(L):
acc = 0
j = 0
while j * L + p < len(h):
if m - j > 0:
acc += h[j * L + p] * xs[m - j]
j += 1
out.append(L * acc)
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: partial phase tail', [[1, 2, 3], 2, [1, 1]], [2, 4, 8, 4]], ['regression: L=3 taps 7', [[1, 1, 1, 1, 1, 1, 1], 3, [1, 2]], [3, 3, 3, 9, 9, 9]], ['repair check: impulse L=2', [[1, 2, 3, 4], 2, [1, 0, 0]], [2, 4, 6, 8, 0, 0]], ['control: random interpolator 5', [[0], 3, [2, 0]], [0, 0, 0, 0, 0, 0]], ['control: random interpolator 11', [[2, 4, -1, -3], 4, [0, -4, 1]], [0, 0, 0, 0, -32, -64, 16, 48, 8, 16, -4, -12]], ['regression: random interpolator 0', [[3, -1, -1, 2, 3], 3, [-4, -4, 2]], [-36, 12, 12, -60, -24, 12, -6, -42, -6]], ['regression: random interpolator 1', [[3, -2, 3, -3, 2, 2], 4, [3]], [36, -24, 36, -36]]], [['regression: random interpolator 1', [[3, -2, 3, -3, 2, 2], 4, [3]], [36, -24, 36, -36]], ['regression: random interpolator 4', [[-3, 3, 2, -1, 1], 4, [1]], [-12, 12, 8, -4]], ['regression: L=3 taps 7', [[1, 1, 1, 1, 1, 1, 1], 3, [1, 2]], [3, 3, 3, 9, 9, 9]], ['control: random interpolator 5', [[0], 3, [2, 0]], [0, 0, 0, 0, 0, 0]], ['control: random interpolator 11', [[2, 4, -1, -3], 4, [0, -4, 1]], [0, 0, 0, 0, -32, -64, 16, 48, 8, 16, -4, -12]], ['regression: random interpolator 0', [[3, -1, -1, 2, 3], 3, [-4, -4, 2]], [-36, 12, 12, -60, -24, 12, -6, -42, -6]], ['regression: random interpolator 8', [[0, -2, 3, 3, -2, 4, -3], 3, [4, 2]], [0, -24, 36, 36, -36, 66]]], [['regression: random interpolator 13', [[-2, 3, 3, -1, -1], 3, [1, 2, 3, -2, -2]], [-6, 9, 9, -15, 15, 18, -24, 21, 27, 3, -27, -18, 18, -12, -18]], ['regression: random interpolator 14', [[4, -1, 3, -1, 0, -2, 4], 3, [1, 3, 5]], [12, -3, 9, 33, -9, 21, 63, -15, 27]], ['regression: random interpolator 1', [[3, -2, 3, -3, 2, 2], 4, [3]], [36, -24, 36, -36]], ['control: random interpolator 5', [[0], 3, [2, 0]], [0, 0, 0, 0, 0, 0]], ['control: random interpolator 11', [[2, 4, -1, -3], 4, [0, -4, 1]], [0, 0, 0, 0, -32, -64, 16, 48, 8, 16, -4, -12]], ['regression: random interpolator 4', [[-3, 3, 2, -1, 1], 4, [1]], [-12, 12, 8, -4]], ['regression: random interpolator 8', [[0, -2, 3, 3, -2, 4, -3], 3, [4, 2]], [0, -24, 36, 36, -36, 66]]], [['regression: random interpolator 17', [[4, 4, 3, 1, -3, 2, 1], 4, [4]], [64, 64, 48, 16]], ['regression: random interpolator 18', [[-2, -1, -2, 0, 2], 2, [-4, 3, 1, 5, 1]], [16, 8, 4, -6, -32, -2, -12, -10, -20, -2]], ['repair check: random interpolator 3', [[-3], 4, [2, 2, 4, -3, -2]], [-24, 0, 0, 0, -24, 0, 0, 0, -48, 0, 0, 0, 36, 0, 0, 0, 24, 0, 0, 0]], ['control: random interpolator 5', [[0], 3, [2, 0]], [0, 0, 0, 0, 0, 0]], ['control: random interpolator 11', [[2, 4, -1, -3], 4, [0, -4, 1]], [0, 0, 0, 0, -32, -64, 16, 48, 8, 16, -4, -12]], ['regression: random interpolator 4', [[-3, 3, 2, -1, 1], 4, [1]], [-12, 12, 8, -4]], ['regression: random interpolator 8', [[0, -2, 3, 3, -2, 4, -3], 3, [4, 2]], [0, -24, 36, 36, -36, 66]]], [['regression: random interpolator 23', [[3, 2, 1, -1, 3, -1], 2, [-3, -1]], [-18, -12, -12, 2]], ['regression: random interpolator 26', [[4, -3, 2, -2], 3, [2, -4, 0, 4, -3]], [24, -18, 12, -60, 36, -24, 24, 0, 0, 48, -36, 24, -60, 27, -18]], ['repair check: random interpolator 6', [[2, -3, 2, -3], 4, [1, 5]], [8, -12, 8, -12, 40, -60, 40, -60]], ['control: random interpolator 5', [[0], 3, [2, 0]], [0, 0, 0, 0, 0, 0]], ['control: random interpolator 11', [[2, 4, -1, -3], 4, [0, -4, 1]], [0, 0, 0, 0, -32, -64, 16, 48, 8, 16, -4, -12]], ['regression: random interpolator 8', [[0, -2, 3, 3, -2, 4, -3], 3, [4, 2]], [0, -24, 36, 36, -36, 66]], ['regression: random interpolator 13', [[-2, 3, 3, -1, -1], 3, [1, 2, 3, -2, -2]], [-6, 9, 9, -15, 15, 18, -24, 21, 27, 3, -27, -18, 18, -12, -18]]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: partial phase tail | [0, 0, 2, 4] | [2, 4, 8, 4] | Failed |
| regression: L=3 taps 7 | [0, 0, 0, 6, 6, 6] | [3, 3, 3, 9, 9, 9] | Failed |
| repair check: impulse L=2 | [0, 0, 0, 0, 0, 0] | [2, 4, 6, 8, 0, 0] | Failed |
| control: random interpolator 5 | [0, 0, 0, 0, 0, 0] | [0, 0, 0, 0, 0, 0] | Passed |
| control: random interpolator 11 | [0, 0, 0, 0, -32, -64, 16, 48, 8, 16, -4, -12] | [0, 0, 0, 0, -32, -64, 16, 48, 8, 16, -4, -12] | Passed |
| regression: random interpolator 0 | [0, 0, 0, -36, 12, 12, -6, -42, -6] | [-36, 12, 12, -60, -24, 12, -6, -42, -6] | Failed |
| regression: random interpolator 1 | [0, 0, 0, 0] | [36, -24, 36, -36] | Failed |
SHA-256 / a754d25524f50785433b68752c7a9390dc3aec64ba354c7445e1a392056af524
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
h, L, xs = x
out = []
for m in range(len(xs)):
for p in range(L):
acc = 0
j = 0
while j * L + p < len(h):
if m - j >= 0:
acc += h[j * L + p] * xs[m - j]
j += 1
out.append(L * acc)
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: partial phase tail', [[1, 2, 3], 2, [1, 1]], [2, 4, 8, 4]], ['regression: L=3 taps 7', [[1, 1, 1, 1, 1, 1, 1], 3, [1, 2]], [3, 3, 3, 9, 9, 9]], ['repair check: impulse L=2', [[1, 2, 3, 4], 2, [1, 0, 0]], [2, 4, 6, 8, 0, 0]], ['control: random interpolator 5', [[0], 3, [2, 0]], [0, 0, 0, 0, 0, 0]], ['control: random interpolator 11', [[2, 4, -1, -3], 4, [0, -4, 1]], [0, 0, 0, 0, -32, -64, 16, 48, 8, 16, -4, -12]], ['regression: random interpolator 0', [[3, -1, -1, 2, 3], 3, [-4, -4, 2]], [-36, 12, 12, -60, -24, 12, -6, -42, -6]], ['regression: random interpolator 1', [[3, -2, 3, -3, 2, 2], 4, [3]], [36, -24, 36, -36]]], [['regression: random interpolator 1', [[3, -2, 3, -3, 2, 2], 4, [3]], [36, -24, 36, -36]], ['regression: random interpolator 4', [[-3, 3, 2, -1, 1], 4, [1]], [-12, 12, 8, -4]], ['regression: L=3 taps 7', [[1, 1, 1, 1, 1, 1, 1], 3, [1, 2]], [3, 3, 3, 9, 9, 9]], ['control: random interpolator 5', [[0], 3, [2, 0]], [0, 0, 0, 0, 0, 0]], ['control: random interpolator 11', [[2, 4, -1, -3], 4, [0, -4, 1]], [0, 0, 0, 0, -32, -64, 16, 48, 8, 16, -4, -12]], ['regression: random interpolator 0', [[3, -1, -1, 2, 3], 3, [-4, -4, 2]], [-36, 12, 12, -60, -24, 12, -6, -42, -6]], ['regression: random interpolator 8', [[0, -2, 3, 3, -2, 4, -3], 3, [4, 2]], [0, -24, 36, 36, -36, 66]]], [['regression: random interpolator 13', [[-2, 3, 3, -1, -1], 3, [1, 2, 3, -2, -2]], [-6, 9, 9, -15, 15, 18, -24, 21, 27, 3, -27, -18, 18, -12, -18]], ['regression: random interpolator 14', [[4, -1, 3, -1, 0, -2, 4], 3, [1, 3, 5]], [12, -3, 9, 33, -9, 21, 63, -15, 27]], ['regression: random interpolator 1', [[3, -2, 3, -3, 2, 2], 4, [3]], [36, -24, 36, -36]], ['control: random interpolator 5', [[0], 3, [2, 0]], [0, 0, 0, 0, 0, 0]], ['control: random interpolator 11', [[2, 4, -1, -3], 4, [0, -4, 1]], [0, 0, 0, 0, -32, -64, 16, 48, 8, 16, -4, -12]], ['regression: random interpolator 4', [[-3, 3, 2, -1, 1], 4, [1]], [-12, 12, 8, -4]], ['regression: random interpolator 8', [[0, -2, 3, 3, -2, 4, -3], 3, [4, 2]], [0, -24, 36, 36, -36, 66]]], [['regression: random interpolator 17', [[4, 4, 3, 1, -3, 2, 1], 4, [4]], [64, 64, 48, 16]], ['regression: random interpolator 18', [[-2, -1, -2, 0, 2], 2, [-4, 3, 1, 5, 1]], [16, 8, 4, -6, -32, -2, -12, -10, -20, -2]], ['repair check: random interpolator 3', [[-3], 4, [2, 2, 4, -3, -2]], [-24, 0, 0, 0, -24, 0, 0, 0, -48, 0, 0, 0, 36, 0, 0, 0, 24, 0, 0, 0]], ['control: random interpolator 5', [[0], 3, [2, 0]], [0, 0, 0, 0, 0, 0]], ['control: random interpolator 11', [[2, 4, -1, -3], 4, [0, -4, 1]], [0, 0, 0, 0, -32, -64, 16, 48, 8, 16, -4, -12]], ['regression: random interpolator 4', [[-3, 3, 2, -1, 1], 4, [1]], [-12, 12, 8, -4]], ['regression: random interpolator 8', [[0, -2, 3, 3, -2, 4, -3], 3, [4, 2]], [0, -24, 36, 36, -36, 66]]], [['regression: random interpolator 23', [[3, 2, 1, -1, 3, -1], 2, [-3, -1]], [-18, -12, -12, 2]], ['regression: random interpolator 26', [[4, -3, 2, -2], 3, [2, -4, 0, 4, -3]], [24, -18, 12, -60, 36, -24, 24, 0, 0, 48, -36, 24, -60, 27, -18]], ['repair check: random interpolator 6', [[2, -3, 2, -3], 4, [1, 5]], [8, -12, 8, -12, 40, -60, 40, -60]], ['control: random interpolator 5', [[0], 3, [2, 0]], [0, 0, 0, 0, 0, 0]], ['control: random interpolator 11', [[2, 4, -1, -3], 4, [0, -4, 1]], [0, 0, 0, 0, -32, -64, 16, 48, 8, 16, -4, -12]], ['regression: random interpolator 8', [[0, -2, 3, 3, -2, 4, -3], 3, [4, 2]], [0, -24, 36, 36, -36, 66]], ['regression: random interpolator 13', [[-2, 3, 3, -1, -1], 3, [1, 2, 3, -2, -2]], [-6, 9, 9, -15, 15, 18, -24, 21, 27, 3, -27, -18, 18, -12, -18]]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: partial phase tail | [2, 4, 8, 4] | [2, 4, 8, 4] | Passed |
| regression: L=3 taps 7 | [3, 3, 3, 9, 9, 9] | [3, 3, 3, 9, 9, 9] | Passed |
| repair check: impulse L=2 | [2, 4, 6, 8, 0, 0] | [2, 4, 6, 8, 0, 0] | Passed |
| control: random interpolator 5 | [0, 0, 0, 0, 0, 0] | [0, 0, 0, 0, 0, 0] | Passed |
| control: random interpolator 11 | [0, 0, 0, 0, -32, -64, 16, 48, 8, 16, -4, -12] | [0, 0, 0, 0, -32, -64, 16, 48, 8, 16, -4, -12] | Passed |
| regression: random interpolator 0 | [-36, 12, 12, -60, -24, 12, -6, -42, -6] | [-36, 12, 12, -60, -24, 12, -6, -42, -6] | Passed |
| regression: random interpolator 1 | [36, -24, 36, -36] | [36, -24, 36, -36] | Passed |
SHA-256 / 8984bc67b0ada09f45a2256d914e2fb875f8498e38add524668c0c939ab4b8b8
Verification & scope
A deterministic bounded teaching model with a stipulated toy contract; exact rational arithmetic or fixed-decimal rounding keeps outputs strict JSON. It is not a production DSP library and claims no standards conformance. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:51:37.004500+00:00.
Case digest / ce406b5ebf90ce786eb0f3d3d16e738505ca415ff7388a5881a61bf1cf1129a8