FAILURE MAP
← Case archive

FA-91441 / Digital signal filters / Open access

CIC normalizes by R^N only · case 01

With M = 2 the output of a unit step settles at 2^N instead of 1.

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

ROOT CAUSE

The gain divisor omits the differential delay factor.

THE FAILURE

The gain divisor omits the differential delay factor.

Unsuccessful approach: The attempted repair divides by (R M) N, a product instead of a power.

Case contract

Input [N, R, M, samples]: N integrator stages at the input rate, keep the integrator output at indices R-1, 2R-1, ... (whole blocks only), then N comb stages y = v - v[k-M] at the low rate with zero initial state; divide by the gain (R M)^N and return exact fraction strings.

Why this case matters

CIC decimators front most digital down-converters; decimation phase, delay or gain slips distort the passband level.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
N = 1
observations = []
def solve(x):
    N, R, M, xs = x
    ints = [0] * N
    dec = []
    for i, v in enumerate(xs):
        acc = v
        for k in range(N):
            ints[k] += acc
            acc = ints[k]
        if i % R == R - 1:
            dec.append(acc)
    combs = [[0] * M for _ in range(N)]
    out = []
    for v in dec:
        for k in range(N):
            d = combs[k]
            prev = d.pop(0)
            d.append(v)
            v = v - prev
        out.append(str(Fraction(v, R ** N)))
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: two stages R=3 M=2', [2, 3, 2, [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], ['1/12', '1/6', '1/12', '0']], ['regression: random cic 0', [1, 3, 2, [4, 1, 1, 5, -2, 4, -1, 4, 5]], ['1', '13/6', '5/2']], ['repair check: step three stages', [3, 2, 1, [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]], ['1/2', '1', '1', '1', '1']], ['control: one stage R=2 M=1', [1, 2, 1, [1, 2, 3, 4, 5, 6]], ['3/2', '7/2', '11/2']], ['control: partial final block', [1, 3, 1, [3, 3, 3, 3, 3]], ['3']], ['control: random cic 1', [1, 4, 1, [2, -1, 3, 4, 5, -3, 5, -2, 3, -1, 2, -3, -3, 0, 4, 0, 2, 4, 1]], ['2', '5/4', '1/4', '1/4']], ['control: random cic 2', [1, 3, 1, [2, 2, 3, -2, 1, -2, 3, 1, -3]], ['7/3', '-1', '1/3']]], [['regression: random cic 4', [1, 2, 2, [-3, 1, 4, 2, 4, 2, -3, 5]], ['-1/2', '1', '3', '2']], ['regression: random cic 5', [3, 2, 2, [-2, 2, -3, 2, -2, -3, 3, -3, -1]], ['-1/16', '-15/64', '-27/64', '-9/16']], ['regression: random cic 3', [3, 2, 2, [3, -3, 3, 5, -2, 3, 2, 4, 2, 2, 0]], ['3/32', '13/32', '57/64', '23/16', '63/32']], ['control: random cic 6', [1, 4, 1, [-2, 5, 3, -2, 5, -2, 1, 3, 0, -2, -3, 4, -2, -1, 5, 4, 2, 0, -2, 1]], ['1', '7/4', '-1/4', '3/2', '1/4']], ['control: random cic 14', [1, 2, 1, [2, 4, 5, 0]], ['3', '5/2']], ['control: random cic 26', [2, 2, 1, [1, 5, -3, 3, -2, 1, -1, 4, 1, 2]], ['7/4', '1/2', '0', '3/4', '2']], ['control: random cic 28', [1, 3, 1, [-3, -2, 1, 3, 3, 3, 0, 3, 5, 3, 5, 0, -2, -2, 5]], ['-4/3', '3', '8/3', '8/3', '1/3']]], [['regression: random cic 10', [3, 2, 2, [-2, 3, -2, 1, 1, 0, 0]], ['-3/64', '-7/64', '1/64']], ['regression: random cic 11', [3, 2, 2, [1, -1, 2, 1, -2, 3]], ['1/32', '11/64', '23/64']], ['repair check: random cic 7', [2, 4, 1, [3, -2, 2, -1, 3, -1, 0, -1, 0, -2, -3, -2]], ['9/16', '7/16', '-9/8']], ['control: random cic 29', [1, 3, 1, [0, 1, -3, 3, 5, 1, 0, 1, 1, 0, 0, -1, 4, 2, 5, 3]], ['-2/3', '3', '2/3', '-1/3', '11/3']], ['control: random cic 43', [1, 4, 1, [3, 2, 0, 5, 1, 5, -3, 2, 4, 1, 4, 2, 4]], ['5/2', '5/4', '11/4']], ['control: one stage R=2 M=1', [1, 2, 1, [1, 2, 3, 4, 5, 6]], ['3/2', '7/2', '11/2']], ['control: partial final block', [1, 3, 1, [3, 3, 3, 3, 3]], ['3']]], [['regression: random cic 13', [2, 3, 2, [0, 3, 3, -2, 4, -2, 2, 4, 1, 1]], ['1/4', '3/4', '7/6']], ['regression: random cic 15', [3, 2, 2, [5, 5, 2, 1]], ['5/16', '87/64']], ['regression: random cic 9', [3, 2, 2, [5, 2, 5, -2, 0, 0, 0, 3, 5, 1, 2]], ['17/64', '75/64', '61/32', '89/64', '55/64']], ['control: random cic 1', [1, 4, 1, [2, -1, 3, 4, 5, -3, 5, -2, 3, -1, 2, -3, -3, 0, 4, 0, 2, 4, 1]], ['2', '5/4', '1/4', '1/4']], ['control: random cic 2', [1, 3, 1, [2, 2, 3, -2, 1, -2, 3, 1, -3]], ['7/3', '-1', '1/3']], ['control: random cic 6', [1, 4, 1, [-2, 5, 3, -2, 5, -2, 1, 3, 0, -2, -3, 4, -2, -1, 5, 4, 2, 0, -2, 1]], ['1', '7/4', '-1/4', '3/2', '1/4']], ['control: random cic 14', [1, 2, 1, [2, 4, 5, 0]], ['3', '5/2']]], [['regression: random cic 18', [1, 3, 2, [5, 2, -1, -2, 3, -2]], ['1', '5/6']], ['regression: random cic 21', [1, 4, 2, [3, -2, 2, -3, 5, 1, -2, -1, -3, -1, 3, 1, -3, 1, 1, -2, -1, 4, -2, 4, 4]], ['0', '3/8', '3/8', '-3/8', '1/4']], ['regression: random cic 11', [3, 2, 2, [1, -1, 2, 1, -2, 3]], ['1/32', '11/64', '23/64']], ['control: random cic 26', [2, 2, 1, [1, 5, -3, 3, -2, 1, -1, 4, 1, 2]], ['7/4', '1/2', '0', '3/4', '2']], ['control: random cic 28', [1, 3, 1, [-3, -2, 1, 3, 3, 3, 0, 3, 5, 3, 5, 0, -2, -2, 5]], ['-4/3', '3', '8/3', '8/3', '1/3']], ['control: random cic 29', [1, 3, 1, [0, 1, -3, 3, 5, 1, 0, 1, 1, 0, 0, -1, 4, 2, 5, 3]], ['-2/3', '3', '2/3', '-1/3', '11/3']], ['control: random cic 43', [1, 4, 1, [3, 2, 0, 5, 1, 5, -3, 2, 4, 1, 4, 2, 4]], ['5/2', '5/4', '11/4']]]]
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: two stages R=3 M=2['1/3', '2/3', '1/3', '0']['1/12', '1/6', '1/12', '0']Failed
regression: random cic 0['2', '13/3', '5']['1', '13/6', '5/2']Failed
repair check: step three stages['1/2', '1', '1', '1', '1']['1/2', '1', '1', '1', '1']Passed
control: one stage R=2 M=1['3/2', '7/2', '11/2']['3/2', '7/2', '11/2']Passed
control: partial final block['3']['3']Passed
control: random cic 1['2', '5/4', '1/4', '1/4']['2', '5/4', '1/4', '1/4']Passed
control: random cic 2['7/3', '-1', '1/3']['7/3', '-1', '1/3']Passed

