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.
23 FUNCTION(gsl_fft_complex,forward) (TYPE(gsl_complex_packed_array) data,
26 const TYPE(gsl_fft_complex_wavetable) * wavetable,
27 TYPE(gsl_fft_complex_workspace) * work)
29 gsl_fft_direction sign = gsl_fft_forward;
30 int status = FUNCTION(gsl_fft_complex,transform) (data, stride, n,
31 wavetable, work, sign);
36 FUNCTION(gsl_fft_complex,backward) (TYPE(gsl_complex_packed_array) data,
39 const TYPE(gsl_fft_complex_wavetable) * wavetable,
40 TYPE(gsl_fft_complex_workspace) * work)
42 gsl_fft_direction sign = gsl_fft_backward;
43 int status = FUNCTION(gsl_fft_complex,transform) (data, stride, n,
44 wavetable, work, sign);
49 FUNCTION(gsl_fft_complex,inverse) (TYPE(gsl_complex_packed_array) data,
52 const TYPE(gsl_fft_complex_wavetable) * wavetable,
53 TYPE(gsl_fft_complex_workspace) * work)
55 gsl_fft_direction sign = gsl_fft_backward;
56 int status = FUNCTION(gsl_fft_complex,transform) (data, stride, n,
57 wavetable, work, sign);
64 /* normalize inverse fft with 1/n */
67 const ATOMIC norm = ONE / (ATOMIC)n;
69 for (i = 0; i < n; i++)
71 REAL(data,stride,i) *= norm;
72 IMAG(data,stride,i) *= norm;
79 FUNCTION(gsl_fft_complex,transform) (TYPE(gsl_complex_packed_array) data,
82 const TYPE(gsl_fft_complex_wavetable) * wavetable,
83 TYPE(gsl_fft_complex_workspace) * work,
84 const gsl_fft_direction sign)
86 const size_t nf = wavetable->nf;
90 size_t q, product = 1;
92 TYPE(gsl_complex) *twiddle1, *twiddle2, *twiddle3, *twiddle4,
97 BASE * const scratch = work->scratch;
100 size_t istride = stride;
102 BASE * out = scratch;
107 GSL_ERROR ("length n must be positive integer", GSL_EDOM);
111 { /* FFT of 1 data point is the identity */
115 if (n != wavetable->n)
117 GSL_ERROR ("wavetable does not match length of data", GSL_EINVAL);
122 GSL_ERROR ("workspace does not match length of data", GSL_EINVAL);
125 for (i = 0; i < nf; i++)
127 const size_t factor = wavetable->factor[i];
150 twiddle1 = wavetable->twiddle[i];
151 FUNCTION(fft_complex,pass_2) (in, istride, out, ostride, sign,
152 product, n, twiddle1);
154 else if (factor == 3)
156 twiddle1 = wavetable->twiddle[i];
157 twiddle2 = twiddle1 + q;
158 FUNCTION(fft_complex,pass_3) (in, istride, out, ostride, sign,
159 product, n, twiddle1, twiddle2);
161 else if (factor == 4)
163 twiddle1 = wavetable->twiddle[i];
164 twiddle2 = twiddle1 + q;
165 twiddle3 = twiddle2 + q;
166 FUNCTION(fft_complex,pass_4) (in, istride, out, ostride, sign,
167 product, n, twiddle1, twiddle2,
170 else if (factor == 5)
172 twiddle1 = wavetable->twiddle[i];
173 twiddle2 = twiddle1 + q;
174 twiddle3 = twiddle2 + q;
175 twiddle4 = twiddle3 + q;
176 FUNCTION(fft_complex,pass_5) (in, istride, out, ostride, sign,
177 product, n, twiddle1, twiddle2,
180 else if (factor == 6)
182 twiddle1 = wavetable->twiddle[i];
183 twiddle2 = twiddle1 + q;
184 twiddle3 = twiddle2 + q;
185 twiddle4 = twiddle3 + q;
186 twiddle5 = twiddle4 + q;
187 FUNCTION(fft_complex,pass_6) (in, istride, out, ostride, sign,
188 product, n, twiddle1, twiddle2,
189 twiddle3, twiddle4, twiddle5);
191 else if (factor == 7)
193 twiddle1 = wavetable->twiddle[i];
194 twiddle2 = twiddle1 + q;
195 twiddle3 = twiddle2 + q;
196 twiddle4 = twiddle3 + q;
197 twiddle5 = twiddle4 + q;
198 twiddle6 = twiddle5 + q;
199 FUNCTION(fft_complex,pass_7) (in, istride, out, ostride, sign,
200 product, n, twiddle1, twiddle2,
201 twiddle3, twiddle4, twiddle5,
206 twiddle1 = wavetable->twiddle[i];
207 FUNCTION(fft_complex,pass_n) (in, istride, out, ostride, sign,
208 factor, product, n, twiddle1);
212 if (state == 1) /* copy results back from scratch to data */
214 for (i = 0; i < n; i++)
216 REAL(data,stride,i) = REAL(scratch,1,i) ;
217 IMAG(data,stride,i) = IMAG(scratch,1,i) ;