143 | class FFT
144 | {
145 | enum { N = 1< recursion;
147 |
148 | // reverse-binary reindexing
149 | void scramble(T* data) {
150 | int j=1;
151 | for (int i=1; i<2*N; i+=2) {
152 | if (j>i) {
153 | swap(data[j-1], data[i-1]);
154 | swap(data[j], data[i]);
155 | }
156 | int m = N;
157 | while (m>=2 && j>m) {
158 | j -= m;
159 | m >>= 1;
160 | }
161 | j += m;
162 | }
163 | }
164 |
165 | void rescale(T* data)
166 | {
167 | /* scale all results by 1/n */
168 | T scale = static_cast(1)/N;
169 | for (unsigned i=0; i<2*N; i++) {
170 | data[i] *= scale;
171 | }
172 | }
173 |
174 | public:
175 | /*!\brief Replaces data[1..2*N] by its discrete Fourier transform */
176 | void fft(T* data) {
177 | scramble(data);
178 | recursion.apply(data,1);
179 | }
180 |
181 | /*!\brief Replaces data[1..2*N] by its inverse discrete Fourier transform */
182 | void ifft(T* data) {
183 | scramble(data);
184 | recursion.apply(data,-1);
185 | rescale(data);
186 | }
187 | };
188 |
189 | #endif /* _fft_h_ */
190 |
--------------------------------------------------------------------------------
/fft_tb.cpp:
--------------------------------------------------------------------------------
1 | /* Test code for the FFT
2 | * Author: Tim Molteno, tim@physics.otago.ac.nz
3 | *
4 | * Copyright Tim Molteno, 2008-2015.
5 | * Licensed under the GPL v3.
6 | *
7 | * Perform 1000 FFT followed by Inverse FFT.
8 | * Print out the calculated number of Megaflops from the formula
9 | * Mflops = 5 N log2(N) / t (us)
10 | *
11 | * gcc -O2 -ftree-vectorize fft_noeigen.cpp -lstdc++
12 | * Real FFT: MFLOPS(N=16384)=1638.4
13 | *
14 | * Real FFT: MFLOPS(N=16384)=1650.19 --march=native --mtune=native
15 | */
16 | #include "fft_real.h"
17 | #include
18 | #include
19 | using namespace std;
20 |
21 | #define LOG_LENGTH 14
22 | #define N (1<
31 | #include
32 | double secnds(void) {
33 | struct tms buffer;
34 |
35 | times(&buffer);
36 | return 1000.0 * ( (double)(buffer.tms_utime + buffer.tms_stime) ) /
37 | ( (double) sysconf(_SC_CLK_TCK) );
38 | }
39 |
40 | typedef double fft_real;
41 |
42 | int main()
43 | {
44 | FFT gfft;
45 |
46 | unsigned long n = 1< gfft;
51 |
52 | fft_real* data = new fft_real [2*N];
53 | for (unsigned i=0; i
12 | using namespace std;
13 |
14 | #define LOG_LENGTH 13
15 | #define N (1< fft_complex;
18 |
19 | #include
20 |
21 | int main()
22 | {
23 | CFFT cfft;
24 | Matrix, N, 1> cdata;
25 | cdata.setRandom();
26 |
27 | std::cout << "Perform 1000 FFT and INVERSE FFT " << endl;
28 | std::cout << "FFT Length= " << N << endl;
29 |
30 | for (int i=0;i<1000;i++) {
31 | cfft.fft(cdata);
32 | cfft.ifft(cdata);
33 | }
34 | return 0;
35 | }
36 |
--------------------------------------------------------------------------------