FAILURE MAP
← Case archive

FA-91821 / Digital signal filters / Open access

Notch design inverts the DC gain correction · case 01

The passband gain is squared away from unity instead of corrected.

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

ROOT CAUSE

The numerator scale is sum(b)/sum(a) instead of sum(a)/sum(b).

VERIFIED REPAIR

Scale b by A(1)/B(1).

Unsuccessful approach: The attempted repair scales both a and b, which leaves the DC gain unchanged.

Case contract

Input [f0, fs, r]: second-order notch with zeros on the unit circle at +-w0 (w0 = 2 pi f0 / fs) and poles at radius r: b = [1, -2 cos w0, 1], a = [1, -2 r cos w0, r^2]; b is scaled for unity DC gain (sum(a)/sum(b)). Coefficients rounded to 9 decimals; "bad-frequency" unless 0 < f0 < fs/2, "bad-radius" unless 0 <= r < 1.

Why this case matters

Notch filters remove mains hum and interference tones; angle or radius slips miss the tone or widen the notch.

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):
    f0, fs, r = Fraction(x[0]), Fraction(x[1]), Fraction(x[2])
    if not 0 < f0 < fs / 2:
        return 'bad-frequency'
    if not 0 <= r < 1:
        return 'bad-radius'
    w0 = 2 * math.pi * float(f0 / fs)
    c = math.cos(w0)
    b = [1.0, -2 * c, 1.0]
    a = [1.0, -2 * float(r) * c, float(r * r)]
    g = sum(b) / sum(a)
    return {'b': [round(g * v, 9) + 0.0 for v in b], 'a': [round(v, 9) + 0.0 for v in a]}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: f0=50 fs=1000 r=0', ['50', '1000', '0'], {'b': [10.215864547, -19.431729095, 10.215864547], 'a': [1.0, 0.0, 0.0]}], ['regression: f0=50 fs=1000 r=9/10', ['50', '1000', '9/10'], {'b': [1.002158645, -1.90621902, 1.002158645], 'a': [1.0, -1.711901729, 0.81]}], ['regression: f0=50 fs=1000 r=1/2', ['50', '1000', '1/2'], {'b': [3.053966137, -5.80898879, 3.053966137], 'a': [1.0, -0.951056516, 0.25]}], ['control: at nyquist', ['4', '8', '1/2'], 'bad-frequency'], ['control: bad radius', ['1', '8', '1'], 'bad-radius'], ['regression: f0=50 fs=1000 r=99/100', ['50', '1000', '99/100'], {'b': [0.991021586, -1.885035075, 0.991021586], 'a': [1.0, -1.883091902, 0.9801]}], ['regression: f0=60 fs=480 r=0', ['60', '480', '0'], {'b': [1.707106781, -2.414213562, 1.707106781], 'a': [1.0, 0.0, 0.0]}]], [['regression: f0=50 fs=1000 r=99/100', ['50', '1000', '99/100'], {'b': [0.991021586, -1.885035075, 0.991021586], 'a': [1.0, -1.883091902, 0.9801]}], ['regression: f0=60 fs=480 r=0', ['60', '480', '0'], {'b': [1.707106781, -2.414213562, 1.707106781], 'a': [1.0, 0.0, 0.0]}], ['regression: f0=50 fs=1000 r=1/2', ['50', '1000', '1/2'], {'b': [3.053966137, -5.80898879, 3.053966137], 'a': [1.0, -0.951056516, 0.25]}], ['control: at nyquist', ['4', '8', '1/2'], 'bad-frequency'], ['control: bad radius', ['1', '8', '1'], 'bad-radius'], ['regression: f0=60 fs=480 r=9/10', ['60', '480', '9/10'], {'b': [0.917071068, -1.296934342, 0.917071068], 'a': [1.0, -1.272792206, 0.81]}], ['regression: f0=60 fs=480 r=1/2', ['60', '480', '1/2'], {'b': [0.926776695, -1.310660172, 0.926776695], 'a': [1.0, -0.707106781, 0.25]}]], [['regression: f0=60 fs=480 r=1/2', ['60', '480', '1/2'], {'b': [0.926776695, -1.310660172, 0.926776695], 'a': [1.0, -0.707106781, 0.25]}], ['regression: f0=60 fs=480 r=99/100', ['60', '480', '99/100'], {'b': [0.990170711, -1.400312848, 0.990170711], 'a': [1.0, -1.400071427, 0.9801]}], ['regression: f0=60 fs=480 r=0', ['60', '480', '0'], {'b': [1.707106781, -2.414213562, 1.707106781], 'a': [1.0, 0.0, 0.0]}], ['control: at nyquist', ['4', '8', '1/2'], 'bad-frequency'], ['control: bad radius', ['1', '8', '1'], 'bad-radius'], ['regression: f0=50 fs=1000 r=99/100', ['50', '1000', '99/100'], {'b': [0.991021586, -1.885035075, 0.991021586], 'a': [1.0, -1.883091902, 0.9801]}], ['regression: f0=60 fs=480 r=9/10', ['60', '480', '9/10'], {'b': [0.917071068, -1.296934342, 0.917071068], 'a': [1.0, -1.272792206, 0.81]}]], [['regression: f0=1 fs=8 r=9/10', ['1', '8', '9/10'], {'b': [0.917071068, -1.296934342, 0.917071068], 'a': [1.0, -1.272792206, 0.81]}], ['regression: f0=1 fs=8 r=1/2', ['1', '8', '1/2'], {'b': [0.926776695, -1.310660172, 0.926776695], 'a': [1.0, -0.707106781, 0.25]}], ['regression: f0=60 fs=480 r=1/2', ['60', '480', '1/2'], {'b': [0.926776695, -1.310660172, 0.926776695], 'a': [1.0, -0.707106781, 0.25]}], ['control: at nyquist', ['4', '8', '1/2'], 'bad-frequency'], ['control: bad radius', ['1', '8', '1'], 'bad-radius'], ['regression: f0=60 fs=480 r=0', ['60', '480', '0'], {'b': [1.707106781, -2.414213562, 1.707106781], 'a': [1.0, 0.0, 0.0]}], ['regression: f0=60 fs=480 r=9/10', ['60', '480', '9/10'], {'b': [0.917071068, -1.296934342, 0.917071068], 'a': [1.0, -1.272792206, 0.81]}]], [['regression: f0=3 fs=8 r=0', ['3', '8', '0'], {'b': [0.292893219, 0.414213562, 0.292893219], 'a': [1.0, 0.0, 0.0]}], ['regression: f0=3 fs=8 r=9/10', ['3', '8', '9/10'], {'b': [0.902928932, 1.276934342, 0.902928932], 'a': [1.0, 1.272792206, 0.81]}], ['regression: f0=1 fs=8 r=0', ['1', '8', '0'], {'b': [1.707106781, -2.414213562, 1.707106781], 'a': [1.0, 0.0, 0.0]}], ['control: at nyquist', ['4', '8', '1/2'], 'bad-frequency'], ['control: bad radius', ['1', '8', '1'], 'bad-radius'], ['regression: f0=60 fs=480 r=9/10', ['60', '480', '9/10'], {'b': [0.917071068, -1.296934342, 0.917071068], 'a': [1.0, -1.272792206, 0.81]}], ['regression: f0=60 fs=480 r=1/2', ['60', '480', '1/2'], {'b': [0.926776695, -1.310660172, 0.926776695], 'a': [1.0, -0.707106781, 0.25]}]]]
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: f0=50 fs=1000 r=0{'a': [1.0, 0.0, 0.0], 'b': [0.097886967, -0.186192076, 0.097886967]}{'a': [1.0, 0.0, 0.0], 'b': [10.215864547, -19.431729095, 10.215864547]}Failed
regression: f0=50 fs=1000 r=9/10{'a': [1.0, -1.711901729, 0.81], 'b': [0.997846004, -1.898015889, 0.997846004]}{'a': [1.0, -1.711901729, 0.81], 'b': [1.002158645, -1.90621902, 1.002158645]}Failed
regression: f0=50 fs=1000 r=1/2{'a': [1.0, -0.951056516, 0.25], 'b': [0.327443054, -0.622833701, 0.327443054]}{'a': [1.0, -0.951056516, 0.25], 'b': [3.053966137, -5.80898879, 3.053966137]}Failed
control: at nyquistbad-frequencybad-frequencyPassed
control: bad radiusbad-radiusbad-radiusPassed
regression: f0=50 fs=1000 r=99/100{'a': [1.0, -1.883091902, 0.9801], 'b': [1.009059756, -1.919345712, 1.009059756]}{'a': [1.0, -1.883091902, 0.9801], 'b': [0.991021586, -1.885035075, 0.991021586]}Failed
regression: f0=60 fs=480 r=0{'a': [1.0, 0.0, 0.0], 'b': [0.585786438, -0.828427125, 0.585786438]}{'a': [1.0, 0.0, 0.0], 'b': [1.707106781, -2.414213562, 1.707106781]}Failed

