در بازبینی مسیر صوت، دیدنِ یک عدد با برچسبِ «تأخیر» کافی نیست؛ باید معلوم باشد این عدد به کدام بخش و کدام تعریف تعلق دارد. این درس فقط سهمِ نظریِ یک فیلترِ دیجیتالِ علّی با ضرایبِ معلوم را بررسی می‌کند. ورودی‌ها ساختگی‌اند و نرخِ نمونه‌برداری، فرضِ آزمایش است. نه تماسِ اینترنتی، شبکه، کدک یا صفِ دریافت اندازه‌گیری می‌شود و نه از نتیجه، زمانِ پاسخ‌گوییِ یک سامانهٔ واقعی را نتیجه می‌گیریم.

۱. تأخیرِ خودِ فیلتر را از زمانِ کلِ مسیر جدا کنیم

زمانِ یک بخش با زمانِ تمامِ مسیر یکی نیست
تصویر مفهومی: زمانِ یک بخش با زمانِ تمامِ مسیر یکی نیست؛ بدون مقیاس عددی و مستقل از نتایج اجرای کد.

در FIR، خروجیِ نمونهٔ جاری از جمعِ ضرایبِ ضرب‌شده در ورودیِ جاری و گذشته ساخته می‌شود. ترتیبِ ضریبِ صفر، نمونهٔ جاری است. فرمولِ تابعِ تبدیل در راهنمای کاملِ freqz در SciPy همین جمعِ نمایی را نشان می‌دهد؛ در اینجا مخرج یک است و بازخوردِ خروجی نداریم. زمانِ صرف‌شده برای اجرای حلقه، با ویژگیِ فازیِ همین مدل یک کمیت نیست.

ضرایبِ مثال، یک‌شانزدهم، یک‌چهارم، سه‌هشتم، یک‌چهارم و یک‌شانزدهم‌اند؛ مجموعشان یک و طولشان پنج است. این‌ها ضرایبِ انتخاب‌شدهٔ آموزشی‌اند، نه نتیجهٔ طراحی برای کیفیتِ گفتار یا فرکانسِ قطعِ سفارش‌داده‌شده. دامنهٔ نمونه و ضریب بی‌بُعد است. پاسخِ ضربه همان پنج ضریب است و در چند نمونه پخش می‌شود؛ بنابراین تأخیرِ دو نمونه به معنای برابر بودنِ خروجی با نسخهٔ صرفاً جابه‌جاشدهٔ هر ورودی نیست.

با نرخِ فرضیِ ۸۰۰۰ هرتز، هر نمونه یک‌هشتمِ میلی‌ثانیه و دو نمونه یک‌چهارمِ میلی‌ثانیه‌اند. در ۱۶۰۰۰ هرتز، دو نمونه یک‌هشتمِ میلی‌ثانیه می‌شوند. این تبدیل فقط تقسیمِ تعدادِ نمونه بر نرخ است؛ برنامه با عوض کردنِ این عدد، صوت را دوباره نمونه‌برداری نمی‌کند. تأخیرِ بسته‌بندی، ارسال، صف و زمانِ محاسبه باید در آزمایشی دیگر تعریف و اندازه‌گیری شوند.

۲. تقارنِ ضرایب چه چیزی را دربارهٔ فاز ثابت می‌کند؟

آینه‌بودنِ چیدمان، تقارنِ ضرایب را یادآوری می‌کند
تصویر مفهومی: آینه‌بودنِ چیدمان، تقارنِ ضرایب را یادآوری می‌کند؛ بدون مقیاس عددی و مستقل از نتایج اجرای کد.

مستندات firwin فیلترهای فازخطیِ طولِ فرد و زوج را جدا معرفی می‌کند. ما تابعِ طراحیِ آن را اجرا نمی‌کنیم و تنها زیرمجموعهٔ حقیقی، متقارن و طولِ فرد را می‌پذیریم. برای طولِ N، مرکزِ اندیسی d برابر نصفِ حاصلِ N منهای یک، یعنی (N−۱)/۲ است. تقارنِ دقیق یعنی ضریبِ جایگاهِ k با ضریبِ جایگاهِ N−۱−k برابر باشد؛ نزدیک‌بودنِ دو عدد، در این قرارداد جای برابری را نمی‌گیرد.

