YaChudo

Швидке перетворення Фур'є

Переглядів: 0. Оновлено 11.10.2026.

Швидке́ перетво́рення Фур'є́ (часто FFT від англ. Fast Fourier Transform) — швидкий алгоритм обчислення дискретного перетворення Фур'є. Якщо для прямого обчислення дискретного перетворення Фур'є з N точок даних потрібно O(N 2) арифметичних операцій, то FFT дозволяє обчислити такий же результат використовуючи O(N log N) операцій. Алгоритм FFT часто використовується для цифрової обробки сигналів для перетворення дискретних даних з часового у частотний діапазон.

Основний алгоритм

Покажемо як виконати дискретне перетворення Фур'є за O ( N ( p 1 + ⋯ + p n ) ) {\displaystyle O(N(p_{1}+\cdots +p_{n}))} обчислень при N = p 1 p 2 ⋯ p n {\displaystyle N=p_{1}p_{2}\cdots p_{n}} . Зокрема, при N = 2 n {\displaystyle N=2^{n}} знадобиться O ( N log ⁡ ( N ) ) {\displaystyle O(N\log(N))} обчислень.

Дискретне перетворення Фур'є перетворює набір чисел a 0 , … , a n − 1 {\displaystyle a_{0},\dots ,a_{n-1}} в набір чисел b 0 , … , b n − 1 {\displaystyle b_{0},\dots ,b_{n-1}} , такий, що b i = ∑ j = 0 n − 1 a j ε i j {\displaystyle b_{i}=\sum _{j=0}^{n-1}a_{j}\varepsilon ^{ij}} , де ε n = 1 {\displaystyle \varepsilon ^{n}=1} і ε k ≠ 1 {\displaystyle \varepsilon ^{k}\neq 1} при 0 < k < n {\displaystyle 0<k<n} . Алгоритм швидкого перетворення Фур'є може бути застосований до будь-яких комутативних асоціативних кілець з одиницею. Найчастіше цей алгоритм застосовують до поля комплексних чисел (з ε = e 2 π i / n {\displaystyle \varepsilon =e^{2\pi i/n}} ) і до кілець залишків за модулем n.

Основний крок алгоритму полягає у зведенні задачі для N {\displaystyle N} чисел до задачі для p = N / q {\displaystyle p=N/q} чисел, де q {\displaystyle q}  — дільник N {\displaystyle N} . Нехай ми вже вміємо вирішувати задачу для N / q {\displaystyle N/q} чисел. Застосуємо перетворення Фур'є до наборів a i , a q + i , … , a q ( p − 1 ) + i {\displaystyle a_{i},a_{q+i},\dots ,a_{q(p-1)+i}} для i = 0 , 1 , … , q − 1 {\displaystyle i=0,1,\dots ,q-1} . Тепер покажемо, як за O ( N p ) {\displaystyle O(Np)} обчислень розв'язати вихідну задачу. Зауважимо, що b i = ∑ j = 0 q − 1 ε i j ( ∑ k = 0 p − 1 a k q + j ε k i q ) {\displaystyle b_{i}=\sum _{j=0}^{q-1}\varepsilon ^{ij}(\sum _{k=0}^{p-1}a_{kq+j}\varepsilon ^{kiq})} . Вирази в дужках нам уже відомі — це i ( mod p ) {\displaystyle i{\pmod {p}}} -те число після перетворення Фур'є j {\displaystyle j} -тої групи. Таким чином, для обчислення кожного b i {\displaystyle b_{i}} потрібно O ( q ) {\displaystyle O(q)} обчислень, а для обчислення всіх b i {\displaystyle b_{i}}  — O ( N q ) {\displaystyle O(Nq)} обчислень.

Обернене перетворення Фур'є

