Обратное ДПФ, амплитудный и фазовый спектр

Замыкаем круг: возвращаемся из спектра во время и разбираем две части спектра — амплитуду и фазу.

Обратное ДПФ восстанавливает сигнал из спектра: x[n] = (1/N)*sum(X[k]*exp(+2j*pi*k*n/N)). Прямое и обратное ДПФ — это пара, переводящая сигнал туда и обратно без потерь.

ДПФ обратимо: из спектра можно точно собрать исходный сигнал. Это критично для практики — фильтрация в частотной области работает так: перешли в спектр, что-то поправили, вернулись во время. А ещё спектр состоит из двух частей — амплитудной и фазовой, — и важно понимать роль каждой.

Обратное ДПФ: туда и обратно

Формула обратного ДПФ отличается знаком в экспоненте (плюс вместо минуса) и делением на N. Проверим, что прямое ДПФ с последующим обратным точно возвращают сигнал.

import math, cmath

def dft(x):
    N = len(x)
    return [sum(x[n] * cmath.exp(-2j * math.pi * k * n / N) for n in range(N))
            for k in range(N)]

def idft(X):
    N = len(X)
    return [sum(X[k] * cmath.exp(2j * math.pi * k * n / N) for k in range(N)).real / N
            for n in range(N)]

x = [1.0, 2.0, 3.0, 4.0]
X = dft(x)
restored = [round(v, 3) for v in idft(X)]
print("исходный: ", x)
print("ДПФ -> оДПФ:", restored)

Вывод:

исходный:  [1.0, 2.0, 3.0, 4.0]
ДПФ -> оДПФ: [1.0, 2.0, 3.0, 4.0]

Сигнал восстановлен в точности. Прямое и обратное ДПФ — обратимая пара, ничего не теряется.

Амплитудный и фазовый спектр

Комплексный X[k] распадается на две вещественные кривые. Амплитудный спектр |X[k]| — «сколько» каждой частоты (громкость тона). Фазовый спектр arg(X[k]) — «когда» каждая частота начинается (сдвиг). Возьмём косинус с фазой pi/4 и убедимся, что ДПФ восстановит и амплитуду, и фазу.

import math, cmath

def dft(x):
    N = len(x)
    return [sum(x[n] * cmath.exp(-2j * math.pi * k * n / N) for n in range(N))
            for k in range(N)]

N = 8
sig = [math.cos(2 * math.pi * 1 * n / N + math.pi / 4) for n in range(N)]
X = dft(sig)

amps = [round(abs(c) / (N / 2), 3) or 0.0 for c in X[:N // 2 + 1]]
phases = [round(cmath.phase(c), 3) if abs(c) > 1e-6 else 0.0 for c in X[:N // 2 + 1]]
print("амплитуды:", amps)
print("фазы(рад):", phases)
print("pi/4 =", round(math.pi / 4, 3))

Вывод:

амплитуды: [0.0, 1.0, 0.0, 0.0, 0.0]
фазы(рад): [0.0, 0.785, 0.0, 0.0, 0.0]
pi/4 = 0.785

Амплитудный спектр показывает линию на бине 1 с амплитудой 1.0 (наш косинус). Фазовый спектр на том же бине даёт 0.785 — это ровно pi/4, фаза, которую мы заложили. ДПФ восстановил оба параметра.

Как работает под капотом

Почему фаза важна? Амплитудный спектр говорит, какие частоты есть, но не как они выстроены во времени. Два сигнала с одинаковым амплитудным спектром, но разными фазами, звучат и выглядят по-разному. Классический пример: если у речевого сигнала сохранить амплитудный спектр, но обнулить фазы, разборчивость пропадёт — именно фаза несёт информацию о форме и временной структуре. Поэтому при обработке в частотной области нельзя выбрасывать фазу: меняем амплитуды (фильтрация), но фазу обычно сохраняем или корректируем аккуратно. Энергия сигнала при этом сохраняется и во времени, и в спектре — это теорема Парсеваля: sum(x[n]²) = (1/N)*sum(|X[k]|²).

Частые ошибки

  • Терять мнимую часть при обратном ДПФ. Из-за округлений она крошечная, но игнорировать структуру нельзя; для вещественного сигнала берут .real осознанно.
  • Считать фазу неважной. Фаза несёт временную структуру; её порча разрушает сигнал даже при правильных амплитудах.
  • Забывать делитель N в обратном ДПФ. Без него амплитуда восстановленного сигнала вырастет в N раз.

Итог

  • Обратное ДПФ восстанавливает сигнал из спектра: знак «+» в экспоненте и делитель N.
  • Прямое и обратное ДПФ — обратимая пара без потерь.
  • Амплитудный спектр — «сколько» частоты, фазовый — «когда» она начинается.
  • Фаза несёт временную структуру; её нельзя выбрасывать при обработке.
Проверьте себя
1. Чем формула обратного ДПФ отличается от прямого?
AНичем
BЗнаком в экспоненте (+ вместо -) и делением на N
CИспользует только вещественные числа
DМеняет частоту дискретизации
2. Что показывает фазовый спектр?
AГромкость каждой частоты
BСдвиг (когда начинается) каждой частоты
CЧисло отсчётов
DУровень шума
3. Почему при обработке нельзя выбрасывать фазовый спектр?
AОн не занимает память
BФаза несёт временную структуру сигнала; без неё форма разрушается
CФаза всегда нулевая
DЕё и так нельзя измерить