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.
21 FUNCTION(gsl_fft_halfcomplex,radix2_backward) (BASE data[],
25 int status = FUNCTION(gsl_fft_halfcomplex,radix2_transform) (data, stride, n) ;
30 FUNCTION(gsl_fft_halfcomplex,radix2_inverse) (BASE data[],
34 int status = FUNCTION(gsl_fft_halfcomplex,radix2_transform) (data, stride, n);
41 /* normalize inverse fft with 1/n */
44 const ATOMIC norm = 1.0 / n;
46 for (i = 0; i < n; i++)
48 data[stride*i] *= norm;
55 FUNCTION(gsl_fft_halfcomplex,radix2_transform) (BASE data[],
65 if (n == 1) /* identity operation */
70 /* make sure that n is a power of 2 */
72 result = fft_binary_logn(n) ;
76 GSL_ERROR ("n is not a power of 2", GSL_EINVAL);
83 /* apply fft recursion */
85 p = n; q = 1 ; p_1 = n/2 ;
87 for (i = 1; i <= logn; i++)
93 for (b = 0; b < q; b++)
95 const ATOMIC z0 = VECTOR(data,stride,b*p);
96 const ATOMIC z1 = VECTOR(data,stride,b*p + p_1);
98 const ATOMIC t0_real = z0 + z1 ;
99 const ATOMIC t1_real = z0 - z1 ;
101 VECTOR(data,stride,b*p) = t0_real;
102 VECTOR(data,stride,b*p + p_1) = t1_real ;
105 /* a = 1 ... p_{i-1}/2 - 1 */
111 const ATOMIC theta = 2.0 * M_PI / p;
113 const ATOMIC s = sin (theta);
114 const ATOMIC t = sin (theta / 2.0);
115 const ATOMIC s2 = 2.0 * t * t;
117 for (a = 1; a < (p_1)/2; a++)
119 /* trignometric recurrence for w-> exp(i theta) w */
122 const ATOMIC tmp_real = w_real - s * w_imag - s2 * w_real;
123 const ATOMIC tmp_imag = w_imag + s * w_real - s2 * w_imag;
128 for (b = 0; b < q; b++)
130 ATOMIC z0_real = VECTOR(data,stride,b*p + a) ;
131 ATOMIC z0_imag = VECTOR(data,stride,b*p + p - a) ;
132 ATOMIC z1_real = VECTOR(data,stride,b*p + p_1 - a) ;
133 ATOMIC z1_imag = -VECTOR(data,stride,b*p + p_1 + a) ;
137 ATOMIC t0_real = z0_real + z1_real;
138 ATOMIC t0_imag = z0_imag + z1_imag;
142 ATOMIC t1_real = z0_real - z1_real;
143 ATOMIC t1_imag = z0_imag - z1_imag;
145 VECTOR(data,stride,b*p + a) = t0_real ;
146 VECTOR(data,stride,b*p + p_1 - a) = t0_imag ;
148 VECTOR(data,stride,b*p + p_1 + a) = (w_real * t1_real - w_imag * t1_imag) ;
149 VECTOR(data,stride,b*p + p - a) = (w_real * t1_imag + w_imag * t1_real) ;
155 for (b = 0; b < q; b++) {
156 VECTOR(data,stride,b*p + p_1/2) *= 2 ;
157 VECTOR(data,stride,b*p + p_1 + p_1/2) *= -2 ;
166 /* bit reverse the ordering of output data for decimation in
167 frequency algorithm */
169 status = FUNCTION(fft_real,bitreverse_order)(data, stride, n, logn) ;