FAILURE MAP
← Case archive

FA-91511 / Digital signal filters / Open access

Windowed sinc normalizes the peak tap to one · case 01

The DC gain is far above unity for long filters.

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

ROOT CAUSE

Taps are divided by the maximum tap instead of the tap sum.

VERIFIED REPAIR

Divide by the sum of taps so the DC gain is 1.

Unsuccessful approach: The attempted repair divides by the sum of absolute taps, which differs when side lobes are negative.

Case contract

Input [N, fc, window]; fc is the cutoff as a fraction of Nyquist in (0, 1], window hamming (0.54 - 0.46 cos(2 pi n/(N-1))), hann (0.5 - 0.5 cos(...)) or rect (N = 1 uses 1). Taps h[n] = fc sinc(fc (n - (N-1)/2)) w[n], normalized to unit DC gain and rounded to 8 decimals; "bad-spec" for invalid input (Hann needs N != 2).

Why this case matters

Windowed-sinc design is the default FIR recipe; centre or normalization slips yield non-linear-phase or wrong-gain filters.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
    N, fc_s, win = x
    fc = float(Fraction(fc_s))
    if N < 1 or not 0 < fc <= 1:
        return 'bad-spec'
    c = (N - 1) / 2
    taps = []
    for n in range(N):
        t = n - c
        s = 1.0 if t == 0 else math.sin(math.pi * fc * t) / (math.pi * fc * t)
        if N == 1 or win == 'rect':
            w = 1.0
        elif win == 'hann':
            w = 0.5 - 0.5 * math.cos(2 * math.pi * n / (N - 1))
        else:
            w = 0.54 - 0.46 * math.cos(2 * math.pi * n / (N - 1))
        taps.append(fc * s * w)
    tot = max(taps)
    return [round(v / tot, 8) + 0.0 for v in taps]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: N=2 fc=1/2 hamming', [2, '1/2', 'hamming'], [0.5, 0.5]], ['regression: N=2 fc=1/2 rect', [2, '1/2', 'rect'], [0.5, 0.5]], ['regression: N=4 fc=1 hamming', [4, '1', 'hamming'], [-0.01793722, 0.51793722, 0.51793722, -0.01793722]], ['control: N=1 fc=1/2 hamming', [1, '1/2', 'hamming'], [1.0]], ['control: N=1 fc=1/2 hann', [1, '1/2', 'hann'], [1.0]], ['control: N=1 fc=1/2 rect', [1, '1/2', 'rect'], [1.0]], ['control: N=1 fc=1/4 hamming', [1, '1/4', 'hamming'], [1.0]]], [['regression: N=2 fc=1/4 rect', [2, '1/4', 'rect'], [0.5, 0.5]], ['regression: N=2 fc=3/5 hamming', [2, '3/5', 'hamming'], [0.5, 0.5]], ['regression: N=5 fc=3/5 hamming', [5, '3/5', 'hamming'], [-0.00820621, 0.17925211, 0.65790821, 0.17925211, -0.00820621]], ['control: N=1 fc=1/4 hann', [1, '1/4', 'hann'], [1.0]], ['control: N=1 fc=1/4 rect', [1, '1/4', 'rect'], [1.0]], ['control: N=1 fc=3/5 hamming', [1, '3/5', 'hamming'], [1.0]], ['control: N=1 fc=3/5 hann', [1, '3/5', 'hann'], [1.0]]], [['regression: N=2 fc=1 hamming', [2, '1', 'hamming'], [0.5, 0.5]], ['regression: N=2 fc=1 rect', [2, '1', 'rect'], [0.5, 0.5]], ['regression: N=7 fc=1/2 hamming', [7, '1/2', 'hamming'], [-0.00872183, 0.0, 0.25184279, 0.51375808, 0.25184279, 0.0, -0.00872183]], ['control: N=1 fc=3/5 rect', [1, '3/5', 'rect'], [1.0]], ['control: N=1 fc=1 hamming', [1, '1', 'hamming'], [1.0]], ['control: N=1 fc=1 hann', [1, '1', 'hann'], [1.0]], ['control: N=1 fc=1 rect', [1, '1', 'rect'], [1.0]]], [['regression: N=4 fc=1/2 hann', [4, '1/2', 'hann'], [0.0, 0.5, 0.5, 0.0]], ['regression: N=4 fc=1/2 rect', [4, '1/2', 'rect'], [0.125, 0.375, 0.375, 0.125]], ['regression: N=7 fc=3/5 hamming', [7, '3/5', 'hamming'], [-0.00499814, -0.02905169, 0.2335168, 0.60106606, 0.2335168, -0.02905169, -0.00499814]], ['control: N=5 fc=1 hamming', [5, '1', 'hamming'], [0.0, 0.0, 1.0, 0.0, 0.0]], ['control: N=5 fc=1 hann', [5, '1', 'hann'], [0.0, 0.0, 1.0, 0.0, 0.0]], ['control: N=5 fc=1 rect', [5, '1', 'rect'], [0.0, 0.0, 1.0, 0.0, 0.0]], ['control: N=7 fc=1 hamming', [7, '1', 'hamming'], [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0]]], [['regression: N=4 fc=1/4 hann', [4, '1/4', 'hann'], [0.0, 0.5, 0.5, 0.0]], ['regression: N=4 fc=1/4 rect', [4, '1/4', 'rect'], [0.22295145, 0.27704855, 0.27704855, 0.22295145]], ['regression: N=7 fc=3/5 rect', [7, '3/5', 'rect'], [-0.06978933, -0.104684, 0.33876452, 0.6714176, 0.33876452, -0.104684, -0.06978933]], ['control: N=7 fc=1 hann', [7, '1', 'hann'], [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0]], ['control: N=7 fc=1 rect', [7, '1', 'rect'], [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0]], ['control: N=11 fc=1 hamming', [11, '1', 'hamming'], [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0]], ['control: N=11 fc=1 hann', [11, '1', 'hann'], [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0]]]]
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: N=2 fc=1/2 hamming[1.0, 1.0][0.5, 0.5]Failed
regression: N=2 fc=1/2 rect[1.0, 1.0][0.5, 0.5]Failed
regression: N=4 fc=1 hamming[-0.03463203, 1.0, 1.0, -0.03463203][-0.01793722, 0.51793722, 0.51793722, -0.01793722]Failed
control: N=1 fc=1/2 hamming[1.0][1.0]Passed
control: N=1 fc=1/2 hann[1.0][1.0]Passed
control: N=1 fc=1/2 rect[1.0][1.0]Passed
control: N=1 fc=1/4 hamming[1.0][1.0]Passed

