[Radix-4 Stockham FFT]
Do you know the Radix-4 Stockham Algorithm? Radix-4 Stockham Algorithm is faster than Radix-2 Stockham Algorithm. In this page, I show the program of Radix-4 Stockham FFT. Please refer to "Introduction to the Stockham FFT" for details of the Stockham algorithm.
Radix-4 Stockham Algorithm(DIF)
#include <complex> #include <cmath> typedef std::complex<double> complex_t; void fft0(int n, int s, bool eo, complex_t* x, complex_t* y) { static const complex_t j = complex_t(0, 1); const int n0 = 0; const int n1 = n/4; const int n2 = n/2; const int n3 = n1 + n2; const double theta0 = 2*M_PI/n; if (n == 1) { if (eo) for (int q = 0; q < s; q++) y[q] = x[q]; } else if (n == 2) { for (int q = 0; q < s; q++) { const complex_t a = x[q + 0]; const complex_t b = x[q + s]; y[q + 0] = a + b; y[q + s] = a - b; } fft0(1, 2*s, !eo, y, x); } else if (n > 2) { for (int p = 0; p < n1; p++) { const complex_t w1p = complex_t(cos(p*theta0), -sin(p*theta0)); const complex_t w2p = w1p*w1p; const complex_t w3p = w1p*w2p; for (int q = 0; q < s; q++) { const complex_t a = x[q + s*(p + n0)]; const complex_t b = x[q + s*(p + n1)]; const complex_t c = x[q + s*(p + n2)]; const complex_t d = x[q + s*(p + n3)]; const complex_t apc = a + c; const complex_t amc = a - c; const complex_t bpd = b + d; const complex_t jbmd = j*(b - d); y[q + s*(4*p + 0)] = apc + bpd; y[q + s*(4*p + 1)] = w1p*(amc - jbmd); y[q + s*(4*p + 2)] = w2p*(apc - bpd); y[q + s*(4*p + 3)] = w3p*(amc + jbmd); } } fft0(n/4, 4*s, !eo, y, x); } } void ifft0(int n, int s, bool eo, complex_t* x, complex_t* y) { static const complex_t j = complex_t(0, 1); const int n0 = 0; const int n1 = n/4; const int n2 = n/2; const int n3 = n1 + n2; const double theta0 = 2*M_PI/n; if (n == 1) { if (eo) for (int q = 0; q < s; q++) y[q] = x[q]; } else if (n == 2) { for (int q = 0; q < s; q++) { const complex_t a = x[q + 0]; const complex_t b = x[q + s]; y[q + 0] = a + b; y[q + s] = a - b; } ifft0(1, 2*s, !eo, y, x); } else if (n > 2) { for (int p = 0; p < n1; p++) { const complex_t w1p = complex_t(cos(p*theta0), sin(p*theta0)); const complex_t w2p = w1p*w1p; const complex_t w3p = w1p*w2p; for (int q = 0; q < s; q++) { const complex_t a = x[q + s*(p + n0)]; const complex_t b = x[q + s*(p + n1)]; const complex_t c = x[q + s*(p + n2)]; const complex_t d = x[q + s*(p + n3)]; const complex_t apc = a + c; const complex_t amc = a - c; const complex_t bpd = b + d; const complex_t jbmd = j*(b - d); y[q + s*(4*p + 0)] = apc + bpd; y[q + s*(4*p + 1)] = w1p*(amc + jbmd); y[q + s*(4*p + 2)] = w2p*(apc - bpd); y[q + s*(4*p + 3)] = w3p*(amc - jbmd); } } ifft0(n/4, 4*s, !eo, y, x); } } void fft(int n, complex_t* x) // Fourier transform // n : sequence length // x : input/output sequence { complex_t* y = new complex_t[n]; fft0(n, 1, 0, x, y); delete[] y; for (int k = 0; k < n; k++) x[k] /= n; } void ifft(int n, complex_t* x) // Inverse Fourier transform // n : sequence length // x : input/output sequence { complex_t* y = new complex_t[n]; ifft0(n, 1, 0, x, y); delete[] y; }