OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
TestFFT.cpp
Go to the documentation of this file.
1
46#include <gtest/gtest.h>
47#include <cmath>
48#include <complex>
49#include <vector>
50#include "Utilities/GSLFFT.h"
51
52class FFTTest : public ::testing::Test {
53protected:
54 void SetUp() override {
55 // Test setup
56 }
57};
58
59TEST_F(FFTTest, ComplexFFT_Identity) {
60 // Test FFT of a constant signal
61 std::vector<std::complex<double>> data(8, std::complex<double>(1.0, 0.0));
62
63 // Create a copy for FFT
64 std::vector<std::complex<double>> fft_data = data;
65
66 // Perform FFT (using the internal fft function)
67 // Note: This tests the internal implementation
68 // For GSL-compatible interface, we'd use gsl_fft_complex_forward
69
70 // Simple test: constant signal should have DC component only
71 // (This is a simplified test - actual FFT would require the internal function)
72 EXPECT_EQ(data.size(), 8);
73}
74
75TEST_F(FFTTest, RealFFT_Transform) {
76 // Test real FFT transform
77 const size_t n = 8;
78 std::vector<double> data(n);
79
80 // Create a simple signal: [1, 0, 0, 0, 0, 0, 0, 0]
81 data[0] = 1.0;
82 for (size_t i = 1; i < n; ++i) {
83 data[i] = 0.0;
84 }
85
88
89 gsl_fft_real_transform(data.data(), 1, n, wavetable, workspace);
90
91 // DC component should be 1.0
92 EXPECT_NEAR(data[0], 1.0, 1e-10);
93
96}
97
98TEST_F(FFTTest, ComplexFFT_Forward) {
99 const size_t n = 4;
100 std::vector<double> data(2 * n); // Complex data: [real0, imag0, real1, imag1, ...]
101
102 // Set data to [1+0i, 0+0i, 0+0i, 0+0i]
103 data[0] = 1.0; // real[0]
104 data[1] = 0.0; // imag[0]
105 for (size_t i = 1; i < n; ++i) {
106 data[2 * i] = 0.0;
107 data[2 * i + 1] = 0.0;
108 }
109
112
113 gsl_fft_complex_forward(data.data(), 1, n, wavetable, workspace);
114
115 // All components should be 1.0 (DC signal transforms to all ones)
116 for (size_t i = 0; i < n; ++i) {
117 EXPECT_NEAR(data[2 * i], 1.0, 1e-10);
118 EXPECT_NEAR(data[2 * i + 1], 0.0, 1e-10);
119 }
120
123}
124
125TEST_F(FFTTest, ComplexFFT_Inverse) {
126 const size_t n = 4;
127 std::vector<double> data(2 * n);
128
129 // Set all components to 1.0 (constant in frequency domain)
130 for (size_t i = 0; i < n; ++i) {
131 data[2 * i] = 1.0;
132 data[2 * i + 1] = 0.0;
133 }
134
137
138 gsl_fft_complex_inverse(data.data(), 1, n, wavetable, workspace);
139
140 // Should recover impulse at n=0
141 EXPECT_NEAR(data[0], static_cast<double>(n), 1e-10);
142 EXPECT_NEAR(data[1], 0.0, 1e-10);
143
146}
147
148TEST_F(FFTTest, FFT_InverseRoundTrip) {
149 const size_t n = 8;
150 std::vector<double> original(2 * n);
151 std::vector<double> transformed(2 * n);
152
153 // Create original signal
154 for (size_t i = 0; i < n; ++i) {
155 original[2 * i] = static_cast<double>(i);
156 original[2 * i + 1] = 0.0;
157 }
158
159 transformed = original;
160
163
164 // Forward transform
165 gsl_fft_complex_forward(transformed.data(), 1, n, wavetable, workspace);
166
167 // Inverse transform
168 gsl_fft_complex_inverse(transformed.data(), 1, n, wavetable, workspace);
169
170 // Should recover original (within scaling)
171 for (size_t i = 0; i < n; ++i) {
172 EXPECT_NEAR(transformed[2 * i], original[2 * i] * static_cast<double>(n), 1e-6);
173 EXPECT_NEAR(transformed[2 * i + 1], 0.0, 1e-6);
174 }
175
178}
179
180TEST_F(FFTTest, Radix2Forward) {
181 const size_t n = 4; // Must be power of 2
182 std::vector<double> data(2 * n);
183
184 // Set to impulse
185 data[0] = 1.0;
186 data[1] = 0.0;
187 for (size_t i = 1; i < n; ++i) {
188 data[2 * i] = 0.0;
189 data[2 * i + 1] = 0.0;
190 }
191
192 gsl_fft_complex_radix2_forward(data.data(), 1, n);
193
194 // All components should be 1.0
195 for (size_t i = 0; i < n; ++i) {
196 EXPECT_NEAR(data[2 * i], 1.0, 1e-10);
197 EXPECT_NEAR(data[2 * i + 1], 0.0, 1e-10);
198 }
199}
200
201TEST_F(FFTTest, Radix2Inverse) {
202 const size_t n = 4;
203 std::vector<double> data(2 * n);
204
205 // Set all to 1.0
206 for (size_t i = 0; i < n; ++i) {
207 data[2 * i] = 1.0;
208 data[2 * i + 1] = 0.0;
209 }
210
211 gsl_fft_complex_radix2_inverse(data.data(), 1, n);
212
213 // Should get impulse at n=0
214 EXPECT_NEAR(data[0], static_cast<double>(n), 1e-10);
215 EXPECT_NEAR(data[1], 0.0, 1e-10);
216}
void gsl_fft_complex_wavetable_free(gsl_fft_complex_wavetable *w)
Free a complex FFT wavetable.
Definition GSLFFT.h:346
gsl_fft_complex_workspace * gsl_fft_complex_workspace_alloc(size_t n)
Allocate a complex FFT workspace of size .
Definition GSLFFT.h:292
void gsl_fft_real_wavetable_free(gsl_fft_real_wavetable *w)
Free a real FFT wavetable.
Definition GSLFFT.h:159
gsl_fft_real_workspace * gsl_fft_real_workspace_alloc(size_t n)
Allocate a real FFT workspace of size .
Definition GSLFFT.h:138
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 ).
Definition GSLFFT.h:327
void gsl_fft_complex_forward(double *data, size_t stride, size_t n, gsl_fft_complex_wavetable *, gsl_fft_complex_workspace *)
Forward complex FFT.
Definition GSLFFT.h:306
void gsl_fft_complex_workspace_free(gsl_fft_complex_workspace *w)
Free a complex FFT workspace.
Definition GSLFFT.h:350
void gsl_fft_real_workspace_free(gsl_fft_real_workspace *w)
Free a real FFT workspace.
Definition GSLFFT.h:163
void gsl_fft_complex_radix2_inverse(double *data, size_t stride, size_t n)
Radix-2 inverse complex FFT (GSL scaling, allocates temporaries).
Definition GSLFFT.h:368
gsl_fft_complex_wavetable * gsl_fft_complex_wavetable_alloc(size_t n)
Allocate a complex FFT wavetable of size .
Definition GSLFFT.h:283
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.
Definition GSLFFT.h:151
gsl_fft_real_wavetable * gsl_fft_real_wavetable_alloc(size_t n)
Allocate a real FFT wavetable of size .
Definition GSLFFT.h:129
void gsl_fft_complex_radix2_forward(double *data, size_t stride, size_t n)
Radix-2 forward complex FFT (allocates temporary wavetable/workspace).
Definition GSLFFT.h:356
Complex FFT types.
Definition GSLFFT.h:269
Workspace for complex FFT routines.
Definition GSLFFT.h:275
GSL-compatible interface for FFT routines.
Definition GSLFFT.h:115
Workspace for real FFT routines.
Definition GSLFFT.h:121
TEST_F(FFTTest, ComplexFFT_Identity)
Definition TestFFT.cpp:59
void SetUp() override
Definition TestFFT.cpp:54