SHA-256 / 53a17d741ddda8739e33ff1fcc3d5cba778f91f63ab480a293fc8c0b38cffb11

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
    N, fc_s, win = x
    fc = float(Fraction(fc_s))
    if N < 1 or not 0 < fc <= 1:
        return 'bad-spec'
    c = (N - 1) / 2
    taps = []
    for n in range(N):
        t = n - c
        s = 1.0 if t == 0 else math.sin(math.pi * fc * t) / (math.pi * fc * t)
        if N == 1 or win == 'rect':
            w = 1.0
        elif win == 'hann':
            w = 0.5 - 0.5 * math.cos(2 * math.pi * n / (N - 1))
        else:
            w = 0.54 - 0.46 * math.cos(2 * math.pi * n / (N - 1))
        taps.append(fc * s * w)
    tot = sum(abs(v) for v in taps)
    return [round(v / tot, 8) + 0.0 for v in taps]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: N=2 fc=1/2 hamming', [2, '1/2', 'hamming'], [0.5, 0.5]], ['regression: N=2 fc=1/2 rect', [2, '1/2', 'rect'], [0.5, 0.5]], ['regression: N=4 fc=1 hamming', [4, '1', 'hamming'], [-0.01793722, 0.51793722, 0.51793722, -0.01793722]], ['control: N=1 fc=1/2 hamming', [1, '1/2', 'hamming'], [1.0]], ['control: N=1 fc=1/2 hann', [1, '1/2', 'hann'], [1.0]], ['control: N=1 fc=1/2 rect', [1, '1/2', 'rect'], [1.0]], ['control: N=1 fc=1/4 hamming', [1, '1/4', 'hamming'], [1.0]]], [['regression: N=2 fc=1/4 rect', [2, '1/4', 'rect'], [0.5, 0.5]], ['regression: N=2 fc=3/5 hamming', [2, '3/5', 'hamming'], [0.5, 0.5]], ['regression: N=5 fc=3/5 hamming', [5, '3/5', 'hamming'], [-0.00820621, 0.17925211, 0.65790821, 0.17925211, -0.00820621]], ['control: N=1 fc=1/4 hann', [1, '1/4', 'hann'], [1.0]], ['control: N=1 fc=1/4 rect', [1, '1/4', 'rect'], [1.0]], ['control: N=1 fc=3/5 hamming', [1, '3/5', 'hamming'], [1.0]], ['control: N=1 fc=3/5 hann', [1, '3/5', 'hann'], [1.0]]], [['regression: N=2 fc=1 hamming', [2, '1', 'hamming'], [0.5, 0.5]], ['regression: N=2 fc=1 rect', [2, '1', 'rect'], [0.5, 0.5]], ['regression: N=7 fc=1/2 hamming', [7, '1/2', 'hamming'], [-0.00872183, 0.0, 0.25184279, 0.51375808, 0.25184279, 0.0, -0.00872183]], ['control: N=1 fc=3/5 rect', [1, '3/5', 'rect'], [1.0]], ['control: N=1 fc=1 hamming', [1, '1', 'hamming'], [1.0]], ['control: N=1 fc=1 hann', [1, '1', 'hann'], [1.0]], ['control: N=1 fc=1 rect', [1, '1', 'rect'], [1.0]]], [['regression: N=4 fc=1/2 hann', [4, '1/2', 'hann'], [0.0, 0.5, 0.5, 0.0]], ['regression: N=4 fc=1/2 rect', [4, '1/2', 'rect'], [0.125, 0.375, 0.375, 0.125]], ['regression: N=7 fc=3/5 hamming', [7, '3/5', 'hamming'], [-0.00499814, -0.02905169, 0.2335168, 0.60106606, 0.2335168, -0.02905169, -0.00499814]], ['control: N=5 fc=1 hamming', [5, '1', 'hamming'], [0.0, 0.0, 1.0, 0.0, 0.0]], ['control: N=5 fc=1 hann', [5, '1', 'hann'], [0.0, 0.0, 1.0, 0.0, 0.0]], ['control: N=5 fc=1 rect', [5, '1', 'rect'], [0.0, 0.0, 1.0, 0.0, 0.0]], ['control: N=7 fc=1 hamming', [7, '1', 'hamming'], [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0]]], [['regression: N=4 fc=1/4 hann', [4, '1/4', 'hann'], [0.0, 0.5, 0.5, 0.0]], ['regression: N=4 fc=1/4 rect', [4, '1/4', 'rect'], [0.22295145, 0.27704855, 0.27704855, 0.22295145]], ['regression: N=7 fc=3/5 rect', [7, '3/5', 'rect'], [-0.06978933, -0.104684, 0.33876452, 0.6714176, 0.33876452, -0.104684, -0.06978933]], ['control: N=7 fc=1 hann', [7, '1', 'hann'], [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0]], ['control: N=7 fc=1 rect', [7, '1', 'rect'], [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0]], ['control: N=11 fc=1 hamming', [11, '1', 'hamming'], [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0]], ['control: N=11 fc=1 hann', [11, '1', 'hann'], [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0]]]]
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: N=2 fc=1/2 hamming[0.5, 0.5][0.5, 0.5]Passed
regression: N=2 fc=1/2 rect[0.5, 0.5][0.5, 0.5]Passed
regression: N=4 fc=1 hamming[-0.0167364, 0.4832636, 0.4832636, -0.0167364][-0.01793722, 0.51793722, 0.51793722, -0.01793722]Failed
control: N=1 fc=1/2 hamming[1.0][1.0]Passed
control: N=1 fc=1/2 hann[1.0][1.0]Passed
control: N=1 fc=1/2 rect[1.0][1.0]Passed
control: N=1 fc=1/4 hamming[1.0][1.0]Passed

