• Nie Znaleziono Wyników

2Instrukcje,wskazówki,podpowiedzi 1Cel Algorytmy2Laboratorium:szybkatransformacjaFouriera(FFT)

N/A
N/A
Protected

Academic year: 2021

Share "2Instrukcje,wskazówki,podpowiedzi 1Cel Algorytmy2Laboratorium:szybkatransformacjaFouriera(FFT)"

Copied!
4
0
0

Pełen tekst

(1)

Algorytmy 2

Laboratorium: szybka transformacja Fouriera (FFT)

Przemysław Klęsk 21 stycznia 2021

1 Cel

Transformacja (przekształcenie) Fouriera odgrywa ważną rolę w informatyce. Praktyczne zastosowania tej transformacji obejmują m.in.: przetwarzanie sygnałów i obrazów, analizę widma, filtrowanie, aprok- symację, kompresję danych audio–wideo, szybkie mnożenie dużych liczb całkowitych.

Przedmiotem zadania jest dyskretna transformacja Fouriera (DFT, ang. Discrete Fourier Transform) obliczana na dwa sposoby: sposobem bezpośrednim (według definicji) oraz sposobem szybkim (FFT, ang. Fast Fourier Transform). Zasadniczym celem zadania jest wykonanie implementacji FFT według klasycznego algorytmu Cooleya–Tukeya opartego na podejściu „dziel i zwyciężaj”, w którym liczba próbek sygnału (N ) jest pewną potęgą dwójki (radix-2 FFT). Algorytm ten składa wynikową transformatę na podstawie dwóch transformat FFT wykonanych osobno dla parzystych i nieparzystych próbek sygnału (lub funkcji). Takie podejście prowadzi do złożoności obliczeniowej Θ(N log N ), podczas gdy obliczenia realizowane według definicji mają złożoność Θ(N2).

Dla przypomnienia: jeżeli f0, f1, . . . , fN −1 oznacza zestaw próbek pewnego sygnału (lub funkcji), to zgodnie z definicją — transformatą, czyli wynikiem dyskretnej transformacji Fouriera, jest zestaw N współczynników zespolonych określonych wzorem

ck =

N −1X

n=0

fne−2πikn/N, k = 0, 1, . . . , N − 1, (1)

gdzie i oznacza jednostkę urojoną (i2= −1).

2 Instrukcje, wskazówki, podpowiedzi

1. W realizowanym programie należy wykorzystać typ reprezentujący liczby zespolone, w którym

części rzeczywista i urojona są liczbami zmiennoprzecinkowymi w precyzji 64-bitowej — std::complex<double>.

W tym celu należy wykonać dołączenie: #include <complex>. Liczby zespolone można wówczas powoływać do życia na kilka sposobów, na przykład:

1

(2)

std::complex<double> z1 = 2.0 + 3.0i;

std::complex<double> z2(2.0, 3.0);

2. Niektóre przydatne funkcje związane z liczbami zespolonymi to: real(...) (oddaje część rzeczy- wistą z liczby zespolonej), imag(...) (część urojona), abs(...) (moduł), conj(...) (sprzężenie zespolone), exp(...) (eksponenta zespolona).

3. Przydatne może być także umieszczenie w nagłówku programu linii:

#define USE MATH DEFINES

#include "math.h"

w celu dołączenia biblioteki matematycznej oraz stałych, m.in. M PI reprezentującej pewne przybli- żenie liczby π.

4. Drugą ewentualnością jest samodzielne zdefiniowanie w programie stałych dla π oraz i (zamiast używania literału i), np. w taki sposób:

const double pi = std::acos(-1);

const std::complex<double> i(0, 1);

5. Należy dostarczyć implementacje dwóch funkcji DFT i FFT wyznaczających transformatę Fouriera odpowiednio wg definicji i w sposób szybki (argumenty: tablica liczb fn, jej rozmiar N ; wynik:

tablica współczynników zespolonych ck; gdzie k, n = 0, 1, . . . , N − 1).

6. Uwaga Realizacja funkcji FFT nie odbywa się w miejscu. W związku z tym należy w ramach rekurencji zadbać o odpowiednie powoływanie i uwalnianie pamięci, zarówno dla wydzielanych próbek parzystych / nieparzystych, jak i dla chwilowych rezultatów cząstkowych. Nie wolno dopuścić do wycieków pamięci.

7. Poprawność odpowiedzi zwracanych przez przygotowane funkcje (DFT i FFT) należy sprawdzić z istniejącymi gotowymi funkcjami w dowolnej bibliotece numerycznej (np. MATLAB lub numpy języka Python).

8. Nie jest wymagane przygotowanie implementacji transformacji odwrotnej (IDFT).

9. W celu weryfikacji zgodności współczynników zespolonych zwracanych przez DFT i FFT należy przygotować funkcję obliczającą błąd pomiędzy tymi wynikami (średni moduł różnic). Np. niech c oraz c oznaczają wyniki zwracane odpowiednio przez DFT i FFT, wówczas błąd powinien być obliczony jako: 1/NPN −1

k=0 |ck− ck|, gdzie | · | oznacza moduł z liczby zespolonej.

10. W końcowym programie należy przewidzieć możliwość wypisania na ekran otrzymanych współczyn- ników (np. z pomocą przełącznika typu bool).

3 Zawartość funkcji main()