Для оберненого перетворення Фур'є можна застосовувати алгоритм прямого перетворення Фур'є — потрібно лише використовувати ε − 1 {\displaystyle \varepsilon ^{-1}} замість ε {\displaystyle \varepsilon } (або застосувати операцію комплексного спряження спочатку до вхідних даних, а потім до результату, отриманого після прямого перетворення Фур'є) і остаточний результат поділити на N {\displaystyle N} .

Загальний випадок

Загальний випадок можна звести до попереднього. Нехай 4 N > 2 k ≥ 2 N {\displaystyle 4N>2^{k}\geq 2N} . Зауважимо, що b i = ε − i 2 / 2 ∑ j = 0 N − 1 ε ( i + j ) 2 / 2 ε − j 2 / 2 a j {\displaystyle b_{i}=\varepsilon ^{-i^{2}/2}\sum _{j=0}^{N-1}\varepsilon ^{(i+j)^{2}/2}\varepsilon ^{-j^{2}/2}a_{j}} . Позначимо a ¯ i = ε − i 2 / 2 a i , b ¯ i = ε i 2 / 2 b i , c i = ε ( 2 N − 2 − i ) 2 / 2 {\displaystyle {\bar {a}}_{i}=\varepsilon ^{-i^{2}/2}a_{i},{\bar {b}}_{i}=\varepsilon ^{i^{2}/2}b_{i},c_{i}=\varepsilon ^{(2N-2-i)^{2}/2}} . Тоді b ¯ i = ∑ j = 0 2 N − 2 − i a ¯ j c 2 N − 2 − i − j {\displaystyle {\bar {b}}_{i}=\sum _{j=0}^{2N-2-i}{\bar {a}}_{j}c_{2N-2-i-j}} , якщо покласти a ¯ i = 0 {\displaystyle {\bar {a}}_{i}=0} при i ≥ N {\displaystyle i\geq N} .

Таким чином, задачу зведено до обчислення згортки, але це можна зробити за допомогою трьох перетворень Фур'є для 2 k {\displaystyle 2^{k}} елементів. Спочатку виконаємо пряме перетворення Фур'є для { a ¯ i } i = 0 i = 2 k − 1 {\displaystyle \{{\bar {a}}_{i}\}_{i=0}^{i=2^{k}-1}} і { c i } i = 0 i = 2 k − 1 {\displaystyle \{c_{i}\}_{i=0}^{i=2^{k}-1}} , далі перемножимо поелементно результати і виконаємо обернене перетворення Фур'є.

Обчислення всіх a ¯ i {\displaystyle {\bar {a}}_{i}} i c i {\displaystyle c_{i}} потребує O ( N ) {\displaystyle O(N)} операцій, три перетворення Фур'є виконується за O ( N log ⁡ ( N ) ) {\displaystyle O(N\log(N))} операцій, перемноження результатів перетворень Фур'є вимагає O ( N ) {\displaystyle O(N)} операцій; знаючи значення згортки обчислення всіх b i {\displaystyle b_{i}} вимагає O ( N ) {\displaystyle O(N)} операцій. Усього для дискретного перетворення Фур'є потрібно O ( N log ⁡ ( N ) ) {\displaystyle O(N\log(N))} дій для будь-якого N {\displaystyle N} .

Цей алгоритм швидкого перетворення Фур'є може працювати над кільцем тільки коли відомі первісні корені з одиниці ступенів 2 N {\displaystyle 2N} і 2 k {\displaystyle 2^{k}} .

Висновок перетворення з ДПФ

Дискретне перетворення Фур'є для вектора x → {\displaystyle {\vec {x}}} , Що складається з N {\displaystyle N} елементів, має вигляд:

X → = A ^ x → {\displaystyle {\vec {X}}={\hat {A}}{\vec {x}}}

елементи матриці A ^ {\displaystyle {\hat {A}}} мають вигляд: a N m n = exp ⁡ ( − 2 π i m n N ) {\displaystyle a_{N}^{mn}=\exp \left(-2\pi i{\frac {mn}{N}}\right)} .

Нехай N {\displaystyle N} парне, тоді ДПФ можна переписати таким чином:

X m = ∑ n = 0 N − 1 x n a N m n = ∑ n = 0 N / 2 − 1 x 2 n a N 2 n m + ∑ n = 0 N / 2 − 1 x 2 n + 1 a N ( 2 n + 1 ) m {\displaystyle X_{m}=\sum _{n=0}^{N-1}x_{n}a_{N}^{mn}=\sum _{n=0}^{N/2-1}x_{2n}a_{N}^{2nm}+\sum _{n=0}^{N/2-1}x_{2n+1}a_{N}^{(2n+1)m}}

Коефіцієнти a N 2 n m {\displaystyle a_{N}^{2nm}} і a N ( 2 n + 1 ) m {\displaystyle a_{N}^{(2n+1)m}} можна переписати наступним чином ( M = N / 2 ) {\displaystyle (M=N/2)} :

a N 2 n m = exp ⁡ ( − 2 π i 2 m n N ) = exp ⁡ ( − 2 π i m n N / 2 ) = a M n m {\displaystyle a_{N}^{2nm}=\exp \left(-2\pi i{\frac {2mn}{N}}\right)=\exp \left(-2\pi i{\frac {mn}{N/2}}\right)=a_{M}^{nm}}
a N ( 2 n + 1 ) m = exp ⁡ ( − 2 π i m N ) a M n m {\displaystyle a_{N}^{(2n+1)m}=\exp \left(-2\pi i{\frac {m}{N}}\right)a_{M}^{nm}}

У результаті отримаємо:

X m = ∑ n = 0 M − 1 x 2 n a M n m + exp ⁡ ( − 2 π i m N ) ∑ n = 0 M − 1 x 2 n + 1 a M n m {\displaystyle X_{m}=\sum _{n=0}^{M-1}x_{2n}a_{M}^{nm}+\exp \left(-2\pi i{\frac {m}{N}}\right)\sum _{n=0}^{M-1}x_{2n+1}a_{M}^{nm}}

Тобто дискретне перетворення Фур'є від вектора, що складається з N {\displaystyle N} відліків, звелося до лінійної композиції двох ДПФ від N 2 {\displaystyle {\frac {N}{2}}} відліків, і якщо для початкової задачі потрібно N 2 {\displaystyle N^{2}} операцій, то для отриманої композиції — N 2 2 {\displaystyle {\frac {N^{2}}{2}}} . Якщо M {\displaystyle M} є степенем двійки, то цей поділ можна продовжувати рекурсивно доти, поки не дійдемо до двоточкового перетворення Фур'є, яке обчислюється за такими формулами:

{ X 0 = x 0 + x 1 X 1 = x 0 − x 1 {\displaystyle {\begin{cases}X_{0}=x_{0}+x_{1}\\X_{1}=x_{0}-x_{1}\end{cases}}}

Алгоритм Кулі-Тьюкі

Найбільш розповсюдженим алгоритмом розрахунку FFT є алгоритм Кулі — Тьюкі, запропонований Джеймсом Кулі та Джоном Тьюкі в 1965 році[1]. Як з'ясувалося згодом, цей алгоритм був винайдений Карлом Гаусом ще в 1805 році.

Алгоритм заснований на рекурсивному розділенні перетворення на кожному кроці на дві частини розміром N / 2 {\displaystyle N/2} . Якщо N {\displaystyle N} не ділиться на два, то робиться факторизація. Для розрахунку застосовують корені з одиниці.

Дискретне перетворення Фур'є величини 2n визначається як:

f m = ∑ k = 0 2 n − 1 x k e − 2 π i 2 n m k m = 0 , … , 2 n − 1. {\displaystyle f_{m}=\sum _{k=0}^{2n-1}x_{k}\;e^{-{\frac {2\pi i}{2n}}mk}\qquad m=0,\dots ,2n-1.}

Якщо позначити вклади парних індексів як

x'0 = x1, x'1 = x2, …, x'n-1 = x2n-2

та їхні перетворення величини n як

f'0, …, f'n-1;

та вклади непарних індексів

x"0 = x1, x"1 = x3, …, x"n-1 = x2n-1

та їхні перетворення величини n як

f"0, …, f"n-1.

тоді:

f m = ∑ k = 0 n − 1 x 2 k e − 2 π i 2 n m ( 2 k ) + ∑ k = 0 n − 1 x 2 k + 1 e − 2 π i 2 n m ( 2 k + 1 ) = ∑ k = 0 n − 1 x k ′ e − 2 π i n m k + e − π i n m ∑ k = 0 n − 1 x k ″ e − 2 π i n m k = { f m ′ + e − π i n m f m ″ ,  m < n f m − n ′ − e − π i n ( m − n ) f m − n ″ ,  m ≥ n {\displaystyle {\begin{aligned}f_{m}&=\sum _{k=0}^{n-1}x_{2k}e^{-{\frac {2\pi i}{2n}}m(2k)}+\sum _{k=0}^{n-1}x_{2k+1}e^{-{\frac {2\pi i}{2n}}m(2k+1)}\\[0.5em]&=\sum _{k=0}^{n-1}x'_{k}e^{-{\frac {2\pi i}{n}}mk}+e^{-{\frac {\pi i}{n}}m}\sum _{k=0}^{n-1}x''_{k}e^{-{\frac {2\pi i}{n}}mk}\\[0.5em]&={\begin{cases}f'_{m}+e^{-{\frac {\pi i}{n}}m}f''_{m}&{\text{, }}m<n\\[0.5em]f'_{m-n}-e^{-{\frac {\pi i}{n}}(m-n)}f''_{m-n}&{\text{, }}m\geq n\end{cases}}\end{aligned}}}

Інші алгоритми ШПФ

Крім алгоритму Кулі—Тьюкі існують також інші. Для N = N 1 × N 2 {\displaystyle N=N1\times N2} зі взаємно простими N 1 {\displaystyle N1} і N 2 {\displaystyle N2} , можна застосувати алгоритм Гуда—Томаса розкладу на прості дільники (Prime-Factor Algorithm), заснований на китайській теоремі про залишки, щоб факторизувати ДПФ аналогічно Кулі—Тьюкі, але без коефіцієнтів повороту.

Див. також

Джерела

  1. ↑ James W. Cooley, John W. Tukey: An algorithm for the machine calculation of complex Fourier series. In: Math. Comput. 19, 1965, S. 297—301.

Посилання

Джерело: стаття у Вікіпедії та історія редагувань (автори).