با جفت‌کردنِ ضرایبِ دو سوی مرکز، پاسخ به شکلِ H(ω)=exp(−jωd) A(ω) نوشته می‌شود. عاملِ A حقیقی است: ضریبِ مرکزی به‌علاوهٔ دو برابرِ مجموعِ ضریب‌های نیمهٔ نخست ضربدر کسینوسِ فاصله‌شان از مرکز. این استدلالِ جبریِ خودمان، دلیلِ ثابت‌بودنِ شیبِ فاز در هر همسایگیِ بدونِ صفر است. در هر چنین بازه‌ای علامتِ A ثابت می‌ماند و فقط سهمِ ثابتِ صفر یا π به فاز اضافه می‌کند.

اگر فازِ پیوسته را نسبت به فرکانسِ زاویه‌ایِ بر حسبِ رادیان بر نمونه مشتق بگیریم و منفی کنیم، d نمونه به دست می‌آید. تعریفِ تأخیرِ گروهی در group_delay نیز بر مشتقِ فازِ پیوسته تکیه دارد. این حکم، فیلترِ نامتقارن، ضرایبِ مختلط، همه‌صفر یا پاسخِ صفر در یک فرکانس را پوشش نمی‌دهد؛ کوچک‌بودنِ خطای چند آزمون، این فرض‌ها را حذف نمی‌کند.

۳. صفرِ پاسخ و فازِ پیچیده‌شده کجا گمراه می‌کنند؟

نبودِ پاسخ، گواهِ تأخیرِ صفر نیست
تصویر مفهومی: نبودِ پاسخ، گواهِ تأخیرِ صفر نیست؛ بدون مقیاس عددی و مستقل از نتایج اجرای کد.

در فرکانسی که پاسخ دقیقاً صفر است، زاویهٔ آن تعریف نمی‌شود و تأخیرِ گروهیِ همان نقطه نیز تعریف ندارد. راهنمای SciPy تصریح می‌کند که در چنین وضعیت‌هایی هشدار می‌دهد و مقدارِ بازگشتی را صفر می‌گذارد. آن صفر، قراردادِ گزارشِ کتابخانه است، نه شاهدِ عبورِ بی‌تأخیرِ مؤلفه‌ای که پاسخ ندارد. کدِ خودمان به جای جعلِ عددِ تأخیر، مقدارِ None برمی‌گرداند؛ هیچ اجرای SciPy برای مقایسه انجام نشده است.

برای ضرایبِ اصلی، پاسخ در ω برابر π با جمعِ متناوبِ کسرها دقیقاً صفر است. ولی محاسبهٔ مختلط از سینوس و کسینوسِ شناور استفاده می‌کند؛ باقیماندهٔ بسیار کوچک ممکن است دیده شود. سیاستِ ما پاسخ‌های کوچک‌تر یا مساویِ یک تریلیونیمِ مجموعِ قدرمطلقِ ضرایب را گزارش‌ناپذیر می‌گیرد. این محافظ، تشخیصِ دقیقِ ریشه نیست: در π منهای ۰٫۰۰۱ نیز عاملِ نظری مثبت است، اما همین محافظ عددِ تأخیر را پنهان می‌کند.

شاهدِ جدا، سه ضریبِ یک‌سوم دارد. در ۰٫۸π، عاملِ حقیقی منفی است و نسبتِ منفیِ زاویهٔ اصلیِ پاسخ به فرکانس، حدودِ منفی یک‌چهارم می‌شود؛ تأخیرِ گروهیِ محلی یک نمونه است. از یک زاویهٔ پیچیده‌شده نمی‌توان شیبِ فاز را استخراج کرد. پیوسته‌سازیِ فاز، انتخابِ شاخه و تأخیرِ فاز مسئله‌های مرتبط اما متفاوت‌اند؛ این فایل الگوریتمِ عمومیِ بازکردنِ فاز را پیاده نمی‌کند.

۴. کدِ کامل و مرجعِ مستقلِ کانولوشن

مرجعِ مستقل و کدِ اصلی باید جدا بررسی شوند
تصویر مفهومی: مرجعِ مستقل و کدِ اصلی باید جدا بررسی شوند؛ بدون مقیاس عددی و مستقل از نتایج اجرای کد.