SHA-256 / 21c8a22dba640856712d614901f8c2fa07998e6b8e3a7955874f1fef922a0bb1

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
    N, fc_s, win = x
    fc = float(Fraction(fc_s))
    if N < 1 or not 0 < fc <= 1:
        return 'bad-spec'
    c = (N - 1) / 2
    taps = []
    for n in range(N):
        t = n - c
        s = 1.0 if t == 0 else math.sin(math.pi * fc * t) / (math.pi * fc * t)
        if N == 1 or win == 'rect':
            w = 1.0
        elif win == 'hann':
            w = 0.5 - 0.5 * math.cos(2 * math.pi * n / (N - 1))
        else:
            w = 0.54 - 0.46 * math.cos(2 * math.pi * n / (N - 1))
        taps.append(fc * s * w)
    tot = sum(taps)
    return [round(v / tot, 8) + 0.0 for v in taps]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: N=2 fc=1/2 hamming', [2, '1/2', 'hamming'], [0.5, 0.5]], ['regression: N=2 fc=1/2 rect', [2, '1/2', 'rect'], [0.5, 0.5]], ['regression: N=4 fc=1 hamming', [4, '1', 'hamming'], [-0.01793722, 0.51793722, 0.51793722, -0.01793722]], ['control: N=1 fc=1/2 hamming', [1, '1/2', 'hamming'], [1.0]], ['control: N=1 fc=1/2 hann', [1, '1/2', 'hann'], [1.0]], ['control: N=1 fc=1/2 rect', [1, '1/2', 'rect'], [1.0]], ['control: N=1 fc=1/4 hamming', [1, '1/4', 'hamming'], [1.0]]], [['regression: N=2 fc=1/4 rect', [2, '1/4', 'rect'], [0.5, 0.5]], ['regression: N=2 fc=3/5 hamming', [2, '3/5', 'hamming'], [0.5, 0.5]], ['regression: N=5 fc=3/5 hamming', [5, '3/5', 'hamming'], [-0.00820621, 0.17925211, 0.65790821, 0.17925211, -0.00820621]], ['control: N=1 fc=1/4 hann', [1, '1/4', 'hann'], [1.0]], ['control: N=1 fc=1/4 rect', [1, '1/4', 'rect'], [1.0]], ['control: N=1 fc=3/5 hamming', [1, '3/5', 'hamming'], [1.0]], ['control: N=1 fc=3/5 hann', [1, '3/5', 'hann'], [1.0]]], [['regression: N=2 fc=1 hamming', [2, '1', 'hamming'], [0.5, 0.5]], ['regression: N=2 fc=1 rect', [2, '1', 'rect'], [0.5, 0.5]], ['regression: N=7 fc=1/2 hamming', [7, '1/2', 'hamming'], [-0.00872183, 0.0, 0.25184279, 0.51375808, 0.25184279, 0.0, -0.00872183]], ['control: N=1 fc=3/5 rect', [1, '3/5', 'rect'], [1.0]], ['control: N=1 fc=1 hamming', [1, '1', 'hamming'], [1.0]], ['control: N=1 fc=1 hann', [1, '1', 'hann'], [1.0]], ['control: N=1 fc=1 rect', [1, '1', 'rect'], [1.0]]], [['regression: N=4 fc=1/2 hann', [4, '1/2', 'hann'], [0.0, 0.5, 0.5, 0.0]], ['regression: N=4 fc=1/2 rect', [4, '1/2', 'rect'], [0.125, 0.375, 0.375, 0.125]], ['regression: N=7 fc=3/5 hamming', [7, '3/5', 'hamming'], [-0.00499814, -0.02905169, 0.2335168, 0.60106606, 0.2335168, -0.02905169, -0.00499814]], ['control: N=5 fc=1 hamming', [5, '1', 'hamming'], [0.0, 0.0, 1.0, 0.0, 0.0]], ['control: N=5 fc=1 hann', [5, '1', 'hann'], [0.0, 0.0, 1.0, 0.0, 0.0]], ['control: N=5 fc=1 rect', [5, '1', 'rect'], [0.0, 0.0, 1.0, 0.0, 0.0]], ['control: N=7 fc=1 hamming', [7, '1', 'hamming'], [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0]]], [['regression: N=4 fc=1/4 hann', [4, '1/4', 'hann'], [0.0, 0.5, 0.5, 0.0]], ['regression: N=4 fc=1/4 rect', [4, '1/4', 'rect'], [0.22295145, 0.27704855, 0.27704855, 0.22295145]], ['regression: N=7 fc=3/5 rect', [7, '3/5', 'rect'], [-0.06978933, -0.104684, 0.33876452, 0.6714176, 0.33876452, -0.104684, -0.06978933]], ['control: N=7 fc=1 hann', [7, '1', 'hann'], [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0]], ['control: N=7 fc=1 rect', [7, '1', 'rect'], [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0]], ['control: N=11 fc=1 hamming', [11, '1', 'hamming'], [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0]], ['control: N=11 fc=1 hann', [11, '1', 'hann'], [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0]]]]
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: N=2 fc=1/2 hamming[0.5, 0.5][0.5, 0.5]Passed
regression: N=2 fc=1/2 rect[0.5, 0.5][0.5, 0.5]Passed
regression: N=4 fc=1 hamming[-0.01793722, 0.51793722, 0.51793722, -0.01793722][-0.01793722, 0.51793722, 0.51793722, -0.01793722]Passed
control: N=1 fc=1/2 hamming[1.0][1.0]Passed
control: N=1 fc=1/2 hann[1.0][1.0]Passed
control: N=1 fc=1/2 rect[1.0][1.0]Passed
control: N=1 fc=1/4 hamming[1.0][1.0]Passed

SHA-256 / c580e011f2186d1034161731802750a56b9f0b5dc80b20b661c320aadf25dc2f

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

Case digest / 75873dbdb6dbedf8097e49e23e2d8d594729c33d7c4dc7533f47ef6e360ba60f