Algorytm Cooleya-Tukeya
Algorytm Cooleya-Tukeya jest metodą szybkiej transformacji Fouriera (FFT), która przedstawia dyskretną transformację Fouriera (DFT) dla dowolnej złożonej wielkości N, wyrażonej jako:
N = N1 × N2,
gdzie człony N1 i N2 odpowiadają mniejszym DFT. Algorytm ten jest realizowany rekurencyjnie, co pozwala na zmniejszenie czasu obliczeń do O(N log N), szczególnie w przypadku, gdy N jest liczbą wysoce złożoną. Z uwagi na jego znaczenie, różne warianty i style implementacji tego algorytmu są znane pod różnymi nazwami, jak opisano poniżej. Nazwa algorytmu pochodzi od J.W. Cooleya i Johna Tukeya.
Algorytm Cooleya-Tukeya dzieli DFT na mniejsze DFT, co umożliwia łączenie go z innymi algorytmami DFT, takimi jak algorytm Rädera lub Bluesteina, które mogą obsługiwać duże czynniki pierwsze.
Historia
Algorytm, w tym jego rekurencyjne podejście, został wynaleziony około 1805 roku przez Carl Friedrich Gaussa, który stosował go do interpolacji trajektorii planetoid Pallas i Juno, jednak jego prace nie były szeroko znane aż do publikacji pośmiertnej. Gauss nie analizował jednak asymptotycznego czasu obliczeń. Formy algorytmu były na nowo odkrywane kilkukrotnie w XIX i XX wieku. Popularność transformacji FFT wzrosła po publikacji artykułu przez Jamesa Cooleya i Johna Tukeya w 1965 roku, w którym przedstawili oni metodę na użycie algorytmu na komputerach.
Uważa się, że Tukey wpadł na ten pomysł podczas posiedzenia amerykańskiej prezydenckiej komisji doradczej, badającej metody wykrywania testów broni jądrowej w ZSRR. Richard Garwin z IBM dostrzegł potencjał tej metody i skontaktował Tukeya z Cooleyem, sugerując, że metoda ta będzie przydatna w analizie danych krystalograficznych 3D. Ich wspólny artykuł zdobył dużą popularność.
Mimo że Gauss opisał ten sam algorytm, jego realizacja miała miejsce dopiero kilka lat po publikacji Cooleya i Tukeya. Ich artykuł odnosił się jedynie do pracy I.J. Gooda, znanej jako „algorytm FFT czynników pierwszych” (PFA), która jednak okazała się zupełnie innym algorytmem.
Przypadek Radix-2 DIT
Radix-2 decymacja w dziedzinie czasu (DIT) FFT jest najprostsza i najczęściej stosowana wersja algorytmu Cooleya-Tukeya. Radix-2 DIT dzieli DFT o rozmiarze N na dwie przeplatające się DFT, każda o rozmiarze N/2 w każdym etapie rekurencyjnym. DFT jest definiowana wzorem:
Xk = ∑n=0N−1 xn e−(2πi/N)nk,
gdzie k jest liczbą całkowitą w zakresie od 0 do N−1.
Radix-2 DIT najpierw oblicza DFT dla danych wejściowych o indeksach parzystych x2m oraz dla indeksów nieparzystych x2m+1, a następnie łączy te dwa wyniki, aby uzyskać DFT całej sekwencji. Proces ten jest powtarzany rekurencyjnie, co redukuje czas do O(N log N).
Zakłada się, że N jest potęgą dwójki, co w praktyce jest często akceptowalne, ponieważ liczba punktów próbkowania N jest zazwyczaj ustalana przez aplikację.
Algorytm Radix-2 DIT dzieli DFT funkcji xn na dwie części: sumę dla indeksów parzystych oraz sumę dla indeksów nieparzystych:
Xk = ∑m=0N/2−1 x2m e−(2πi/N)(2m)k + ∑m=0N/2−1 x2m+1 e−(2πi/N)(2m+1)k.
Można uwzględnić wspólny czynnik e−(2πi/N)k z drugiej sumy. Wówczas obie sumy są DFT dla części o parzystych i nieparzystych indeksach funkcji xn.
Pseudokod
W pseudokodzie proces ten można zapisać:
X0,...,N −1 ← ditfft2 (x, N, s):
if N = 1 then
X0 ← x0
else
X0,...,N/2−1 ← ditfft2 (x, N/2, 2s)
XN/2,...,N −1 ← ditfft2 (x +s, N/2, 2s)
for k = 0 to N/2−1
t ← Xk
Xk ← t + exp(−2πi k/N) Xk + N/2
Xk +N/2 ← t − exp(−2π i k/N) Xk +N/2
endfor
endif
Algorytm ditfft2 oblicza X = DFT(x) przez radix-2 DIT FFT, gdzie N jest całkowitą potęgą dwójki.
Algorytmy zmiany kolejności danych
Wiele technik reorganizacji danych istnieje w różnych implementacjach algorytmu Cooleya-Tukeya. Szczególnie interesujący jest problem opracowania algorytmu w miejscu, który nadpisuje dane wejściowe swoimi danymi wyjściowymi przy minimalnym użyciu pamięci.
Najbardziej znana technika to jawne odwrócenie bitów, które jest permutacją, w której dane o indeksie n przenoszone są do indeksu o odwróconych cyfrach. W przypadku algorytmu radix-2 DIT, dane wyjściowe są nadpisywane w miejscu na danych wejściowych, co wymaga zamiany wartości wyjściowych.
Opracowane zostały również różne alternatywne metody implementacji dla algorytmu Cooleya-Tukeya, które nie wymagają oddzielnego odwracania bitów i/lub angażowania dodatkowych permutacji w pośrednich fazach.
Bibliografia
James W. Cooley, John W. Tukey. An algorithm for the machine calculation of complex Fourier series. „Math. Comput.”. 19, s. 297–301, 1965. DOI: 10.2307/2003354.
Linki zewnętrzne
Prosty, pedagogiczny algorytm radix-2 Cooley-Tukeya FFT w C++.
KISSFFT – prosta mixed-radix implementacja Cooleya-Tukeya w C (open source).