فایل با Python 3.14.5 و فقط کتابخانهٔ استاندارد یک بار اجرا شده است. ضرایب باید tuple دقیق با طولِ فردِ یک تا نه باشند؛ هر عضو int دقیق یا Fraction دقیق، با قدرِ حداکثر چهار و مخرجِ حداکثر ۱۰۲۴ است. تقارن و غیرصفر بودن بررسی می‌شوند. نرخ، int دقیقِ ۱۰۰۰ تا ۱۹۲۰۰۰ هرتز است؛ bool و زیرکلاس‌ها پذیرفته نمی‌شوند. فرکانس نیز int یا float دقیق، در بازهٔ صفر تا π است و NaN و بی‌نهایت رد می‌شوند.

"""Original bounded symmetric FIR delay lesson; no SciPy/audio/network run."""
from fractions import Fraction
from itertools import product
from enum import IntEnum
import cmath
import json
import math
import platform

RELATIVE_NULL_GUARD = 1e-12


def _taps(values):
    if type(values) is not tuple or not 1 <= len(values) <= 9 or len(values) % 2 != 1:
        raise ValueError("taps_shape")
    if any(type(v) not in (int, Fraction) for v in values):
        raise ValueError("tap_type")
    result = tuple(Fraction(v) for v in values)
    if any(abs(v) > 4 or v.denominator > 1024 for v in result):
        raise ValueError("tap_bound")
    if not any(result):
        raise ValueError("all_zero")
    if result != result[::-1]:
        raise ValueError("not_exactly_symmetric")
    return result


def filter_info(taps, fs_hz):
    """Return exact component delay; not an end-to-end measurement."""
    h = _taps(taps)
    if type(fs_hz) is not int or not 1000 <= fs_hz <= 192000:
        raise ValueError("sample_rate")
    delay = Fraction(len(h) - 1, 2)
    return delay, 1000 * delay / fs_hz


def probe(taps, omega):
    """Numerical H and group delay, or None under a declared relative guard."""
    h = _taps(taps)
    if type(omega) not in (int, float) or not 0 <= omega <= math.pi:
        raise ValueError("frequency")
    w = float(omega)
    terms = [float(c) * cmath.exp(-1j * w * n) for n, c in enumerate(h)]
    response = sum(terms, 0j)
    scale = sum(abs(float(c)) for c in h)
    if abs(response) <= RELATIVE_NULL_GUARD * scale:
        return response, None
    moment = sum((n * term for n, term in enumerate(terms)), 0j)
    # H' = -j * moment; -Im(H'/H) = Re(moment/H).
    return response, (moment / response).real


def fir_full(samples, taps):
    """Exact full causal convolution of bounded synthetic integer amplitudes."""
    h = _taps(taps)
    if type(samples) is not tuple or len(samples) > 8:
        raise ValueError("samples_shape")
    if any(type(x) is not int or not -4 <= x <= 4 for x in samples):
        raise ValueError("sample_value")
    if not samples:
        return ()
    return tuple(sum((c * samples[n - k] for k, c in enumerate(h)
                      if 0 <= n - k < len(samples)), Fraction())
                 for n in range(len(samples) + len(h) - 1))


def _four_average_reference(samples):
    """Independent factorized model: cascade four [1/2,1/2] stages."""
    if not samples:
        return ()
    old = tuple(Fraction(x) for x in samples)
    for _ in range(4):
        old = tuple((old[n] if n < len(old) else Fraction()) / 2
                    + (old[n - 1] if n > 0 else Fraction()) / 2
                    for n in range(len(old) + 1))
    return old


def _paired_factor(taps, w):
    """Separate real cosine-pair construction; no direct complex response sum."""
    middle = (len(taps) - 1) // 2
    real_factor = float(taps[middle]) + 2 * sum(
        float(taps[k]) * math.cos((middle - k) * w) for k in range(middle))
    return cmath.exp(-1j * middle * w) * real_factor


def _rejects(function, *args):
    try:
        function(*args)
    except ValueError:
        return True
    return False


