FAILURE MAP
← Case archive

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.

Verified by executionVariant 1 · 7 checks per implementationDownload source bundle ↓JSON ↗

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 fixtureActualExpectedOutcome
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 fixtureActualExpectedOutcome
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 fixtureActualExpectedOutcome
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