SHA-256 / 8bd145da6307d79d4a6270674ff98aff8da40be9d6fb6644f94b70422ef31f50

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
N = 1
observations = []
def solve(x):
    N, R, M, xs = x
    ints = [0] * N
    dec = []
    for i, v in enumerate(xs):
        acc = v
        for k in range(N):
            ints[k] += acc
            acc = ints[k]
        if i % R == R - 1:
            dec.append(acc)
    combs = [[0] * M for _ in range(N)]
    out = []
    for v in dec:
        for k in range(N):
            d = combs[k]
            prev = d.pop(0)
            d.append(v)
            v = v - prev
        out.append(str(Fraction(v, R * M * N)))
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: two stages R=3 M=2', [2, 3, 2, [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], ['1/12', '1/6', '1/12', '0']], ['regression: random cic 0', [1, 3, 2, [4, 1, 1, 5, -2, 4, -1, 4, 5]], ['1', '13/6', '5/2']], ['repair check: step three stages', [3, 2, 1, [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]], ['1/2', '1', '1', '1', '1']], ['control: one stage R=2 M=1', [1, 2, 1, [1, 2, 3, 4, 5, 6]], ['3/2', '7/2', '11/2']], ['control: partial final block', [1, 3, 1, [3, 3, 3, 3, 3]], ['3']], ['control: random cic 1', [1, 4, 1, [2, -1, 3, 4, 5, -3, 5, -2, 3, -1, 2, -3, -3, 0, 4, 0, 2, 4, 1]], ['2', '5/4', '1/4', '1/4']], ['control: random cic 2', [1, 3, 1, [2, 2, 3, -2, 1, -2, 3, 1, -3]], ['7/3', '-1', '1/3']]], [['regression: random cic 4', [1, 2, 2, [-3, 1, 4, 2, 4, 2, -3, 5]], ['-1/2', '1', '3', '2']], ['regression: random cic 5', [3, 2, 2, [-2, 2, -3, 2, -2, -3, 3, -3, -1]], ['-1/16', '-15/64', '-27/64', '-9/16']], ['regression: random cic 3', [3, 2, 2, [3, -3, 3, 5, -2, 3, 2, 4, 2, 2, 0]], ['3/32', '13/32', '57/64', '23/16', '63/32']], ['control: random cic 6', [1, 4, 1, [-2, 5, 3, -2, 5, -2, 1, 3, 0, -2, -3, 4, -2, -1, 5, 4, 2, 0, -2, 1]], ['1', '7/4', '-1/4', '3/2', '1/4']], ['control: random cic 14', [1, 2, 1, [2, 4, 5, 0]], ['3', '5/2']], ['control: random cic 26', [2, 2, 1, [1, 5, -3, 3, -2, 1, -1, 4, 1, 2]], ['7/4', '1/2', '0', '3/4', '2']], ['control: random cic 28', [1, 3, 1, [-3, -2, 1, 3, 3, 3, 0, 3, 5, 3, 5, 0, -2, -2, 5]], ['-4/3', '3', '8/3', '8/3', '1/3']]], [['regression: random cic 10', [3, 2, 2, [-2, 3, -2, 1, 1, 0, 0]], ['-3/64', '-7/64', '1/64']], ['regression: random cic 11', [3, 2, 2, [1, -1, 2, 1, -2, 3]], ['1/32', '11/64', '23/64']], ['repair check: random cic 7', [2, 4, 1, [3, -2, 2, -1, 3, -1, 0, -1, 0, -2, -3, -2]], ['9/16', '7/16', '-9/8']], ['control: random cic 29', [1, 3, 1, [0, 1, -3, 3, 5, 1, 0, 1, 1, 0, 0, -1, 4, 2, 5, 3]], ['-2/3', '3', '2/3', '-1/3', '11/3']], ['control: random cic 43', [1, 4, 1, [3, 2, 0, 5, 1, 5, -3, 2, 4, 1, 4, 2, 4]], ['5/2', '5/4', '11/4']], ['control: one stage R=2 M=1', [1, 2, 1, [1, 2, 3, 4, 5, 6]], ['3/2', '7/2', '11/2']], ['control: partial final block', [1, 3, 1, [3, 3, 3, 3, 3]], ['3']]], [['regression: random cic 13', [2, 3, 2, [0, 3, 3, -2, 4, -2, 2, 4, 1, 1]], ['1/4', '3/4', '7/6']], ['regression: random cic 15', [3, 2, 2, [5, 5, 2, 1]], ['5/16', '87/64']], ['regression: random cic 9', [3, 2, 2, [5, 2, 5, -2, 0, 0, 0, 3, 5, 1, 2]], ['17/64', '75/64', '61/32', '89/64', '55/64']], ['control: random cic 1', [1, 4, 1, [2, -1, 3, 4, 5, -3, 5, -2, 3, -1, 2, -3, -3, 0, 4, 0, 2, 4, 1]], ['2', '5/4', '1/4', '1/4']], ['control: random cic 2', [1, 3, 1, [2, 2, 3, -2, 1, -2, 3, 1, -3]], ['7/3', '-1', '1/3']], ['control: random cic 6', [1, 4, 1, [-2, 5, 3, -2, 5, -2, 1, 3, 0, -2, -3, 4, -2, -1, 5, 4, 2, 0, -2, 1]], ['1', '7/4', '-1/4', '3/2', '1/4']], ['control: random cic 14', [1, 2, 1, [2, 4, 5, 0]], ['3', '5/2']]], [['regression: random cic 18', [1, 3, 2, [5, 2, -1, -2, 3, -2]], ['1', '5/6']], ['regression: random cic 21', [1, 4, 2, [3, -2, 2, -3, 5, 1, -2, -1, -3, -1, 3, 1, -3, 1, 1, -2, -1, 4, -2, 4, 4]], ['0', '3/8', '3/8', '-3/8', '1/4']], ['regression: random cic 11', [3, 2, 2, [1, -1, 2, 1, -2, 3]], ['1/32', '11/64', '23/64']], ['control: random cic 26', [2, 2, 1, [1, 5, -3, 3, -2, 1, -1, 4, 1, 2]], ['7/4', '1/2', '0', '3/4', '2']], ['control: random cic 28', [1, 3, 1, [-3, -2, 1, 3, 3, 3, 0, 3, 5, 3, 5, 0, -2, -2, 5]], ['-4/3', '3', '8/3', '8/3', '1/3']], ['control: random cic 29', [1, 3, 1, [0, 1, -3, 3, 5, 1, 0, 1, 1, 0, 0, -1, 4, 2, 5, 3]], ['-2/3', '3', '2/3', '-1/3', '11/3']], ['control: random cic 43', [1, 4, 1, [3, 2, 0, 5, 1, 5, -3, 2, 4, 1, 4, 2, 4]], ['5/2', '5/4', '11/4']]]]
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: two stages R=3 M=2['1/4', '1/2', '1/4', '0']['1/12', '1/6', '1/12', '0']Failed
regression: random cic 0['1', '13/6', '5/2']['1', '13/6', '5/2']Passed
repair check: step three stages['2/3', '4/3', '4/3', '4/3', '4/3']['1/2', '1', '1', '1', '1']Failed
control: one stage R=2 M=1['3/2', '7/2', '11/2']['3/2', '7/2', '11/2']Passed
control: partial final block['3']['3']Passed
control: random cic 1['2', '5/4', '1/4', '1/4']['2', '5/4', '1/4', '1/4']Passed
control: random cic 2['7/3', '-1', '1/3']['7/3', '-1', '1/3']Passed

SHA-256 / d1489773bf14e0ce03ee63272579be742cd0adf0213665a2f0c54c95bfbaa652

HELD IN THE MEMBER ARCHIVE

The verified repair and its recorded checks are member-only.

This mechanism has 7 recorded checks per implementation. The open-access tier publishes the failure and the unsuccessful fix; the repaired source that passes every check, and the observations that prove it, are available to members.

Every case sharing this mechanism uses the same contract and the same repair, so this one record is held back for all of them.

Member access is invitation-based. Sign in with your invited account to inspect the repair.

Sign in to the archive ↗

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

Case digest / fddc875c96db7512286df01788698f1b386871bb17ce77c15fc346f8e36e1649