18#ifndef OPAL_GSL_FFT_HH
19#define OPAL_GSL_FFT_HH
31 void fft(std::vector<std::complex<double>>& x) {
36 std::vector<std::complex<double>> even(n / 2);
37 std::vector<std::complex<double>> odd(n / 2);
38 for (
size_t i = 0; i < n / 2; ++i) {
40 odd[i] = x[2 * i + 1];
48 for (
size_t i = 0; i < n / 2; ++i) {
49 std::complex<double> t = std::polar(1.0, -2.0 * M_PI * i / n) * odd[i];
51 x[i + n / 2] = even[i] - t;
56 void ifft(std::vector<std::complex<double>>& x) {
70 val = std::conj(val) /
static_cast<double>(n);
89 std::vector<std::complex<double>> complex_data(n);
90 for (
size_t i = 0; i < n; ++i) {
91 complex_data[i] = std::complex<double>(data[i * stride], 0.0);
99 data[0] = complex_data[0].real();
102 for (
size_t i = 1; i < half; ++i) {
103 data[2 * i - 1] = complex_data[i].real();
104 data[2 * i] = complex_data[i].imag();
107 data[n - 1] = complex_data[half].real();
208 std::vector<std::complex<double>> complex_data(n);
209 complex_data[0] = std::complex<double>(data[0], 0.0);
212 for (
size_t i = 1; i < half; ++i) {
213 complex_data[i] = std::complex<double>(data[2 * i - 1], data[2 * i]);
214 complex_data[n - i] = std::conj(complex_data[i]);
217 complex_data[half] = std::complex<double>(data[n - 1], 0.0);
223 double scale =
static_cast<double>(n);
226 for (
size_t i = 0; i < n; ++i) {
227 data[i * stride] = complex_data[i].real() * scale;
277 std::vector<std::complex<double>>
work;
309 std::vector<std::complex<double>> complex_data(n);
310 for (
size_t i = 0; i < n; ++i) {
311 complex_data[i] = std::complex<double>(data[2 * i * stride], data[(2 * i + 1) * stride]);
314 for (
size_t i = 0; i < n; ++i) {
315 data[2 * i * stride] = complex_data[i].real();
316 data[(2 * i + 1) * stride] = complex_data[i].imag();
330 std::vector<std::complex<double>> complex_data(n);
331 for (
size_t i = 0; i < n; ++i) {
332 complex_data[i] = std::complex<double>(data[2 * i * stride], data[(2 * i + 1) * stride]);
337 double scale =
static_cast<double>(n);
338 for (
size_t i = 0; i < n; ++i) {
339 data[2 * i * stride] = complex_data[i].real() * scale;
340 data[(2 * i + 1) * stride] = complex_data[i].imag() * scale;
std::vector< double > work
std::vector< std::complex< double > > work
void gsl_fft_complex_wavetable_free(gsl_fft_complex_wavetable *w)
Free a complex FFT wavetable.
gsl_fft_halfcomplex_wavetable * gsl_fft_halfcomplex_wavetable_alloc(size_t n)
Allocate a halfcomplex FFT wavetable of size .
gsl_fft_complex_workspace * gsl_fft_complex_workspace_alloc(size_t n)
Allocate a complex FFT workspace of size .
void gsl_fft_halfcomplex_transform(double *data, size_t stride, size_t n, gsl_fft_halfcomplex_wavetable *, gsl_fft_halfcomplex_workspace *)
Inverse transform from halfcomplex packed data.
void gsl_fft_real_wavetable_free(gsl_fft_real_wavetable *w)
Free a real FFT wavetable.
std::vector< double > work
gsl_fft_real_workspace * gsl_fft_real_workspace_alloc(size_t n)
Allocate a real FFT workspace of size .
gsl_fft_halfcomplex_workspace * gsl_fft_halfcomplex_workspace_alloc(size_t n)
Allocate a halfcomplex FFT workspace of size .
void gsl_fft_halfcomplex_inverse(double *data, size_t stride, size_t n, gsl_fft_halfcomplex_wavetable *wavetable, gsl_fft_halfcomplex_workspace *workspace)
Alias for halfcomplex inverse transform.
void gsl_fft_complex_inverse(double *data, size_t stride, size_t n, gsl_fft_complex_wavetable *, gsl_fft_complex_workspace *)
Inverse complex FFT (GSL scaling: multiplies by ).
void gsl_fft_complex_forward(double *data, size_t stride, size_t n, gsl_fft_complex_wavetable *, gsl_fft_complex_workspace *)
Forward complex FFT.
void gsl_fft_complex_workspace_free(gsl_fft_complex_workspace *w)
Free a complex FFT workspace.
void gsl_fft_real_workspace_free(gsl_fft_real_workspace *w)
Free a real FFT workspace.
void gsl_fft_complex_radix2_inverse(double *data, size_t stride, size_t n)
Radix-2 inverse complex FFT (GSL scaling, allocates temporaries).
void gsl_fft_halfcomplex_workspace_free(gsl_fft_halfcomplex_workspace *w)
Free a halfcomplex FFT workspace.
gsl_fft_complex_wavetable * gsl_fft_complex_wavetable_alloc(size_t n)
Allocate a complex FFT wavetable of size .
void gsl_fft_real_transform(double *data, size_t stride, size_t n, gsl_fft_real_wavetable *, gsl_fft_real_workspace *)
Forward real FFT with GSL-compatible packed output.
gsl_fft_real_wavetable * gsl_fft_real_wavetable_alloc(size_t n)
Allocate a real FFT wavetable of size .
void gsl_fft_halfcomplex_wavetable_free(gsl_fft_halfcomplex_wavetable *w)
Free a halfcomplex FFT wavetable.
void gsl_fft_complex_radix2_forward(double *data, size_t stride, size_t n)
Radix-2 forward complex FFT (allocates temporary wavetable/workspace).
Workspace for complex FFT routines.
Halfcomplex FFT types for inverse transforms.
Workspace for halfcomplex FFT routines.
GSL-compatible interface for FFT routines.
Workspace for real FFT routines.
Simple FFT implementation using Cooley-Tukey algorithm.
void fft_real_transform(double *data, size_t stride, size_t n)
Forward FFT for real data (packed output).