FAILURE MAP
← Case archive

FA-91341 / Digital signal filters / Open access

Streaming FIR clears its delay line at every block · case 01

Outputs at the start of each block ignore samples from the previous block, producing edge glitches.

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

ROOT CAUSE

The history buffer is re-initialized to zeros inside the block loop.

VERIFIED REPAIR

Initialize the delay line once and carry it across blocks.

Unsuccessful approach: The attempted repair rebuilds history from the previous block only, which is wrong when a block is shorter than the delay line.

Case contract

Input [taps, blocks] of integers. Filter the concatenated stream with y[n] = sum_k taps[k] x[n-k] (zero initial history) while processing block by block; return the outputs grouped per input block.

Why this case matters

Block-based FIR processing must carry history across buffer boundaries or every block edge glitches.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    b, blocks = x
    hist = [0] * (len(b) - 1)
    outs = []
    for blk in blocks:
        hist = [0] * (len(b) - 1)
        ys = []
        for s in blk:
            taps = [s] + hist
            ys.append(sum(c * v for c, v in zip(b, taps)))
            hist = taps[:len(b) - 1]
        outs.append(ys)
    return outs
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: short blocks spanning history', [[1, 2, 3, 4], [[1], [0], [0, 5], [2]]], [[1], [2], [3, 9], [12]]], ['regression: empty block in stream', [[2, 1], [[1, 2], [], [3]]], [[2, 5], [], [8]]], ['regression: random stream 0', [[3, 1, 3, 3], [[3, 4, -2], [3], [5, 4, -3], []]], [[9, 15, 7], [28], [24, 20, 19], []]], ['control: single tap', [[3], [[1, 2], [3]]], [[3, 6], [9]]], ['control: asymmetric taps one block', [[1, -1, 2], [[1, 0, 0, 0]]], [[1, -1, 2, 0]]], ['control: random stream 1', [[-1, -2, -3, 1], [[1, 2, 5, 4]]], [[-1, -4, -12, -19]]], ['control: random stream 2', [[1, -3], [[]]], [[]]]], [['regression: random stream 11', [[-3, -1], [[], [-3], [4, 5, 4]]], [[], [9], [-9, -19, -17]]], ['regression: random stream 16', [[2, -2], [[-2, 5, 1, 2], [-4, 1, -5, -4]]], [[-4, 14, -8, 2], [-12, 10, -12, 2]]], ['regression: random stream 0', [[3, 1, 3, 3], [[3, 4, -2], [3], [5, 4, -3], []]], [[9, 15, 7], [28], [24, 20, 19], []]], ['control: random stream 3', [[-2], [[-5, 2, 0, 2], [-2, 3, -2, 5]]], [[10, -4, 0, -4], [4, -6, 4, -10]]], ['control: random stream 4', [[0, -3, 2], [[5, -1, 1]]], [[0, -15, 13]]], ['control: random stream 5', [[3, -3, 2, -1, -1], [[-1, -5, -4, 4], []]], [[-3, -12, 1, 15], []]], ['control: random stream 6', [[-3, 3, -1, 0], [[]]], [[]]]], [['regression: random stream 22', [[2, -3, 0, -3, 2], [[-3, -4], [], [3, 0, -5]]], [[-6, 1], [], [18, 0, -4]]], ['regression: random stream 23', [[3, -1], [[], [-4, 1, -5], [4, -5, 4]]], [[], [-12, 7, -16], [17, -19, 17]]], ['regression: random stream 28', [[2, -1, -2, 2], [[-2], [-2, 4, 0], [-3], [2]]], [[-4], [-2, 14, -4], [-18], [15]]], ['control: random stream 7', [[-2], [[], [1, 1, 1]]], [[], [-2, -2, -2]]], ['control: random stream 8', [[1], [[0, -4], [0, -5]]], [[0, -4], [0, -5]]], ['control: random stream 9', [[3, -3, -2, -2], [[]]], [[]]], ['control: random stream 10', [[0], [[5], [-2, 2, 3, -2], [1], [-4, 1, 1]]], [[0], [0, 0, 0, 0], [0], [0, 0, 0]]]], [['regression: random stream 27', [[-3, -1, -1], [[-2, 3, -3, 0], [2, -2, 0]]], [[6, -7, 8, 0], [-3, 4, 0]]], ['regression: random stream 28', [[2, -1, -2, 2], [[-2], [-2, 4, 0], [-3], [2]]], [[-4], [-2, 14, -4], [-18], [15]]], ['regression: random stream 39', [[2, 3, -2], [[3], [5, 2, 2, 4], [], [2]]], [[6], [19, 13, 0, 10], [], [12]]], ['control: random stream 12', [[-3], [[2], [-5, 4]]], [[-6], [15, -12]]], ['control: random stream 13', [[3, -1, 0], [[]]], [[]]], ['control: random stream 14', [[-2], [[], [0, 0, 4, 2]]], [[], [0, 0, -8, -4]]], ['control: random stream 15', [[1, 0], [[-3, 5, -3], [-2, 4]]], [[-3, 5, -3], [-2, 4]]]], [['regression: random stream 33', [[-3, 2, 1, 2], [[], [-2], [-1, -3, -5]]], [[], [6], [-1, 5, 4]]], ['regression: random stream 34', [[1, 2, -3, -2], [[0, 3], [3, 4, -3, 1]]], [[0, 3], [9, 1, -10, -23]]], ['regression: short blocks spanning history', [[1, 2, 3, 4], [[1], [0], [0, 5], [2]]], [[1], [2], [3, 9], [12]]], ['control: random stream 17', [[-3], [[1], [1, 4], [-1, 3, -3]]], [[-3], [-3, -12], [3, -9, 9]]], ['control: random stream 18', [[-2], [[3, 5, 4], [-4, -1, -2, -2]]], [[-6, -10, -8], [8, 2, 4, 4]]], ['control: random stream 19', [[-3], [[2, -2, -5], [], [-1]]], [[-6, 6, 15], [], [3]]], ['control: random stream 20', [[1, 1, -2], [[-3, 2]]], [[-3, -1]]]]]
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: short blocks spanning history[[1], [0], [0, 5], [2]][[1], [2], [3, 9], [12]]Failed
regression: empty block in stream[[2, 5], [], [6]][[2, 5], [], [8]]Failed
regression: random stream 0[[9, 15, 7], [9], [15, 17, 10], []][[9, 15, 7], [28], [24, 20, 19], []]Failed
control: single tap[[3, 6], [9]][[3, 6], [9]]Passed
control: asymmetric taps one block[[1, -1, 2, 0]][[1, -1, 2, 0]]Passed
control: random stream 1[[-1, -4, -12, -19]][[-1, -4, -12, -19]]Passed
control: random stream 2[[]][[]]Passed

