FA-91751 / Digital signal filters / Open access
Feedback comb accepts unit feedback gain · case 01
g = 1 is accepted, giving a non-decaying (marginally stable) resonator instead of "unstable".
ROOT CAUSE
The stability check is |g| > 1.
VERIFIED REPAIR
Reject |g| >= 1.
Unsuccessful approach: The attempted repair checks g >= 1 only, accepting g = -1.
Case contract
Input [D, g, samples]: y[n] = x[n] + g y[n-D] using a D-slot ring buffer with zero initial state; "bad-delay" if D < 1, "unstable" if |g| >= 1. Return exact fraction strings.
Why this case matters
Feedback combs build resonators and reverberators; ring-buffer indexing slips change the delay and the pitch.
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):
D, g, xs = x[0], Fraction(x[1]), x[2]
if D < 1:
return 'bad-delay'
if abs(g) > 1:
return 'unstable'
buf = [Fraction(0)] * D
pos = 0
out = []
for v in xs:
delayed = buf[pos]
y = v + g * delayed
buf[pos] = y
pos = (pos + 1) % D
out.append(str(y))
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: unit gain rejected', [3, '1', [1]], 'unstable'], ['regression: negative unit gain', [3, '-1', [1]], 'unstable'], ['control: impulse delay 2', [2, '1/2', [1, 0, 0, 0, 0, 0]], ['1', '0', '1/2', '0', '1/4', '0']], ['control: delay 1', [1, '-1/2', [1, 0, 0]], ['1', '-1/2', '1/4']], ['control: bad delay', [0, '1/2', [1]], 'bad-delay'], ['control: random comb 0', [2, '1/2', [-1, 3, 3, 0, 3, 2, -3, -1, -2]], ['-1', '3', '5/2', '3/2', '17/4', '11/4', '-7/8', '3/8', '-39/16']]], [['regression: negative unit gain', [3, '-1', [1]], 'unstable'], ['regression: unit gain rejected', [3, '1', [1]], 'unstable'], ['control: random comb 1', [4, '1/2', [-3, -2, 2, -3, 2, -1, -3, -2, -3]], ['-3', '-2', '2', '-3', '1/2', '-2', '-2', '-7/2', '-11/4']], ['control: random comb 2', [4, '-2/3', [2, 2, -1, 3, -1, 2, 1]], ['2', '2', '-1', '3', '-7/3', '2/3', '5/3']], ['control: random comb 3', [2, '1/2', [2, -1, -3]], ['2', '-1', '-2']], ['control: random comb 4', [3, '1/3', [-3, 3, 1, -1]], ['-3', '3', '1', '-2']]], [['regression: unit gain rejected', [3, '1', [1]], 'unstable'], ['regression: negative unit gain', [3, '-1', [1]], 'unstable'], ['control: random comb 5', [2, '-2/3', [-3, -3, -1, -3, -1]], ['-3', '-3', '1', '-1', '-5/3']], ['control: random comb 6', [4, '-2/3', [1, 0, -3, 3]], ['1', '0', '-3', '3']], ['control: random comb 7', [4, '-2/3', [1, 3, 3, -1, -1, 2, 3, -2, 2]], ['1', '3', '3', '-1', '-5/3', '0', '1', '-4/3', '28/9']], ['control: random comb 8', [4, '-2/3', [1, 3, -2, -1]], ['1', '3', '-2', '-1']]], [['regression: negative unit gain', [3, '-1', [1]], 'unstable'], ['regression: unit gain rejected', [3, '1', [1]], 'unstable'], ['control: random comb 9', [3, '1/2', [-2, 0, -3, 1, -3, 0, 3, 1]], ['-2', '0', '-3', '0', '-3', '-3/2', '3', '-1/2']], ['control: random comb 10', [3, '3/4', [3, -3, 2, -2, 0, -1]], ['3', '-3', '2', '1/4', '-9/4', '1/2']], ['control: random comb 11', [1, '3/4', [0, 1, 2, 0, -2, 1, 0]], ['0', '1', '11/4', '33/16', '-29/64', '169/256', '507/1024']], ['control: random comb 12', [3, '1/2', [2, 3, 0, -2, 3, 1]], ['2', '3', '0', '-1', '9/2', '1']]], [['regression: unit gain rejected', [3, '1', [1]], 'unstable'], ['regression: negative unit gain', [3, '-1', [1]], 'unstable'], ['control: random comb 13', [4, '-2/3', [3, -1, -3, -2, 3]], ['3', '-1', '-3', '-2', '1']], ['control: random comb 14', [4, '-2/3', [0, 0, -3, -3, -3]], ['0', '0', '-3', '-3', '-3']], ['control: random comb 15', [4, '1/2', [-2, 0, -3, 3, 1, -2, -2]], ['-2', '0', '-3', '3', '0', '-2', '-7/2']], ['control: random comb 16', [4, '1/3', [1, 3, 1, 0, -2, 3, 0, 0]], ['1', '3', '1', '0', '-5/3', '4', '1/3', '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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: unit gain rejected | ['1'] | unstable | Failed |
| regression: negative unit gain | ['1'] | unstable | Failed |
| control: impulse delay 2 | ['1', '0', '1/2', '0', '1/4', '0'] | ['1', '0', '1/2', '0', '1/4', '0'] | Passed |
| control: delay 1 | ['1', '-1/2', '1/4'] | ['1', '-1/2', '1/4'] | Passed |
| control: bad delay | bad-delay | bad-delay | Passed |
| control: random comb 0 | ['-1', '3', '5/2', '3/2', '17/4', '11/4', '-7/8', '3/8', '-39/16'] | ['-1', '3', '5/2', '3/2', '17/4', '11/4', '-7/8', '3/8', '-39/16'] | Passed |
SHA-256 / ee9bc4f40f23c6af50552890fdaa3f3f37387f2bba4a5a815e7a9eba7f448860
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):
D, g, xs = x[0], Fraction(x[1]), x[2]
if D < 1:
return 'bad-delay'
if g >= 1:
return 'unstable'
buf = [Fraction(0)] * D
pos = 0
out = []
for v in xs:
delayed = buf[pos]
y = v + g * delayed
buf[pos] = y
pos = (pos + 1) % D
out.append(str(y))
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: unit gain rejected', [3, '1', [1]], 'unstable'], ['regression: negative unit gain', [3, '-1', [1]], 'unstable'], ['control: impulse delay 2', [2, '1/2', [1, 0, 0, 0, 0, 0]], ['1', '0', '1/2', '0', '1/4', '0']], ['control: delay 1', [1, '-1/2', [1, 0, 0]], ['1', '-1/2', '1/4']], ['control: bad delay', [0, '1/2', [1]], 'bad-delay'], ['control: random comb 0', [2, '1/2', [-1, 3, 3, 0, 3, 2, -3, -1, -2]], ['-1', '3', '5/2', '3/2', '17/4', '11/4', '-7/8', '3/8', '-39/16']]], [['regression: negative unit gain', [3, '-1', [1]], 'unstable'], ['regression: unit gain rejected', [3, '1', [1]], 'unstable'], ['control: random comb 1', [4, '1/2', [-3, -2, 2, -3, 2, -1, -3, -2, -3]], ['-3', '-2', '2', '-3', '1/2', '-2', '-2', '-7/2', '-11/4']], ['control: random comb 2', [4, '-2/3', [2, 2, -1, 3, -1, 2, 1]], ['2', '2', '-1', '3', '-7/3', '2/3', '5/3']], ['control: random comb 3', [2, '1/2', [2, -1, -3]], ['2', '-1', '-2']], ['control: random comb 4', [3, '1/3', [-3, 3, 1, -1]], ['-3', '3', '1', '-2']]], [['regression: unit gain rejected', [3, '1', [1]], 'unstable'], ['regression: negative unit gain', [3, '-1', [1]], 'unstable'], ['control: random comb 5', [2, '-2/3', [-3, -3, -1, -3, -1]], ['-3', '-3', '1', '-1', '-5/3']], ['control: random comb 6', [4, '-2/3', [1, 0, -3, 3]], ['1', '0', '-3', '3']], ['control: random comb 7', [4, '-2/3', [1, 3, 3, -1, -1, 2, 3, -2, 2]], ['1', '3', '3', '-1', '-5/3', '0', '1', '-4/3', '28/9']], ['control: random comb 8', [4, '-2/3', [1, 3, -2, -1]], ['1', '3', '-2', '-1']]], [['regression: negative unit gain', [3, '-1', [1]], 'unstable'], ['regression: unit gain rejected', [3, '1', [1]], 'unstable'], ['control: random comb 9', [3, '1/2', [-2, 0, -3, 1, -3, 0, 3, 1]], ['-2', '0', '-3', '0', '-3', '-3/2', '3', '-1/2']], ['control: random comb 10', [3, '3/4', [3, -3, 2, -2, 0, -1]], ['3', '-3', '2', '1/4', '-9/4', '1/2']], ['control: random comb 11', [1, '3/4', [0, 1, 2, 0, -2, 1, 0]], ['0', '1', '11/4', '33/16', '-29/64', '169/256', '507/1024']], ['control: random comb 12', [3, '1/2', [2, 3, 0, -2, 3, 1]], ['2', '3', '0', '-1', '9/2', '1']]], [['regression: unit gain rejected', [3, '1', [1]], 'unstable'], ['regression: negative unit gain', [3, '-1', [1]], 'unstable'], ['control: random comb 13', [4, '-2/3', [3, -1, -3, -2, 3]], ['3', '-1', '-3', '-2', '1']], ['control: random comb 14', [4, '-2/3', [0, 0, -3, -3, -3]], ['0', '0', '-3', '-3', '-3']], ['control: random comb 15', [4, '1/2', [-2, 0, -3, 3, 1, -2, -2]], ['-2', '0', '-3', '3', '0', '-2', '-7/2']], ['control: random comb 16', [4, '1/3', [1, 3, 1, 0, -2, 3, 0, 0]], ['1', '3', '1', '0', '-5/3', '4', '1/3', '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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: unit gain rejected | unstable | unstable | Passed |
| regression: negative unit gain | ['1'] | unstable | Failed |
| control: impulse delay 2 | ['1', '0', '1/2', '0', '1/4', '0'] | ['1', '0', '1/2', '0', '1/4', '0'] | Passed |
| control: delay 1 | ['1', '-1/2', '1/4'] | ['1', '-1/2', '1/4'] | Passed |
| control: bad delay | bad-delay | bad-delay | Passed |
| control: random comb 0 | ['-1', '3', '5/2', '3/2', '17/4', '11/4', '-7/8', '3/8', '-39/16'] | ['-1', '3', '5/2', '3/2', '17/4', '11/4', '-7/8', '3/8', '-39/16'] | Passed |
SHA-256 / 6937972b72a049f2f9b8d47e187aa7f40747b766048fc3cb4818ee291fe17a55
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
N = 1
observations = []
def solve(x):
D, g, xs = x[0], Fraction(x[1]), x[2]
if D < 1:
return 'bad-delay'
if abs(g) >= 1:
return 'unstable'
buf = [Fraction(0)] * D
pos = 0
out = []
for v in xs:
delayed = buf[pos]
y = v + g * delayed
buf[pos] = y
pos = (pos + 1) % D
out.append(str(y))
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: unit gain rejected', [3, '1', [1]], 'unstable'], ['regression: negative unit gain', [3, '-1', [1]], 'unstable'], ['control: impulse delay 2', [2, '1/2', [1, 0, 0, 0, 0, 0]], ['1', '0', '1/2', '0', '1/4', '0']], ['control: delay 1', [1, '-1/2', [1, 0, 0]], ['1', '-1/2', '1/4']], ['control: bad delay', [0, '1/2', [1]], 'bad-delay'], ['control: random comb 0', [2, '1/2', [-1, 3, 3, 0, 3, 2, -3, -1, -2]], ['-1', '3', '5/2', '3/2', '17/4', '11/4', '-7/8', '3/8', '-39/16']]], [['regression: negative unit gain', [3, '-1', [1]], 'unstable'], ['regression: unit gain rejected', [3, '1', [1]], 'unstable'], ['control: random comb 1', [4, '1/2', [-3, -2, 2, -3, 2, -1, -3, -2, -3]], ['-3', '-2', '2', '-3', '1/2', '-2', '-2', '-7/2', '-11/4']], ['control: random comb 2', [4, '-2/3', [2, 2, -1, 3, -1, 2, 1]], ['2', '2', '-1', '3', '-7/3', '2/3', '5/3']], ['control: random comb 3', [2, '1/2', [2, -1, -3]], ['2', '-1', '-2']], ['control: random comb 4', [3, '1/3', [-3, 3, 1, -1]], ['-3', '3', '1', '-2']]], [['regression: unit gain rejected', [3, '1', [1]], 'unstable'], ['regression: negative unit gain', [3, '-1', [1]], 'unstable'], ['control: random comb 5', [2, '-2/3', [-3, -3, -1, -3, -1]], ['-3', '-3', '1', '-1', '-5/3']], ['control: random comb 6', [4, '-2/3', [1, 0, -3, 3]], ['1', '0', '-3', '3']], ['control: random comb 7', [4, '-2/3', [1, 3, 3, -1, -1, 2, 3, -2, 2]], ['1', '3', '3', '-1', '-5/3', '0', '1', '-4/3', '28/9']], ['control: random comb 8', [4, '-2/3', [1, 3, -2, -1]], ['1', '3', '-2', '-1']]], [['regression: negative unit gain', [3, '-1', [1]], 'unstable'], ['regression: unit gain rejected', [3, '1', [1]], 'unstable'], ['control: random comb 9', [3, '1/2', [-2, 0, -3, 1, -3, 0, 3, 1]], ['-2', '0', '-3', '0', '-3', '-3/2', '3', '-1/2']], ['control: random comb 10', [3, '3/4', [3, -3, 2, -2, 0, -1]], ['3', '-3', '2', '1/4', '-9/4', '1/2']], ['control: random comb 11', [1, '3/4', [0, 1, 2, 0, -2, 1, 0]], ['0', '1', '11/4', '33/16', '-29/64', '169/256', '507/1024']], ['control: random comb 12', [3, '1/2', [2, 3, 0, -2, 3, 1]], ['2', '3', '0', '-1', '9/2', '1']]], [['regression: unit gain rejected', [3, '1', [1]], 'unstable'], ['regression: negative unit gain', [3, '-1', [1]], 'unstable'], ['control: random comb 13', [4, '-2/3', [3, -1, -3, -2, 3]], ['3', '-1', '-3', '-2', '1']], ['control: random comb 14', [4, '-2/3', [0, 0, -3, -3, -3]], ['0', '0', '-3', '-3', '-3']], ['control: random comb 15', [4, '1/2', [-2, 0, -3, 3, 1, -2, -2]], ['-2', '0', '-3', '3', '0', '-2', '-7/2']], ['control: random comb 16', [4, '1/3', [1, 3, 1, 0, -2, 3, 0, 0]], ['1', '3', '1', '0', '-5/3', '4', '1/3', '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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: unit gain rejected | unstable | unstable | Passed |
| regression: negative unit gain | unstable | unstable | Passed |
| control: impulse delay 2 | ['1', '0', '1/2', '0', '1/4', '0'] | ['1', '0', '1/2', '0', '1/4', '0'] | Passed |
| control: delay 1 | ['1', '-1/2', '1/4'] | ['1', '-1/2', '1/4'] | Passed |
| control: bad delay | bad-delay | bad-delay | Passed |
| control: random comb 0 | ['-1', '3', '5/2', '3/2', '17/4', '11/4', '-7/8', '3/8', '-39/16'] | ['-1', '3', '5/2', '3/2', '17/4', '11/4', '-7/8', '3/8', '-39/16'] | Passed |
SHA-256 / aa2c0c848da81b626cf2f227e45845771ada62e990a648a46d7ada7bb34b7546
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:38.902540+00:00.
Case digest / ba1b4c854966ef6e5088535394ef1770e3931765cc21b29d19e6aeba82d50bb5