3 * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or (at
8 * your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "bitreverse.h"
24 void FUNCTION(test_complex,func) (size_t stride, size_t n);
25 int FUNCTION(test,offset) (const BASE data[], size_t stride,
26 size_t n, size_t offset);
27 void FUNCTION(test_complex,bitreverse_order) (size_t stride, size_t n) ;
28 void FUNCTION(test_complex,radix2) (size_t stride, size_t n);
30 int FUNCTION(test,offset) (const BASE data[], size_t stride,
31 size_t n, size_t offset)
36 for (i = 0; i < n; i++)
40 for (j = 1; j < stride; j++)
42 status |= data[k] != k + offset ;
44 status |= data[k] != k + offset ;
52 void FUNCTION(test_complex,func) (size_t stride, size_t n)
57 TYPE(gsl_fft_complex_wavetable) * cw ;
58 TYPE(gsl_fft_complex_workspace) * cwork ;
60 BASE * complex_data = (BASE *) malloc (2 * n * stride * sizeof (BASE));
61 BASE * complex_tmp = (BASE *) malloc (2 * n * stride * sizeof (BASE));
62 BASE * fft_complex_data = (BASE *) malloc (2 * n * stride * sizeof (BASE));
63 BASE * fft_complex_tmp = (BASE *) malloc (2 * n * stride * sizeof (BASE));
65 for (i = 0 ; i < 2 * n * stride ; i++)
67 complex_data[i] = (BASE)i ;
68 complex_tmp[i] = (BASE)(i + 1000.0) ;
69 fft_complex_data[i] = (BASE)(i + 2000.0) ;
70 fft_complex_tmp[i] = (BASE)(i + 3000.0) ;
73 gsl_set_error_handler (NULL); /* abort on any errors */
78 cw = FUNCTION(gsl_fft_complex_wavetable,alloc) (n);
79 gsl_test (cw == 0, NAME(gsl_fft_complex_wavetable)
80 "_alloc, n = %d, stride = %d", n, stride);
84 cwork = FUNCTION(gsl_fft_complex_workspace,alloc) (n);
85 gsl_test (cwork == 0, NAME(gsl_fft_complex_workspace)
90 /* Test mixed radix fft with noise */
93 FUNCTION(fft_signal,complex_noise) (n, stride, complex_data, fft_complex_data);
94 for (i = 0 ; i < n ; i++)
96 REAL(complex_tmp,stride,i) = REAL(complex_data,stride,i) ;
97 IMAG(complex_tmp,stride,i) = IMAG(complex_data,stride,i) ;
100 FUNCTION(gsl_fft_complex,forward) (complex_data, stride, n, cw, cwork);
102 for (i = 0 ; i < n ; i++)
104 REAL(fft_complex_tmp,stride,i) = REAL(complex_data,stride,i) ;
105 IMAG(fft_complex_tmp,stride,i) = IMAG(complex_data,stride,i) ;
108 status = FUNCTION(compare_complex,results) ("dft", fft_complex_data,
109 "fft of noise", complex_data,
111 gsl_test (status, NAME(gsl_fft_complex)
112 "_forward with signal_noise, n = %d, stride = %d", n, stride);
116 status = FUNCTION(test, offset) (complex_data, stride, n, 0) ;
118 gsl_test (status, NAME(gsl_fft_complex)
119 "_forward avoids unstrided data, n = %d, stride = %d",
124 /* Test the inverse fft */
127 status = FUNCTION(gsl_fft_complex,inverse) (complex_data, stride, n, cw, cwork);
128 status = FUNCTION(compare_complex,results) ("orig", complex_tmp,
129 "fft inverse", complex_data,
131 gsl_test (status, NAME(gsl_fft_complex)
132 "_inverse with signal_noise, n = %d, stride = %d", n, stride);
136 status = FUNCTION(test, offset) (complex_data, stride, n, 0) ;
138 gsl_test (status, NAME(gsl_fft_complex)
139 "_inverse other data untouched, n = %d, stride = %d",
145 /* Test the backward fft */
148 status = FUNCTION(gsl_fft_complex,backward) (fft_complex_tmp, stride, n, cw, cwork);
150 for (i = 0; i < n; i++)
152 REAL(complex_tmp,stride,i) *= n;
153 IMAG(complex_tmp,stride,i) *= n;
155 status = FUNCTION(compare_complex,results) ("orig",
161 gsl_test (status, NAME(gsl_fft_complex)
162 "_backward with signal_noise, n = %d, stride = %d", n, stride);
166 status = FUNCTION(test, offset) (fft_complex_tmp, stride, n, 3000) ;
168 gsl_test (status, NAME(gsl_fft_complex)
169 "_backward avoids unstrided data, n = %d, stride = %d",
175 /* Test a pulse signal */
178 FUNCTION(fft_signal,complex_pulse) (1, n, stride, 1.0, 0.0, complex_data,
180 FUNCTION(gsl_fft_complex,forward) (complex_data, stride, n, cw, cwork);
181 status = FUNCTION(compare_complex,results) ("analytic", fft_complex_data,
182 "fft of pulse", complex_data,
184 gsl_test (status, NAME(gsl_fft_complex)
185 "_forward with signal_pulse, n = %d, stride = %d", n, stride);
190 /* Test a constant signal */
193 FUNCTION(fft_signal,complex_constant) (n, stride, 1.0, 0.0, complex_data,
195 FUNCTION(gsl_fft_complex,forward) (complex_data, stride, n, cw, cwork);
196 status = FUNCTION(compare_complex,results) ("analytic", fft_complex_data,
200 gsl_test (status, NAME(gsl_fft_complex)
201 "_forward with signal_constant, n = %d, stride = %d", n, stride);
204 /* Test an exponential (cos/sin) signal */
208 for (i = 0; i < n; i++)
210 FUNCTION(fft_signal,complex_exp) ((int)i, n, stride, 1.0, 0.0, complex_data,
212 FUNCTION(gsl_fft_complex,forward) (complex_data, stride, n, cw, cwork);
213 status |= FUNCTION(compare_complex,results) ("analytic",
219 gsl_test (status, NAME(gsl_fft_complex)
220 "_forward with signal_exp, n = %d, stride = %d", n, stride);
223 FUNCTION(gsl_fft_complex_wavetable,free) (cw);
224 FUNCTION(gsl_fft_complex_workspace,free) (cwork);
228 free (fft_complex_data);
229 free (fft_complex_tmp);
234 FUNCTION(test_complex,bitreverse_order) (size_t stride, size_t n)
239 BASE * tmp = (BASE *) malloc (2 * n * stride * sizeof (BASE));
240 BASE * data = (BASE *) malloc (2 * n * stride * sizeof (BASE));
241 BASE * reversed_data = (BASE *) malloc (2 * n * stride * sizeof (BASE));
243 for (i = 0; i < 2 * stride * n; i++)
248 memcpy (tmp, data, 2 * n * stride * sizeof(BASE)) ;
250 logn = 0 ; while (n > (1U<<logn)) {logn++ ; } ;
252 /* do a naive bit reversal as a baseline for testing the other routines */
254 for (i = 0; i < n; i++)
260 for (bit = 0; bit < logn; bit++)
262 j <<= 1; /* reverse shift i into j */
267 reversed_data[2*j*stride] = data[2*i*stride] ;
268 reversed_data[2*j*stride+1] = data[2*i*stride+1] ;
271 FUNCTION(fft_complex,bitreverse_order) (data, stride, n, logn);
273 status = FUNCTION(compare_complex,results) ("naive bit reverse",
275 "fft_complex_bitreverse_order",
279 gsl_test (status, "fft_complex_bitreverse_order, n = %d", n);
281 free (reversed_data) ;
286 void FUNCTION(test_complex,radix2) (size_t stride, size_t n)
291 BASE * complex_data = (BASE *) malloc (2 * n * stride * sizeof (BASE));
292 BASE * complex_tmp = (BASE *) malloc (2 * n * stride * sizeof (BASE));
293 BASE * fft_complex_data = (BASE *) malloc (2 * n * stride * sizeof (BASE));
294 BASE * fft_complex_tmp = (BASE *) malloc (2 * n * stride * sizeof (BASE));
296 for (i = 0 ; i < 2 * n * stride ; i++)
298 complex_data[i] = (BASE)i ;
299 complex_tmp[i] = (BASE)(i + 1000.0) ;
300 fft_complex_data[i] = (BASE)(i + 2000.0) ;
301 fft_complex_tmp[i] = (BASE)(i + 3000.0) ;
304 gsl_set_error_handler (NULL); /* abort on any errors */
306 /* Test radix-2 fft with noise */
309 FUNCTION(fft_signal,complex_noise) (n, stride, complex_data,
311 for (i = 0 ; i < n ; i++)
313 REAL(complex_tmp,stride,i) = REAL(complex_data,stride,i) ;
314 IMAG(complex_tmp,stride,i) = IMAG(complex_data,stride,i) ;
317 FUNCTION(gsl_fft_complex,radix2_forward) (complex_data, stride, n);
319 for (i = 0 ; i < n ; i++)
321 REAL(fft_complex_tmp,stride,i) = REAL(complex_data,stride,i) ;
322 IMAG(fft_complex_tmp,stride,i) = IMAG(complex_data,stride,i) ;
325 status = FUNCTION(compare_complex,results) ("dft", fft_complex_data,
326 "fft of noise", complex_data,
328 gsl_test (status, NAME(gsl_fft_complex)
329 "_radix2_forward with signal_noise, n = %d, stride = %d",
334 status = FUNCTION(test, offset) (complex_data, stride, n, 0) ;
336 gsl_test (status, NAME(gsl_fft_complex)
337 "_radix2_forward avoids unstrided data, n = %d, stride = %d",
342 /* Test the inverse fft */
345 status = FUNCTION(gsl_fft_complex,radix2_inverse) (complex_data, stride, n);
346 status = FUNCTION(compare_complex,results) ("orig", complex_tmp,
347 "fft inverse", complex_data,
349 gsl_test (status, NAME(gsl_fft_complex)
350 "_radix2_inverse with signal_noise, n = %d, stride = %d", n, stride);
354 status = FUNCTION(test, offset) (complex_data, stride, n, 0) ;
356 gsl_test (status, NAME(gsl_fft_complex)
357 "_radix2_inverse other data untouched, n = %d, stride = %d",
363 /* Test the backward fft */
366 status = FUNCTION(gsl_fft_complex,radix2_backward) (fft_complex_tmp, stride, n);
368 for (i = 0; i < n; i++)
370 REAL(complex_tmp,stride,i) *= n;
371 IMAG(complex_tmp,stride,i) *= n;
373 status = FUNCTION(compare_complex,results) ("orig",
379 gsl_test (status, NAME(gsl_fft_complex)
380 "_radix2_backward with signal_noise, n = %d, stride = %d", n, stride);
384 status = FUNCTION(test, offset) (fft_complex_tmp, stride, n, 3000) ;
386 gsl_test (status, NAME(gsl_fft_complex)
387 "_radix2_backward avoids unstrided data, n = %d, stride = %d",
393 /* Test a pulse signal */
396 FUNCTION(fft_signal,complex_pulse) (1, n, stride, 1.0, 0.0, complex_data,
398 FUNCTION(gsl_fft_complex,radix2_forward) (complex_data, stride, n);
399 status = FUNCTION(compare_complex,results) ("analytic", fft_complex_data,
400 "fft of pulse", complex_data,
402 gsl_test (status, NAME(gsl_fft_complex)
403 "_radix2_forward with signal_pulse, n = %d, stride = %d", n, stride);
408 /* Test a constant signal */
411 FUNCTION(fft_signal,complex_constant) (n, stride, 1.0, 0.0, complex_data,
413 FUNCTION(gsl_fft_complex,radix2_forward) (complex_data, stride, n);
414 status = FUNCTION(compare_complex,results) ("analytic", fft_complex_data,
418 gsl_test (status, NAME(gsl_fft_complex)
419 "_radix2_forward with signal_constant, n = %d, stride = %d",
423 /* Test an exponential (cos/sin) signal */
427 for (i = 0; i < n; i++)
429 FUNCTION(fft_signal,complex_exp) ((int)i, n, stride, 1.0, 0.0, complex_data,
431 FUNCTION(gsl_fft_complex,radix2_forward) (complex_data, stride, n);
432 status |= FUNCTION(compare_complex,results) ("analytic",
438 gsl_test (status, NAME(gsl_fft_complex)
439 "_radix2_forward with signal_exp, n = %d, stride = %d", n, stride);
445 free (fft_complex_data);
446 free (fft_complex_tmp);