SHA-256 / 5297befe9d5944689338d48d6dd8dec7f375a53108dfdeb7d496704c527729a0

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):
    f0, fs, r = Fraction(x[0]), Fraction(x[1]), Fraction(x[2])
    if not 0 < f0 < fs / 2:
        return 'bad-frequency'
    if not 0 <= r < 1:
        return 'bad-radius'
    w0 = 2 * math.pi * float(f0 / fs)
    c = math.cos(w0)
    b = [1.0, -2 * c, 1.0]
    a = [1.0, -2 * float(r) * c, float(r * r)]
    g = sum(a) / sum(b)
    return {'b': [round(g * v, 9) + 0.0 for v in b], 'a': [round(g * v, 9) + 0.0 for v in a]}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: f0=50 fs=1000 r=0', ['50', '1000', '0'], {'b': [10.215864547, -19.431729095, 10.215864547], 'a': [1.0, 0.0, 0.0]}], ['regression: f0=50 fs=1000 r=9/10', ['50', '1000', '9/10'], {'b': [1.002158645, -1.90621902, 1.002158645], 'a': [1.0, -1.711901729, 0.81]}], ['regression: f0=50 fs=1000 r=1/2', ['50', '1000', '1/2'], {'b': [3.053966137, -5.80898879, 3.053966137], 'a': [1.0, -0.951056516, 0.25]}], ['control: at nyquist', ['4', '8', '1/2'], 'bad-frequency'], ['control: bad radius', ['1', '8', '1'], 'bad-radius'], ['regression: f0=50 fs=1000 r=99/100', ['50', '1000', '99/100'], {'b': [0.991021586, -1.885035075, 0.991021586], 'a': [1.0, -1.883091902, 0.9801]}], ['regression: f0=60 fs=480 r=0', ['60', '480', '0'], {'b': [1.707106781, -2.414213562, 1.707106781], 'a': [1.0, 0.0, 0.0]}]], [['regression: f0=50 fs=1000 r=99/100', ['50', '1000', '99/100'], {'b': [0.991021586, -1.885035075, 0.991021586], 'a': [1.0, -1.883091902, 0.9801]}], ['regression: f0=60 fs=480 r=0', ['60', '480', '0'], {'b': [1.707106781, -2.414213562, 1.707106781], 'a': [1.0, 0.0, 0.0]}], ['regression: f0=50 fs=1000 r=1/2', ['50', '1000', '1/2'], {'b': [3.053966137, -5.80898879, 3.053966137], 'a': [1.0, -0.951056516, 0.25]}], ['control: at nyquist', ['4', '8', '1/2'], 'bad-frequency'], ['control: bad radius', ['1', '8', '1'], 'bad-radius'], ['regression: f0=60 fs=480 r=9/10', ['60', '480', '9/10'], {'b': [0.917071068, -1.296934342, 0.917071068], 'a': [1.0, -1.272792206, 0.81]}], ['regression: f0=60 fs=480 r=1/2', ['60', '480', '1/2'], {'b': [0.926776695, -1.310660172, 0.926776695], 'a': [1.0, -0.707106781, 0.25]}]], [['regression: f0=60 fs=480 r=1/2', ['60', '480', '1/2'], {'b': [0.926776695, -1.310660172, 0.926776695], 'a': [1.0, -0.707106781, 0.25]}], ['regression: f0=60 fs=480 r=99/100', ['60', '480', '99/100'], {'b': [0.990170711, -1.400312848, 0.990170711], 'a': [1.0, -1.400071427, 0.9801]}], ['regression: f0=60 fs=480 r=0', ['60', '480', '0'], {'b': [1.707106781, -2.414213562, 1.707106781], 'a': [1.0, 0.0, 0.0]}], ['control: at nyquist', ['4', '8', '1/2'], 'bad-frequency'], ['control: bad radius', ['1', '8', '1'], 'bad-radius'], ['regression: f0=50 fs=1000 r=99/100', ['50', '1000', '99/100'], {'b': [0.991021586, -1.885035075, 0.991021586], 'a': [1.0, -1.883091902, 0.9801]}], ['regression: f0=60 fs=480 r=9/10', ['60', '480', '9/10'], {'b': [0.917071068, -1.296934342, 0.917071068], 'a': [1.0, -1.272792206, 0.81]}]], [['regression: f0=1 fs=8 r=9/10', ['1', '8', '9/10'], {'b': [0.917071068, -1.296934342, 0.917071068], 'a': [1.0, -1.272792206, 0.81]}], ['regression: f0=1 fs=8 r=1/2', ['1', '8', '1/2'], {'b': [0.926776695, -1.310660172, 0.926776695], 'a': [1.0, -0.707106781, 0.25]}], ['regression: f0=60 fs=480 r=1/2', ['60', '480', '1/2'], {'b': [0.926776695, -1.310660172, 0.926776695], 'a': [1.0, -0.707106781, 0.25]}], ['control: at nyquist', ['4', '8', '1/2'], 'bad-frequency'], ['control: bad radius', ['1', '8', '1'], 'bad-radius'], ['regression: f0=60 fs=480 r=0', ['60', '480', '0'], {'b': [1.707106781, -2.414213562, 1.707106781], 'a': [1.0, 0.0, 0.0]}], ['regression: f0=60 fs=480 r=9/10', ['60', '480', '9/10'], {'b': [0.917071068, -1.296934342, 0.917071068], 'a': [1.0, -1.272792206, 0.81]}]], [['regression: f0=3 fs=8 r=0', ['3', '8', '0'], {'b': [0.292893219, 0.414213562, 0.292893219], 'a': [1.0, 0.0, 0.0]}], ['regression: f0=3 fs=8 r=9/10', ['3', '8', '9/10'], {'b': [0.902928932, 1.276934342, 0.902928932], 'a': [1.0, 1.272792206, 0.81]}], ['regression: f0=1 fs=8 r=0', ['1', '8', '0'], {'b': [1.707106781, -2.414213562, 1.707106781], 'a': [1.0, 0.0, 0.0]}], ['control: at nyquist', ['4', '8', '1/2'], 'bad-frequency'], ['control: bad radius', ['1', '8', '1'], 'bad-radius'], ['regression: f0=60 fs=480 r=9/10', ['60', '480', '9/10'], {'b': [0.917071068, -1.296934342, 0.917071068], 'a': [1.0, -1.272792206, 0.81]}], ['regression: f0=60 fs=480 r=1/2', ['60', '480', '1/2'], {'b': [0.926776695, -1.310660172, 0.926776695], 'a': [1.0, -0.707106781, 0.25]}]]]
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: f0=50 fs=1000 r=0{'a': [10.215864547, 0.0, 0.0], 'b': [10.215864547, -19.431729095, 10.215864547]}{'a': [1.0, 0.0, 0.0], 'b': [10.215864547, -19.431729095, 10.215864547]}Failed
regression: f0=50 fs=1000 r=9/10{'a': [1.002158645, -1.715597118, 0.811748503], 'b': [1.002158645, -1.90621902, 1.002158645]}{'a': [1.0, -1.711901729, 0.81], 'b': [1.002158645, -1.90621902, 1.002158645]}Failed
regression: f0=50 fs=1000 r=1/2{'a': [3.053966137, -2.904494395, 0.763491534], 'b': [3.053966137, -5.80898879, 3.053966137]}{'a': [1.0, -0.951056516, 0.25], 'b': [3.053966137, -5.80898879, 3.053966137]}Failed
control: at nyquistbad-frequencybad-frequencyPassed
control: bad radiusbad-radiusbad-radiusPassed
regression: f0=50 fs=1000 r=99/100{'a': [0.991021586, -1.866184724, 0.971300257], 'b': [0.991021586, -1.885035075, 0.991021586]}{'a': [1.0, -1.883091902, 0.9801], 'b': [0.991021586, -1.885035075, 0.991021586]}Failed
regression: f0=60 fs=480 r=0{'a': [1.707106781, 0.0, 0.0], 'b': [1.707106781, -2.414213562, 1.707106781]}{'a': [1.0, 0.0, 0.0], 'b': [1.707106781, -2.414213562, 1.707106781]}Failed