def run_checks():
    h = tuple(Fraction(x, 16) for x in (1, 4, 6, 4, 1))
    delay, milliseconds = filter_info(h, 8000)
    checks = {}
    checks["literal_five_tap_component_samples_and_two_sample_rates"] = (
        delay == 2 and milliseconds == Fraction(1, 4)
        and filter_info(h, 16000) == (Fraction(2), Fraction(1, 8)))
    impulse = fir_full((1,), h)
    checks["literal_full_impulse_is_spread_not_a_pure_two_sample_shift"] = (
        impulse == h and impulse != (Fraction(0), Fraction(0), Fraction(1), Fraction(0), Fraction(0))
        and len(fir_full((-4, 4) * 4, h)) == 12)
    oracle_cases, cascade_ok = 0, True
    for size in range(5):
        for xs in product((-1, 0, 1), repeat=size):
            cascade_ok = cascade_ok and fir_full(xs, h) == _four_average_reference(xs)
            oracle_cases += 1
    checks["independent_four_stage_rational_oracle_121_sequences"] = (
        oracle_cases == 121 and cascade_ok)
    filters = []
    for half_size in (1, 2, 3):
        for first in product((-1, 0, 1), repeat=half_size):
            candidate = first + first[-2::-1]
            if any(candidate):
                filters.append(candidate)
    factor_cases, factor_error, group_error, defined = 0, 0.0, 0.0, 0
    for taps in filters:
        for index in range(9):
            w = math.pi * index / 8
            response, gd = probe(taps, w)
            factor_error = max(factor_error, abs(response - _paired_factor(taps, w)))
            factor_cases += 1
            if gd is not None:
                group_error = max(group_error, abs(gd - (len(taps) - 1) / 2))
                defined += 1
    checks["independent_cosine_pair_factorization_36_filters_324_points"] = (
        len(filters) == 36 and factor_cases == 324 and factor_error < 1e-12)
    checks["analytic_complex_moment_delay_at_resolved_grid_points"] = (
        defined > 0 and group_error < 1e-10)
    exact_pi = sum((c * (-1) ** n for n, c in enumerate(h)), Fraction())
    checks["exact_nyquist_zero_is_not_reported_as_zero_delay"] = (
        exact_pi == 0 and probe(h, math.pi)[1] is None)
    near_w = math.pi - 1e-3
    exact_form_amplitude = math.cos(near_w / 2) ** 4
    checks["near_null_guard_is_not_an_exact_mathematical_zero_classifier"] = (
        exact_form_amplitude > 0 and probe(h, near_w)[1] is None)
    signed_taps = (Fraction(1, 3),) * 3
    w = 0.8 * math.pi
    response, gd = probe(signed_taps, w)
    principal_quotient = -cmath.phase(response) / w
    checks["negative_real_factor_exposes_principal_phase_quotient_error"] = (
        math.isclose(principal_quotient, -0.25, abs_tol=1e-12)
        and math.isclose(gd, 1.0, abs_tol=1e-12)
        and not math.isclose(principal_quotient, gd, abs_tol=1e-12))
    derivative_error = 0.0
    for taps in (h, signed_taps, (1, -2, 1)):
        for w in (0.2, 0.7, 1.3, 2.4):
            eps = 1e-5
            left = probe(taps, w - eps)[0]
            right = probe(taps, w + eps)[0]
            local_slope_delay = -cmath.phase(right / left) / (2 * eps)
            derivative_error = max(derivative_error,
                                   abs(local_slope_delay - probe(taps, w)[1]))
    checks["independent_local_phase_difference_twelve_resolved_points"] = derivative_error < 1e-8
    base = probe(h, 0.7)[1]
    changed_gain = probe(tuple(-2 * c for c in h), 0.7)[1]
    padded = probe((0,) + h + (0,), 0.7)[1]
    checks["gain_and_one_sample_symmetric_padding_have_distinct_delay_effects"] = (
        math.isclose(changed_gain, base, abs_tol=1e-12)
        and math.isclose(padded, base + 1, abs_tol=1e-12)
        and filter_info((0,) + h + (0,), 8000)[0] == delay + 1)
    highpass = (1, -2, 1)
    checks["zero_dc_gain_does_not_invalidate_all_other_frequencies"] = (
        sum(highpass) == 0 and probe(highpass, 0)[1] is None
        and math.isclose(probe(highpass, 1.3)[1], 1, abs_tol=1e-12)
        and filter_info(highpass, 8000)[0] == 1)
    checks["one_tap_negative_gain_and_maximum_nine_tap_contract"] = (
        filter_info((-4,), 1000) == (Fraction(0), Fraction(0))
        and probe((-4,), 1.0)[1] == 0
        and filter_info((1,) * 9, 192000) == (Fraction(4), Fraction(1, 48))
        and filter_info((Fraction(1, 1024),) * 9, 192000)[0] == 4
        and fir_full((), h) == ())
    class SubInt(int):
        pass
    class SubTuple(tuple):
        pass
    class SubFraction(Fraction):
        pass
    class Foreign(IntEnum):
        ONE = 1
    bad_taps = [(), [], (1, 1), (1,) * 11, (0,), (1, 2, 0),
                (True,), (1.0,), (math.nan,), (math.inf,), (1j,),
                (SubInt(1),), (Foreign.ONE,), (SubFraction(1),),
                (Fraction(1, 1025),), (5,), SubTuple((1,))]
    bad_rates = (True, 8000.0, 999, 192001, SubInt(8000), Foreign.ONE, "8000")
    bad_w = (True, math.nan, math.inf, -0.1, math.pi + 0.1, 1j, SubInt(1))
    bad_samples = ([1], (0,) * 9, (True,), (1.0,), (5,), (SubInt(1),), (Foreign.ONE,))
    rejections = ([_rejects(filter_info, taps, 8000) for taps in bad_taps]
                  + [_rejects(filter_info, h, rate) for rate in bad_rates]
                  + [_rejects(probe, h, w) for w in bad_w]
                  + [_rejects(fir_full, xs, h) for xs in bad_samples])
    checks["strict_bounded_shape_value_frequency_rate_and_sample_rejections"] = all(rejections)
    assert all(type(v) is bool and v for v in checks.values()), checks
    return {"python": platform.python_version(), "implementation": platform.python_implementation(),
            "dependencies": "standard library only", "scipy_executed": False, "matlab_executed": False,
            "units": {"taps_samples": "dimensionless synthetic amplitudes",
                      "omega": "radians/sample", "group_delay": "samples",
                      "sample_rate": "Hz", "reported_component_time": "milliseconds"},
            "main_taps_exact": [str(c) for c in h], "main_impulse_exact": [str(c) for c in impulse],
            "main_component_delay_samples": str(delay),
            "component_milliseconds_at_8000_Hz": str(milliseconds),
            "component_milliseconds_at_16000_Hz": str(filter_info(h, 16000)[1]),
            "exact_H_at_pi": str(exact_pi), "numerical_pi_group_delay": None,
            "relative_response_guard": RELATIVE_NULL_GUARD,
            "near_null_positive_cosine_form_amplitude": exact_form_amplitude,
            "negative_factor_example": {"omega_over_pi": 0.8,
                "principal_arg_quotient_samples": principal_quotient,
                "group_delay_samples": gd},
            "cases_within_groups": {"four_stage_oracle_sequences": oracle_cases,
                "symmetric_filters": len(filters), "frequency_grid_points": factor_cases,
                "resolved_group_delay_points": defined,
                "local_phase_difference_points": 12, "invalid_contract_cases": len(rejections)},
            "maximum_pair_factor_absolute_difference": factor_error,
            "maximum_resolved_group_delay_absolute_difference": group_error,
            "maximum_local_phase_difference_absolute_difference": derivative_error,
            "checks": checks,
            "limits": ["Exact odd real symmetric taps, chosen finite input domain, not an arbitrary filter API",
                       "Group delay is undefined at exact zeros; None guard also masks small NONZERO responses",
                       "No phase unwrap implementation or universal tolerance guarantee",
                       "Component delay is not call, network, codec, buffering, wallclock or processing latency",
                       "No actual audio, SciPy/MATLAB execution, design specification, benchmark or speech-quality claim"]}