Główny eksperyment zawarty w funkcji main() ma polegać na wielokrotnym wykonywaniu przygotowa- nych funkcji DFT i FFT dla coraz większych rozmiarów tablicy wejściowej z próbkami sygnału (kolejne

2

(3)

rzędy wielkości o podstawie 2, od 21aż do 213), wraz z raportowaniem pomiarów czasowych. Dostarczone próbki mogą pochodzić z dowolnej wybranej funkcji, np. liniowej fn = n/N lub funkcji kwadratowej fn = (n/N )2, n = 0, 1, . . . N − 1 (lub jeszcze innej).

Poniższy listing pokazuje schemat eksperymentu (proszę traktować go jako poglądowy przykład):

int main () {

const int M A X _ O R D E R = 13; // m a k s y m a l n y rzad w i e l k o s c i d a n y c h ( w r a m a c h bazy 2)

const bool P R I N T _ C O E F S = false ; // p r z e l a c z n i k do e w e n t u a l n e g o w y p i s u na e k r a n r e z u l t a t o w DFT , FFT

for ( int o = 1; o <= M A X _ O R D E R ; o ++) {

const int N = 1 << o ; // r o z m i a r p r o b l e m u ( p o t e g a d w o j k i - p r z e s u n i e c i e b i t o w e w lewo ) p r i n t f (”N:%i \n”, N ) ;

d o u b l e * f = new d o u b l e [ N ] ; for ( int n = 0; n < N ; n ++)

f [ n ] = n / ( d o u b l e ) N ; // p r z y k l a d o w e dane ( tu a k u r a t: p r o b k i f u n k c j i l i n i o w e j )

c l o c k _ t t1 = clock () ;

complex < double >* cDFT = dft (f , N ) ; c l o c k _ t t2 = clock () ;

d o u b l e d f t _ t i m e = ( t2 - t1 ) / ( d o u b l e ) C L O C K S _ P E R _ S E C * 1 0 0 0 . 0 ; p r i n t f (”DFT time [ms] : %f \n”, d f t _ t i m e ) ;

t1 = clock () ;

complex < double >* cFFT = fft (f , N ) ; t2 = clock () ;

d o u b l e f f t _ t i m e = ( t2 - t1 ) / ( d o u b l e ) C L O C K S _ P E R _ S E C * 1 0 0 0 . 0 ; p r i n t f (”FFT time [ms] : %f \n”, f f t _ t i m e ) ;

p r i n t f (”mean e r r o r:%f \n”, err ( cDFT , cFFT , N ) ) ;

if ( P R I N T _ C O E F S )

for ( int k = 0; k < N ; k ++)

... // w y p i s na e k r a n w s p o l c z y n n i k o w obu t r a n s f o r m a t ( c z e s c i r z e c z y w i s t e i u r o j o n e ) p r i n t f (”−−−−−\n”, N ) ;

d e l e t e [ ] f ; d e l e t e [ ] cDFT ; d e l e t e [ ] cFFT ; }

r e t u r n 0;

}

4 Sprawdzenie antyplagiatowe — przygotowanie wiadomości e-mail do wysłania

1. Kod źródłowy programu po sprawdzeniu przez prowadzącego zajęcia laboratoryjne musi zostać przesłany na adres algo2@zut.edu.pl.

2. Plik z kodem źródłowym musi mieć nazwę wg schematu: nr albumu.algo2.nr lab.main.c (plik

3

(4)

może mieć rozszerzenie .c lub .cpp). Przykład: 123456.algo2.lab06.main.c (szóste zadanie laboratoryjne studenta o numerze albumu 123456). Jeżeli kod źródłowy programu składa się z wielu plików, to należy stworzyć jeden plik, umieszczając w nim kody wszystkich plików składowych.

3. Plik musi zostać wysłany z poczty ZUT (zut.edu.pl).

4. Temat maila musi mieć postać: ALGO2 IS1 XXXY LAB06, gdzie XXXY to numer grupy (np. ALGO2 IS1 210C LAB06).

5. W pierwszych trzech liniach pliku z kodem źródłowym w komentarzach muszą znaleźć się:

- informacja identyczna z zamieszczoną w temacie maila (linia 1), - imię i nazwisko autora (linia 2),

- adres e-mail (linia 3).

6. Mail nie może zawierać żadnej treści (tylko załącznik).

7. W razie wykrycia plagiatu, wszytkie uwikłane osoby otrzymają za dane zadanie ocenę 0 punktów (co jest gorsze niż ocena 2 w skali {2, 3, 3.5, 4, 4.5, 5}).

4

Cytaty

Powiązane dokumenty

Widzimy że rezultat transformaty Fouriera (zwyczajowo sygnał w dziedzinie częstotliwości zapisujemy dużymi literami, w dziedzinie czasu małymi) jest liczbą zespoloną (dla

Jeśli funkcja f(x) jest rzeczywista wówczas „zwykły” szereg Fouriera jest częścią rzeczywistą zespolonego szeregu Fouriera:.. Dla

1) Algorytm Winograda/Radera – DFT jest sformułowane w postaci cyklicznego splotu. W każdym kroku DFT jest wyrażana jako suma DFT dla N/2 oraz dwóch DFT dla N/4. Jest to

The parameters of the contact force model used in discrete element simulations of pattern transformation (cf. Chapter 5 ) and dispersion relation calculations (cf. Chapter 6 ) of

a) transformata splotu

Dyskretna transformata Fouriera. zadania

Dyskretna transformata Fouriera. zadania

[r]