SHA-256 / 55d6470fb7840243851b766bbf85cac1a243d96c92ca6a8e424a8d17e01a0796

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):
    f0, fs, r = Fraction(x[0]), Fraction(x[1]), Fraction(x[2])
    if not 0 < f0 < fs / 2:
        return 'bad-frequency'
    if not 0 <= r < 1:
        return 'bad-radius'
    w0 = 2 * math.pi * float(f0 / fs)
    c = math.cos(w0)
    b = [1.0, -2 * c, 1.0]
    a = [1.0, -2 * float(r) * c, float(r * r)]
    g = sum(a) / sum(b)
    return {'b': [round(g * v, 9) + 0.0 for v in b], 'a': [round(v, 9) + 0.0 for v in a]}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: f0=50 fs=1000 r=0', ['50', '1000', '0'], {'b': [10.215864547, -19.431729095, 10.215864547], 'a': [1.0, 0.0, 0.0]}], ['regression: f0=50 fs=1000 r=9/10', ['50', '1000', '9/10'], {'b': [1.002158645, -1.90621902, 1.002158645], 'a': [1.0, -1.711901729, 0.81]}], ['regression: f0=50 fs=1000 r=1/2', ['50', '1000', '1/2'], {'b': [3.053966137, -5.80898879, 3.053966137], 'a': [1.0, -0.951056516, 0.25]}], ['control: at nyquist', ['4', '8', '1/2'], 'bad-frequency'], ['control: bad radius', ['1', '8', '1'], 'bad-radius'], ['regression: f0=50 fs=1000 r=99/100', ['50', '1000', '99/100'], {'b': [0.991021586, -1.885035075, 0.991021586], 'a': [1.0, -1.883091902, 0.9801]}], ['regression: f0=60 fs=480 r=0', ['60', '480', '0'], {'b': [1.707106781, -2.414213562, 1.707106781], 'a': [1.0, 0.0, 0.0]}]], [['regression: f0=50 fs=1000 r=99/100', ['50', '1000', '99/100'], {'b': [0.991021586, -1.885035075, 0.991021586], 'a': [1.0, -1.883091902, 0.9801]}], ['regression: f0=60 fs=480 r=0', ['60', '480', '0'], {'b': [1.707106781, -2.414213562, 1.707106781], 'a': [1.0, 0.0, 0.0]}], ['regression: f0=50 fs=1000 r=1/2', ['50', '1000', '1/2'], {'b': [3.053966137, -5.80898879, 3.053966137], 'a': [1.0, -0.951056516, 0.25]}], ['control: at nyquist', ['4', '8', '1/2'], 'bad-frequency'], ['control: bad radius', ['1', '8', '1'], 'bad-radius'], ['regression: f0=60 fs=480 r=9/10', ['60', '480', '9/10'], {'b': [0.917071068, -1.296934342, 0.917071068], 'a': [1.0, -1.272792206, 0.81]}], ['regression: f0=60 fs=480 r=1/2', ['60', '480', '1/2'], {'b': [0.926776695, -1.310660172, 0.926776695], 'a': [1.0, -0.707106781, 0.25]}]], [['regression: f0=60 fs=480 r=1/2', ['60', '480', '1/2'], {'b': [0.926776695, -1.310660172, 0.926776695], 'a': [1.0, -0.707106781, 0.25]}], ['regression: f0=60 fs=480 r=99/100', ['60', '480', '99/100'], {'b': [0.990170711, -1.400312848, 0.990170711], 'a': [1.0, -1.400071427, 0.9801]}], ['regression: f0=60 fs=480 r=0', ['60', '480', '0'], {'b': [1.707106781, -2.414213562, 1.707106781], 'a': [1.0, 0.0, 0.0]}], ['control: at nyquist', ['4', '8', '1/2'], 'bad-frequency'], ['control: bad radius', ['1', '8', '1'], 'bad-radius'], ['regression: f0=50 fs=1000 r=99/100', ['50', '1000', '99/100'], {'b': [0.991021586, -1.885035075, 0.991021586], 'a': [1.0, -1.883091902, 0.9801]}], ['regression: f0=60 fs=480 r=9/10', ['60', '480', '9/10'], {'b': [0.917071068, -1.296934342, 0.917071068], 'a': [1.0, -1.272792206, 0.81]}]], [['regression: f0=1 fs=8 r=9/10', ['1', '8', '9/10'], {'b': [0.917071068, -1.296934342, 0.917071068], 'a': [1.0, -1.272792206, 0.81]}], ['regression: f0=1 fs=8 r=1/2', ['1', '8', '1/2'], {'b': [0.926776695, -1.310660172, 0.926776695], 'a': [1.0, -0.707106781, 0.25]}], ['regression: f0=60 fs=480 r=1/2', ['60', '480', '1/2'], {'b': [0.926776695, -1.310660172, 0.926776695], 'a': [1.0, -0.707106781, 0.25]}], ['control: at nyquist', ['4', '8', '1/2'], 'bad-frequency'], ['control: bad radius', ['1', '8', '1'], 'bad-radius'], ['regression: f0=60 fs=480 r=0', ['60', '480', '0'], {'b': [1.707106781, -2.414213562, 1.707106781], 'a': [1.0, 0.0, 0.0]}], ['regression: f0=60 fs=480 r=9/10', ['60', '480', '9/10'], {'b': [0.917071068, -1.296934342, 0.917071068], 'a': [1.0, -1.272792206, 0.81]}]], [['regression: f0=3 fs=8 r=0', ['3', '8', '0'], {'b': [0.292893219, 0.414213562, 0.292893219], 'a': [1.0, 0.0, 0.0]}], ['regression: f0=3 fs=8 r=9/10', ['3', '8', '9/10'], {'b': [0.902928932, 1.276934342, 0.902928932], 'a': [1.0, 1.272792206, 0.81]}], ['regression: f0=1 fs=8 r=0', ['1', '8', '0'], {'b': [1.707106781, -2.414213562, 1.707106781], 'a': [1.0, 0.0, 0.0]}], ['control: at nyquist', ['4', '8', '1/2'], 'bad-frequency'], ['control: bad radius', ['1', '8', '1'], 'bad-radius'], ['regression: f0=60 fs=480 r=9/10', ['60', '480', '9/10'], {'b': [0.917071068, -1.296934342, 0.917071068], 'a': [1.0, -1.272792206, 0.81]}], ['regression: f0=60 fs=480 r=1/2', ['60', '480', '1/2'], {'b': [0.926776695, -1.310660172, 0.926776695], 'a': [1.0, -0.707106781, 0.25]}]]]
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: f0=50 fs=1000 r=0{'a': [1.0, 0.0, 0.0], 'b': [10.215864547, -19.431729095, 10.215864547]}{'a': [1.0, 0.0, 0.0], 'b': [10.215864547, -19.431729095, 10.215864547]}Passed
regression: f0=50 fs=1000 r=9/10{'a': [1.0, -1.711901729, 0.81], 'b': [1.002158645, -1.90621902, 1.002158645]}{'a': [1.0, -1.711901729, 0.81], 'b': [1.002158645, -1.90621902, 1.002158645]}Passed
regression: f0=50 fs=1000 r=1/2{'a': [1.0, -0.951056516, 0.25], 'b': [3.053966137, -5.80898879, 3.053966137]}{'a': [1.0, -0.951056516, 0.25], 'b': [3.053966137, -5.80898879, 3.053966137]}Passed
control: at nyquistbad-frequencybad-frequencyPassed
control: bad radiusbad-radiusbad-radiusPassed
regression: f0=50 fs=1000 r=99/100{'a': [1.0, -1.883091902, 0.9801], 'b': [0.991021586, -1.885035075, 0.991021586]}{'a': [1.0, -1.883091902, 0.9801], 'b': [0.991021586, -1.885035075, 0.991021586]}Passed
regression: f0=60 fs=480 r=0{'a': [1.0, 0.0, 0.0], 'b': [1.707106781, -2.414213562, 1.707106781]}{'a': [1.0, 0.0, 0.0], 'b': [1.707106781, -2.414213562, 1.707106781]}Passed

SHA-256 / 190b3fbe490ec9f03ef979b23d6f6cbcfd9b49bcbb003979f018c924c932c186

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

Case digest / dcac5e2b4fe938735a48543db579fa6f6a05862205f92162c185e3989571b45a