if __name__ == "__main__":
    print(json.dumps(run_checks(), ensure_ascii=False, indent=2))

کانولوشنِ کامل، حداکثر هشت نمونهٔ صحیحِ ساختگی در بازهٔ منفی چهار تا چهار می‌گیرد. ورودیِ غیرخالی با طولِ L، دقیقاً L+N−۱ خروجی می‌دهد؛ ورودیِ خالی طبقِ قرارداد خروجیِ خالی دارد. محاسبهٔ این بخش با کسرها دقیق است. مرجعِ مستقل، ضرایبِ پنج‌تایی را دریافت نمی‌کند: چهار مرحلهٔ پیاپیِ میانگینِ دوهمسایه‌ای را با آغاز و پایانِ صفر می‌سازد و با خروجیِ تابعِ جمع‌آوریِ اصلی مقایسه می‌کند.

۱۳ گروهِ نام‌دار موفق شدند. ۱۲۱ دنباله در مرجعِ چهارمرحله‌ای، ۳۶ فیلتر در ۳۲۴ نقطهٔ فرکانسی و ۳۸ ورودیِ نامعتبر، حالت‌های داخلِ گروه‌ها هستند. بازنویسیِ جدا با جفتِ کسینوسی، جمعِ مختلط را می‌سنجد؛ اختلافِ فازِ دو نقطهٔ نزدیک نیز در دوازده نقطهٔ دور از صفر، کنترلِ مستقلی برای مشتق است. این کنترلِ عددیِ محدود، اثباتِ دقت برای همهٔ فرکانس‌ها یا تمامِ سخت‌افزارها نیست.