SHA-256 / 2ff02ffb73315dcadfab4078ecf89f2e4fadd86866706e691a330d26fa2843e6

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    b, blocks = x
    hist = [0] * (len(b) - 1)
    outs = []
    prev = []
    for blk in blocks:
        hist = (prev[::-1] + [0] * (len(b) - 1))[:len(b) - 1]
        ys = []
        for s in blk:
            taps = [s] + hist
            ys.append(sum(c * v for c, v in zip(b, taps)))
            hist = taps[:len(b) - 1]
        outs.append(ys)
        prev = blk
    return outs
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: short blocks spanning history', [[1, 2, 3, 4], [[1], [0], [0, 5], [2]]], [[1], [2], [3, 9], [12]]], ['regression: empty block in stream', [[2, 1], [[1, 2], [], [3]]], [[2, 5], [], [8]]], ['regression: random stream 0', [[3, 1, 3, 3], [[3, 4, -2], [3], [5, 4, -3], []]], [[9, 15, 7], [28], [24, 20, 19], []]], ['control: single tap', [[3], [[1, 2], [3]]], [[3, 6], [9]]], ['control: asymmetric taps one block', [[1, -1, 2], [[1, 0, 0, 0]]], [[1, -1, 2, 0]]], ['control: random stream 1', [[-1, -2, -3, 1], [[1, 2, 5, 4]]], [[-1, -4, -12, -19]]], ['control: random stream 2', [[1, -3], [[]]], [[]]]], [['regression: random stream 11', [[-3, -1], [[], [-3], [4, 5, 4]]], [[], [9], [-9, -19, -17]]], ['regression: random stream 16', [[2, -2], [[-2, 5, 1, 2], [-4, 1, -5, -4]]], [[-4, 14, -8, 2], [-12, 10, -12, 2]]], ['regression: random stream 0', [[3, 1, 3, 3], [[3, 4, -2], [3], [5, 4, -3], []]], [[9, 15, 7], [28], [24, 20, 19], []]], ['control: random stream 3', [[-2], [[-5, 2, 0, 2], [-2, 3, -2, 5]]], [[10, -4, 0, -4], [4, -6, 4, -10]]], ['control: random stream 4', [[0, -3, 2], [[5, -1, 1]]], [[0, -15, 13]]], ['control: random stream 5', [[3, -3, 2, -1, -1], [[-1, -5, -4, 4], []]], [[-3, -12, 1, 15], []]], ['control: random stream 6', [[-3, 3, -1, 0], [[]]], [[]]]], [['regression: random stream 22', [[2, -3, 0, -3, 2], [[-3, -4], [], [3, 0, -5]]], [[-6, 1], [], [18, 0, -4]]], ['regression: random stream 23', [[3, -1], [[], [-4, 1, -5], [4, -5, 4]]], [[], [-12, 7, -16], [17, -19, 17]]], ['regression: random stream 28', [[2, -1, -2, 2], [[-2], [-2, 4, 0], [-3], [2]]], [[-4], [-2, 14, -4], [-18], [15]]], ['control: random stream 7', [[-2], [[], [1, 1, 1]]], [[], [-2, -2, -2]]], ['control: random stream 8', [[1], [[0, -4], [0, -5]]], [[0, -4], [0, -5]]], ['control: random stream 9', [[3, -3, -2, -2], [[]]], [[]]], ['control: random stream 10', [[0], [[5], [-2, 2, 3, -2], [1], [-4, 1, 1]]], [[0], [0, 0, 0, 0], [0], [0, 0, 0]]]], [['regression: random stream 27', [[-3, -1, -1], [[-2, 3, -3, 0], [2, -2, 0]]], [[6, -7, 8, 0], [-3, 4, 0]]], ['regression: random stream 28', [[2, -1, -2, 2], [[-2], [-2, 4, 0], [-3], [2]]], [[-4], [-2, 14, -4], [-18], [15]]], ['regression: random stream 39', [[2, 3, -2], [[3], [5, 2, 2, 4], [], [2]]], [[6], [19, 13, 0, 10], [], [12]]], ['control: random stream 12', [[-3], [[2], [-5, 4]]], [[-6], [15, -12]]], ['control: random stream 13', [[3, -1, 0], [[]]], [[]]], ['control: random stream 14', [[-2], [[], [0, 0, 4, 2]]], [[], [0, 0, -8, -4]]], ['control: random stream 15', [[1, 0], [[-3, 5, -3], [-2, 4]]], [[-3, 5, -3], [-2, 4]]]], [['regression: random stream 33', [[-3, 2, 1, 2], [[], [-2], [-1, -3, -5]]], [[], [6], [-1, 5, 4]]], ['regression: random stream 34', [[1, 2, -3, -2], [[0, 3], [3, 4, -3, 1]]], [[0, 3], [9, 1, -10, -23]]], ['regression: short blocks spanning history', [[1, 2, 3, 4], [[1], [0], [0, 5], [2]]], [[1], [2], [3, 9], [12]]], ['control: random stream 17', [[-3], [[1], [1, 4], [-1, 3, -3]]], [[-3], [-3, -12], [3, -9, 9]]], ['control: random stream 18', [[-2], [[3, 5, 4], [-4, -1, -2, -2]]], [[-6, -10, -8], [8, 2, 4, 4]]], ['control: random stream 19', [[-3], [[2, -2, -5], [], [-1]]], [[-6, 6, 15], [], [3]]], ['control: random stream 20', [[1, 1, -2], [[-3, 2]]], [[-3, -1]]]]]
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: short blocks spanning history[[1], [2], [0, 5], [12]][[1], [2], [3, 9], [12]]Failed
regression: empty block in stream[[2, 5], [], [6]][[2, 5], [], [8]]Failed
regression: random stream 0[[9, 15, 7], [28], [18, 26, 19], []][[9, 15, 7], [28], [24, 20, 19], []]Failed
control: single tap[[3, 6], [9]][[3, 6], [9]]Passed
control: asymmetric taps one block[[1, -1, 2, 0]][[1, -1, 2, 0]]Passed
control: random stream 1[[-1, -4, -12, -19]][[-1, -4, -12, -19]]Passed
control: random stream 2[[]][[]]Passed

