БИХ-фильтры (IIR): рекурсия и обратная связь
Разбираем IIR — фильтры с обратной связью: они экономнее FIR, но требуют осторожности.
IIR-фильтр (БИХ, с бесконечной импульсной характеристикой) использует обратную связь: выход зависит не только от входа, но и от прошлых выходов:
y[n] = b*x[n] + a*y[n-1] + .... Отсюда бесконечный импульсный отклик.
FIR прост и надёжен, но «прожорлив»: крутой фильтр требует сотни коэффициентов. IIR решает ту же задачу горсткой коэффициентов за счёт хитрого приёма — обратной связи. Эхо, реверберация, резонанс, аналоговые фильтры (Баттерворта, Чебышёва) — всё это IIR. Но обратная связь несёт риск: фильтр может «разойтись». Разберёмся.
Однополюсный IIR: эконом-сглаживатель
Простейший IIR — однополюсный ФНЧ: y[n] = a*x[n] + (1-a)*y[n-1]. Каждый новый выход — это смесь нового входа и предыдущего выхода. Всего один коэффициент, а сглаживает не хуже длинного FIR.
def iir_lowpass(x, a):
y = []
prev = 0.0
for s in x:
prev = a * s + (1 - a) * prev # обратная связь: используем прошлый выход
y.append(round(prev, 3))
return y
step = [0, 0] + [10] * 8 # сигнал-ступенька
print("вход: ", step)
print("IIR (a=0.5): ", iir_lowpass(step, 0.5))
Вывод:
вход: [0, 0, 10, 10, 10, 10, 10, 10, 10, 10] IIR (a=0.5): [0.0, 0.0, 5.0, 7.5, 8.75, 9.375, 9.688, 9.844, 9.922, 9.961]
Выход плавно подползает к уровню 10 — это классическая экспоненциальная реакция ФНЧ. Параметр a задаёт скорость: меньше a — медленнее и сильнее сглаживание. И всё это одним коэффициентом!
Почему импульсная характеристика бесконечна
Подадим в IIR единичный импульс. Из-за обратной связи отклик не обрывается, а бесконечно затухает — отсюда название «бесконечная импульсная характеристика».
def iir_impulse(a, N):
y = []
prev = 0.0
for n in range(N):
x = 1 if n == 0 else 0
prev = a * x + (1 - a) * prev
y.append(round(prev, 4))
return y
print("Импульсный отклик IIR (a=0.5):", iir_impulse(0.5, 8))
Вывод:
Импульсный отклик IIR (a=0.5): [0.5, 0.25, 0.125, 0.0625, 0.0312, 0.0156, 0.0078, 0.0039]
После единственного «укола» отклик тянется бесконечно, уменьшаясь вдвое на каждом шаге. У FIR он оборвался бы на длине ядра — у IIR продолжается вечно, пусть и затухая.
Устойчивость — главный риск IIR
Обратная связь может выйти из-под контроля. Рассмотрим фильтр y[n] = x[n] + a*y[n-1]. При |a| < 1 отклик затухает (устойчив), при |a| > 1 — растёт без предела (неустойчив).
def iir(a, N):
y = []
prev = 0.0
for n in range(N):
x = 1 if n == 0 else 0
prev = x + a * prev
y.append(round(prev, 2))
return y
print("a=0.8 (|a|<1, устойчив): ", iir(0.8, 8))
print("a=1.2 (|a|>1, расходится):", iir(1.2, 8))
Вывод:
a=0.8 (|a|<1, устойчив): [1.0, 0.8, 0.64, 0.51, 0.41, 0.33, 0.26, 0.21] a=1.2 (|a|>1, расходится): [1.0, 1.2, 1.44, 1.73, 2.07, 2.49, 2.99, 3.58]
При a=0.8 отклик мирно затухает. При a=1.2 он растёт лавиной — фильтр «взорвался». Устойчивость IIR надо проверять всегда; для FIR такой проблемы нет в принципе.
Как работает под капотом
Устойчивость IIR определяется положением его полюсов на комплексной плоскости (z-плоскости, см. следующий урок). Правило: все полюса должны лежать внутри единичной окружности — тогда фильтр устойчив. В нашем примере полюс находится в точке z = a: при |a| < 1 он внутри окружности (устойчиво), при |a| > 1 — снаружи (расходится). Реальные IIR-фильтры (Баттерворта, Чебышёва, эллиптические) проектируют, расставляя полюса и нули так, чтобы получить нужную АЧХ при минимальном порядке. IIR даёт крутые срезы дёшево, но платит нелинейной фазой и риском неустойчивости из-за конечной точности вычислений.
Частые ошибки
- Не проверить устойчивость. Полюс вне единичной окружности — и фильтр расходится, выдавая бесконечность.
- Игнорировать нелинейную фазу. IIR искажает форму сигнала; где важна форма, берут FIR или фильтруют «туда-обратно».
- Высокий порядок одним блоком. Из-за округлений длинные IIR теряют устойчивость; их разбивают на каскад биквадов (секций 2-го порядка).
Итог
- IIR использует обратную связь: выход зависит от прошлых выходов.
- Импульсная характеристика бесконечна (затухает, но не обрывается).
- IIR экономнее FIR: крутой фильтр — несколько коэффициентов.
- Расплата — нелинейная фаза и риск неустойчивости (полюса вне единичной окружности).