{
  "python": "3.14.5",
  "implementation": "CPython",
  "dependencies": "standard library only",
  "scipy_executed": false,
  "matlab_executed": false,
  "units": {
    "taps_samples": "dimensionless synthetic amplitudes",
    "omega": "radians/sample",
    "group_delay": "samples",
    "sample_rate": "Hz",
    "reported_component_time": "milliseconds"
  },
  "main_taps_exact": [
    "1/16",
    "1/4",
    "3/8",
    "1/4",
    "1/16"
  ],
  "main_impulse_exact": [
    "1/16",
    "1/4",
    "3/8",
    "1/4",
    "1/16"
  ],
  "main_component_delay_samples": "2",
  "component_milliseconds_at_8000_Hz": "1/4",
  "component_milliseconds_at_16000_Hz": "1/8",
  "exact_H_at_pi": "0",
  "numerical_pi_group_delay": null,
  "relative_response_guard": 1e-12,
  "near_null_positive_cosine_form_amplitude": 6.249998958333719e-14,
  "negative_factor_example": {
    "omega_over_pi": 0.8,
    "principal_arg_quotient_samples": -0.25000000000000006,
    "group_delay_samples": 1.0
  },
  "cases_within_groups": {
    "four_stage_oracle_sequences": 121,
    "symmetric_filters": 36,
    "frequency_grid_points": 324,
    "resolved_group_delay_points": 312,
    "local_phase_difference_points": 12,
    "invalid_contract_cases": 38
  },
  "maximum_pair_factor_absolute_difference": 9.930136612989092e-16,
  "maximum_resolved_group_delay_absolute_difference": 7.549516567451064e-15,
  "maximum_local_phase_difference_absolute_difference": 3.660871605859484e-11,
  "checks": {
    "literal_five_tap_component_samples_and_two_sample_rates": true,
    "literal_full_impulse_is_spread_not_a_pure_two_sample_shift": true,
    "independent_four_stage_rational_oracle_121_sequences": true,
    "independent_cosine_pair_factorization_36_filters_324_points": true,
    "analytic_complex_moment_delay_at_resolved_grid_points": true,
    "exact_nyquist_zero_is_not_reported_as_zero_delay": true,
    "near_null_guard_is_not_an_exact_mathematical_zero_classifier": true,
    "negative_real_factor_exposes_principal_phase_quotient_error": true,
    "independent_local_phase_difference_twelve_resolved_points": true,
    "gain_and_one_sample_symmetric_padding_have_distinct_delay_effects": true,
    "zero_dc_gain_does_not_invalidate_all_other_frequencies": true,
    "one_tap_negative_gain_and_maximum_nine_tap_contract": true,
    "strict_bounded_shape_value_frequency_rate_and_sample_rejections": true
  },
  "limits": [
    "Exact odd real symmetric taps, chosen finite input domain, not an arbitrary filter API",
    "Group delay is undefined at exact zeros; None guard also masks small NONZERO responses",
    "No phase unwrap implementation or universal tolerance guarantee",
    "Component delay is not call, network, codec, buffering, wallclock or processing latency",
    "No actual audio, SciPy/MATLAB execution, design specification, benchmark or speech-quality claim"
  ]
}

