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_real,func) (size_t stride, size_t n);
25 void FUNCTION(test_real,bitreverse_order) (size_t stride, size_t n);
26 void FUNCTION(test_real,radix2) (size_t stride, size_t n);
28 void FUNCTION(test_real,func) (size_t stride, size_t n)
33 TYPE(gsl_fft_real_wavetable) * rw ;
34 TYPE(gsl_fft_halfcomplex_wavetable) * hcw ;
35 TYPE(gsl_fft_real_workspace) * rwork ;
37 BASE * real_data = (BASE *) malloc (n * stride * sizeof (BASE));
38 BASE * complex_data = (BASE *) malloc (2 * n * stride * sizeof (BASE));
39 BASE * complex_tmp = (BASE *) malloc (2 * n * stride * sizeof (BASE));
40 BASE * fft_complex_data = (BASE *) malloc (2 * n * stride * sizeof (BASE));
42 for (i = 0 ; i < n * stride ; i++)
44 real_data[i] = (BASE)i ;
47 for (i = 0 ; i < 2 * n * stride ; i++)
49 complex_data[i] = (BASE)(i + 1000.0) ;
50 complex_tmp[i] = (BASE)(i + 2000.0) ;
51 fft_complex_data[i] = (BASE)(i + 3000.0) ;
54 gsl_set_error_handler (NULL); /* abort on any errors */
56 /* mixed radix real fft */
58 rw = FUNCTION(gsl_fft_real_wavetable,alloc) (n);
59 gsl_test (rw == 0, NAME(gsl_fft_real_wavetable)
60 "_alloc, n = %d, stride = %d", n, stride);
62 rwork = FUNCTION(gsl_fft_real_workspace,alloc) (n);
63 gsl_test (rwork == 0, NAME(gsl_fft_real_workspace)
66 FUNCTION(fft_signal,real_noise) (n, stride, complex_data, fft_complex_data);
67 memcpy (complex_tmp, complex_data, 2 * n * stride * sizeof (BASE));
69 for (i = 0; i < n; i++)
71 real_data[i*stride] = REAL(complex_data,stride,i);
74 FUNCTION(gsl_fft_real,transform) (real_data, stride, n, rw, rwork);
75 FUNCTION(gsl_fft_halfcomplex,unpack) (real_data, complex_data, stride, n);
77 status = FUNCTION(compare_complex,results) ("dft", fft_complex_data,
78 "fft of noise", complex_data,
80 gsl_test (status, NAME(gsl_fft_real)
81 " with signal_real_noise, n = %d, stride = %d", n, stride);
83 /* compute the inverse fft */
85 hcw = FUNCTION(gsl_fft_halfcomplex_wavetable,alloc) (n);
86 gsl_test (hcw == 0, NAME(gsl_fft_halfcomplex_wavetable)
87 "_alloc, n = %d, stride = %d", n, stride);
89 status = FUNCTION(gsl_fft_halfcomplex,transform) (real_data, stride, n, hcw, rwork);
91 for (i = 0; i < n; i++)
93 real_data[i*stride] /= n;
96 FUNCTION(gsl_fft_real,unpack) (real_data, complex_data, stride, n);
98 status = FUNCTION(compare_complex,results) ("orig", complex_tmp,
99 "fft inverse", complex_data,
102 gsl_test (status, NAME(gsl_fft_halfcomplex)
103 " with data from signal_noise, n = %d, stride = %d", n, stride);
105 FUNCTION(gsl_fft_real_workspace,free) (rwork);
106 FUNCTION(gsl_fft_real_wavetable,free) (rw);
107 FUNCTION(gsl_fft_halfcomplex_wavetable,free) (hcw);
112 free(fft_complex_data) ;
117 FUNCTION(test_real,bitreverse_order) (size_t stride, size_t n)
122 BASE * tmp = (BASE *) malloc (n * stride * sizeof (BASE));
123 BASE * data = (BASE *) malloc (n * stride * sizeof (BASE));
124 BASE * reversed_data = (BASE *) malloc (n * stride * sizeof (BASE));
126 for (i = 0; i < stride * n; i++)
131 memcpy (tmp, data, n * stride * sizeof(BASE)) ;
133 logn = 0 ; while (n > (1U <<logn)) {logn++;} ;
135 /* do a naive bit reversal as a baseline for testing the other routines */
137 for (i = 0; i < n; i++)
143 for (bit = 0; bit < logn; bit++)
145 j <<= 1; /* reverse shift i into j */
150 reversed_data[j*stride] = data[i*stride] ;
153 FUNCTION(fft_real,bitreverse_order) (data, stride, n, logn);
155 status = FUNCTION(compare_real,results) ("naive bit reverse",
157 "fft_complex_bitreverse_order",
161 gsl_test (status, NAME(fft_real) "_bitreverse_order, n = %d", n);
163 free (reversed_data) ;
169 void FUNCTION(test_real,radix2) (size_t stride, size_t n)
174 BASE * real_data = (BASE *) malloc (n * stride * sizeof (BASE));
175 BASE * complex_data = (BASE *) malloc (2 * n * stride * sizeof (BASE));
176 BASE * complex_tmp = (BASE *) malloc (2 * n * stride * sizeof (BASE));
177 BASE * fft_complex_data = (BASE *) malloc (2 * n * stride * sizeof (BASE));
179 for (i = 0 ; i < n * stride ; i++)
181 real_data[i] = (BASE)i ;
184 for (i = 0 ; i < 2 * n * stride ; i++)
186 complex_data[i] = (BASE)(i + 1000.0) ;
187 complex_tmp[i] = (BASE)(i + 2000.0) ;
188 fft_complex_data[i] = (BASE)(i + 3000.0) ;
191 gsl_set_error_handler (NULL); /* abort on any errors */
193 /* radix-2 real fft */
195 FUNCTION(fft_signal,real_noise) (n, stride, complex_data, fft_complex_data);
196 memcpy (complex_tmp, complex_data, 2 * n * stride * sizeof (BASE));
198 for (i = 0; i < n; i++)
200 real_data[i*stride] = REAL(complex_data,stride,i);
203 FUNCTION(gsl_fft_real,radix2_transform) (real_data, stride, n);
204 FUNCTION(gsl_fft_halfcomplex,radix2_unpack) (real_data, complex_data, stride, n);
206 status = FUNCTION(compare_complex,results) ("dft", fft_complex_data,
207 "fft of noise", complex_data,
209 gsl_test (status, NAME(gsl_fft_real)
210 "_radix2 with signal_real_noise, n = %d, stride = %d", n, stride);
212 /* compute the inverse fft */
214 status = FUNCTION(gsl_fft_halfcomplex,radix2_transform) (real_data, stride, n);
216 for (i = 0; i < n; i++)
218 real_data[i*stride] /= n;
221 FUNCTION(gsl_fft_real,unpack) (real_data, complex_data, stride, n);
223 status = FUNCTION(compare_complex,results) ("orig", complex_tmp,
224 "fft inverse", complex_data,
227 gsl_test (status, NAME(gsl_fft_halfcomplex)
228 "_radix2 with data from signal_noise, n = %d, stride = %d", n, stride);
234 free(fft_complex_data) ;