SHA-256 / 125f351e50290256dd14daba21fe14e9ba13c22719df27578a804aeb3aa1b1c7

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    b, blocks = x
    hist = [0] * (len(b) - 1)
    outs = []
    for blk in blocks:
        ys = []
        for s in blk:
            taps = [s] + hist
            ys.append(sum(c * v for c, v in zip(b, taps)))
            hist = taps[:len(b) - 1]
        outs.append(ys)
    return outs
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: short blocks spanning history', [[1, 2, 3, 4], [[1], [0], [0, 5], [2]]], [[1], [2], [3, 9], [12]]], ['regression: empty block in stream', [[2, 1], [[1, 2], [], [3]]], [[2, 5], [], [8]]], ['regression: random stream 0', [[3, 1, 3, 3], [[3, 4, -2], [3], [5, 4, -3], []]], [[9, 15, 7], [28], [24, 20, 19], []]], ['control: single tap', [[3], [[1, 2], [3]]], [[3, 6], [9]]], ['control: asymmetric taps one block', [[1, -1, 2], [[1, 0, 0, 0]]], [[1, -1, 2, 0]]], ['control: random stream 1', [[-1, -2, -3, 1], [[1, 2, 5, 4]]], [[-1, -4, -12, -19]]], ['control: random stream 2', [[1, -3], [[]]], [[]]]], [['regression: random stream 11', [[-3, -1], [[], [-3], [4, 5, 4]]], [[], [9], [-9, -19, -17]]], ['regression: random stream 16', [[2, -2], [[-2, 5, 1, 2], [-4, 1, -5, -4]]], [[-4, 14, -8, 2], [-12, 10, -12, 2]]], ['regression: random stream 0', [[3, 1, 3, 3], [[3, 4, -2], [3], [5, 4, -3], []]], [[9, 15, 7], [28], [24, 20, 19], []]], ['control: random stream 3', [[-2], [[-5, 2, 0, 2], [-2, 3, -2, 5]]], [[10, -4, 0, -4], [4, -6, 4, -10]]], ['control: random stream 4', [[0, -3, 2], [[5, -1, 1]]], [[0, -15, 13]]], ['control: random stream 5', [[3, -3, 2, -1, -1], [[-1, -5, -4, 4], []]], [[-3, -12, 1, 15], []]], ['control: random stream 6', [[-3, 3, -1, 0], [[]]], [[]]]], [['regression: random stream 22', [[2, -3, 0, -3, 2], [[-3, -4], [], [3, 0, -5]]], [[-6, 1], [], [18, 0, -4]]], ['regression: random stream 23', [[3, -1], [[], [-4, 1, -5], [4, -5, 4]]], [[], [-12, 7, -16], [17, -19, 17]]], ['regression: random stream 28', [[2, -1, -2, 2], [[-2], [-2, 4, 0], [-3], [2]]], [[-4], [-2, 14, -4], [-18], [15]]], ['control: random stream 7', [[-2], [[], [1, 1, 1]]], [[], [-2, -2, -2]]], ['control: random stream 8', [[1], [[0, -4], [0, -5]]], [[0, -4], [0, -5]]], ['control: random stream 9', [[3, -3, -2, -2], [[]]], [[]]], ['control: random stream 10', [[0], [[5], [-2, 2, 3, -2], [1], [-4, 1, 1]]], [[0], [0, 0, 0, 0], [0], [0, 0, 0]]]], [['regression: random stream 27', [[-3, -1, -1], [[-2, 3, -3, 0], [2, -2, 0]]], [[6, -7, 8, 0], [-3, 4, 0]]], ['regression: random stream 28', [[2, -1, -2, 2], [[-2], [-2, 4, 0], [-3], [2]]], [[-4], [-2, 14, -4], [-18], [15]]], ['regression: random stream 39', [[2, 3, -2], [[3], [5, 2, 2, 4], [], [2]]], [[6], [19, 13, 0, 10], [], [12]]], ['control: random stream 12', [[-3], [[2], [-5, 4]]], [[-6], [15, -12]]], ['control: random stream 13', [[3, -1, 0], [[]]], [[]]], ['control: random stream 14', [[-2], [[], [0, 0, 4, 2]]], [[], [0, 0, -8, -4]]], ['control: random stream 15', [[1, 0], [[-3, 5, -3], [-2, 4]]], [[-3, 5, -3], [-2, 4]]]], [['regression: random stream 33', [[-3, 2, 1, 2], [[], [-2], [-1, -3, -5]]], [[], [6], [-1, 5, 4]]], ['regression: random stream 34', [[1, 2, -3, -2], [[0, 3], [3, 4, -3, 1]]], [[0, 3], [9, 1, -10, -23]]], ['regression: short blocks spanning history', [[1, 2, 3, 4], [[1], [0], [0, 5], [2]]], [[1], [2], [3, 9], [12]]], ['control: random stream 17', [[-3], [[1], [1, 4], [-1, 3, -3]]], [[-3], [-3, -12], [3, -9, 9]]], ['control: random stream 18', [[-2], [[3, 5, 4], [-4, -1, -2, -2]]], [[-6, -10, -8], [8, 2, 4, 4]]], ['control: random stream 19', [[-3], [[2, -2, -5], [], [-1]]], [[-6, 6, 15], [], [3]]], ['control: random stream 20', [[1, 1, -2], [[-3, 2]]], [[-3, -1]]]]]
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: short blocks spanning history[[1], [2], [3, 9], [12]][[1], [2], [3, 9], [12]]Passed
regression: empty block in stream[[2, 5], [], [8]][[2, 5], [], [8]]Passed
regression: random stream 0[[9, 15, 7], [28], [24, 20, 19], []][[9, 15, 7], [28], [24, 20, 19], []]Passed
control: single tap[[3, 6], [9]][[3, 6], [9]]Passed
control: asymmetric taps one block[[1, -1, 2, 0]][[1, -1, 2, 0]]Passed
control: random stream 1[[-1, -4, -12, -19]][[-1, -4, -12, -19]]Passed
control: random stream 2[[]][[]]Passed

SHA-256 / b417fb1e823f60b2609685a994d713744dcb0f683f0cb71b6938b78319441b6f

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:35.005753+00:00.

Case digest / ab0ce4f3e6cb116a6a7ec0e2eec0040038f8cff276de25b571fe0467fcbb353b