درسِ بازخورد و حالتِ فیلترِ مرتبه‌دو دربارهٔ ساختارِ دیگری است و دامنهٔ FFT و پنجره قراردادِ نمایشِ طیف را بررسی می‌کند. اینجا نه حالتِ آن فیلتر را منتقل می‌کنیم و نه از قلهٔ طیف، تأخیر می‌خوانیم. مستنداتِ مرجع هنگامِ مطالعه SciPy 1.18.0 بود؛ نسخهٔ مرجع با محیطِ اجرای پایتونِ ما جدا ثبت شده است.

۵. چهار پرسش دربارهٔ نمونه، میلی‌ثانیه و محدودیت

تبدیلِ واحد و محدودیتِ مدل به پرسش‌های جدا نیاز دارند
تصویر مفهومی: تبدیلِ واحد و محدودیتِ مدل به پرسش‌های جدا نیاز دارند؛ بدون مقیاس عددی و مستقل از نتایج اجرای کد.

پرسش اول: با دو برابر شدنِ نرخ، تأخیرِ دو نمونه چه می‌شود؟ پاسخ: اگر همان ضرایب را با نرخِ جدید تفسیر کنیم، دو نمونه باقی می‌ماند ولی زمان از یک‌چهارم به یک‌هشتمِ میلی‌ثانیه می‌رسد. این محاسبه، تبدیلِ نرخِ داده یا ثابت‌ماندنِ پاسخ بر حسبِ هرتز را ثابت نمی‌کند؛ فرکانسِ زاویه‌ای و فرکانسِ فیزیکی نیز با نرخ مرتبط‌اند.

پرسش دوم: صفرِ پاسخ یعنی صفرِ تأخیر؟ پاسخ: خیر؛ در نقطهٔ صفر، زاویه و مشتقِ لازم تعریف ندارند. None در خروجیِ ما ممکن است علاوه بر صفرِ دقیق، پاسخِ غیرصفرِ کوچک را هم بپوشاند. برای همین، شاهدِ جمعِ متناوبِ دقیق و آستانهٔ عددی را جدا نگه می‌داریم و خانهٔ خالی را به عددِ موفق تبدیل نمی‌کنیم.

پرسش سوم: ضربِ تمامِ ضرایب در منفی دو، تأخیر را دو برابر می‌کند؟ پاسخ: خیر؛ بهره و شاخهٔ فاز عوض می‌شوند، اما مشتقِ محلیِ فاز در نقاطِ دارای پاسخ همان است. در مقابل، افزودنِ یک صفر به هر دو سرِ ضرایب، عاملِ یک نمونه تأخیر اضافه می‌کند. هر دو تغییر در کد جدا آزموده شده‌اند؛ تعدادِ ضرایبِ ظاهری را بدون توجه به جایگاهشان تفسیر نمی‌کنیم.

پرسش چهارم: موفقیتِ آزمون‌ها برای تأییدِ مکالمه کافی است؟ پاسخ: خیر؛ فقط قراردادِ محدودِ محاسبه و مثالِ مؤلفهٔ فیلتر بررسی شده‌اند. کیفیتِ شنیداری، تأخیرِ انتهابه‌انتها، طراحیِ گذرباند و اجرای بی‌درنگ ارزیابی نشده‌اند. منابع در ۲۷ مهر ۱۴۰۵ خوانده شدند؛ تاریخِ انتشارِ نخستِ صفحات معلوم نبود. این متن آموزشِ پایه است و تصاویرِ مفهومیِ آن گزارشِ خروجیِ عددی یا خبرِ محصول نیستند.

منابع و مطالعهٔ بیشتر

بررسی منابع: ۲۷ مهر ۱۴۰۵. تحلیل‌ها و پیشنهادهای اجرایی، جمع‌بندی نویسنده‌اند.