Added MACS source
[htsworkflow.git] / htswanalysis / MACS / lib / gsl / gsl-1.11 / doc / fft.texi
1 @cindex FFT
2 @cindex Fast Fourier Transforms, see FFT
3 @cindex Fourier Transforms, see FFT
4 @cindex Discrete Fourier Transforms, see FFT
5 @cindex DFTs, see FFT
6
7 This chapter describes functions for performing Fast Fourier Transforms
8 (FFTs).  The library includes radix-2 routines (for lengths which are a
9 power of two) and mixed-radix routines (which work for any length).  For
10 efficiency there are separate versions of the routines for real data and
11 for complex data.  The mixed-radix routines are a reimplementation of the
12 @sc{fftpack} library of Paul Swarztrauber.  Fortran code for @sc{fftpack} is
13 available on Netlib (@sc{fftpack} also includes some routines for sine and
14 cosine transforms but these are currently not available in GSL).  For
15 details and derivations of the underlying algorithms consult the
16 document @cite{GSL FFT Algorithms} (@pxref{FFT References and Further Reading})
17
18 @menu
19 * Mathematical Definitions::    
20 * Overview of complex data FFTs::  
21 * Radix-2 FFT routines for complex data::  
22 * Mixed-radix FFT routines for complex data::  
23 * Overview of real data FFTs::  
24 * Radix-2 FFT routines for real data::  
25 * Mixed-radix FFT routines for real data::  
26 * FFT References and Further Reading::  
27 @end menu
28
29 @node Mathematical Definitions
30 @section Mathematical Definitions 
31 @cindex FFT mathematical definition
32
33 Fast Fourier Transforms are efficient algorithms for
34 calculating the discrete fourier transform (DFT),
35 @tex
36 \beforedisplay
37 $$
38 x_j = \sum_{k=0}^{N-1} z_k \exp(-2\pi i j k / N) 
39 $$
40 \afterdisplay
41 @end tex
42 @ifinfo
43
44 @example
45 x_j = \sum_@{k=0@}^@{N-1@} z_k \exp(-2\pi i j k / N) 
46 @end example
47 @end ifinfo
48
49 The DFT usually arises as an approximation to the continuous fourier
50 transform when functions are sampled at discrete intervals in space or
51 time.  The naive evaluation of the discrete fourier transform is a
52 matrix-vector multiplication 
53 @c{$W\vec{z}$}
54 @math{W\vec@{z@}}. A general matrix-vector multiplication takes
55 @math{O(N^2)} operations for @math{N} data-points.  Fast fourier
56 transform algorithms use a divide-and-conquer strategy to factorize the
57 matrix @math{W} into smaller sub-matrices, corresponding to the integer
58 factors of the length @math{N}.  If @math{N} can be factorized into a
59 product of integers
60 @c{$f_1 f_2 \ldots f_n$} 
61 @math{f_1 f_2 ... f_n} then the DFT can be computed in @math{O(N \sum
62 f_i)} operations.  For a radix-2 FFT this gives an operation count of
63 @math{O(N \log_2 N)}.
64
65 All the FFT functions offer three types of transform: forwards, inverse
66 and backwards, based on the same mathematical definitions.  The
67 definition of the @dfn{forward fourier transform},
68 @c{$x = \hbox{FFT}(z)$}
69 @math{x = FFT(z)}, is,
70 @tex
71 \beforedisplay
72 $$
73 x_j = \sum_{k=0}^{N-1} z_k \exp(-2\pi i j k / N) 
74 $$
75 \afterdisplay
76 @end tex
77 @ifinfo
78
79 @example
80 x_j = \sum_@{k=0@}^@{N-1@} z_k \exp(-2\pi i j k / N) 
81 @end example
82
83 @end ifinfo
84 @noindent
85 and the definition of the @dfn{inverse fourier transform},
86 @c{$x = \hbox{IFFT}(z)$}
87 @math{x = IFFT(z)}, is,
88 @tex
89 \beforedisplay
90 $$
91 z_j = {1 \over N} \sum_{k=0}^{N-1} x_k \exp(2\pi i j k / N).
92 $$
93 \afterdisplay
94 @end tex
95 @ifinfo
96
97 @example
98 z_j = @{1 \over N@} \sum_@{k=0@}^@{N-1@} x_k \exp(2\pi i j k / N).
99 @end example
100
101 @end ifinfo
102 @noindent
103 The factor of @math{1/N} makes this a true inverse.  For example, a call
104 to @code{gsl_fft_complex_forward} followed by a call to
105 @code{gsl_fft_complex_inverse} should return the original data (within
106 numerical errors).
107
108 In general there are two possible choices for the sign of the
109 exponential in the transform/ inverse-transform pair. GSL follows the
110 same convention as @sc{fftpack}, using a negative exponential for the forward
111 transform.  The advantage of this convention is that the inverse
112 transform recreates the original function with simple fourier
113 synthesis.  Numerical Recipes uses the opposite convention, a positive
114 exponential in the forward transform.
115
116 The @dfn{backwards FFT} is simply our terminology for an unscaled
117 version of the inverse FFT,
118 @tex
119 \beforedisplay
120 $$
121 z^{backwards}_j = \sum_{k=0}^{N-1} x_k \exp(2\pi i j k / N).
122 $$
123 \afterdisplay
124 @end tex
125 @ifinfo
126
127 @example
128 z^@{backwards@}_j = \sum_@{k=0@}^@{N-1@} x_k \exp(2\pi i j k / N).
129 @end example
130
131 @end ifinfo
132 @noindent
133 When the overall scale of the result is unimportant it is often
134 convenient to use the backwards FFT instead of the inverse to save
135 unnecessary divisions.
136
137 @node Overview of complex data FFTs
138 @section Overview of complex data FFTs
139 @cindex FFT, complex data
140
141 The inputs and outputs for the complex FFT routines are @dfn{packed
142 arrays} of floating point numbers.  In a packed array the real and
143 imaginary parts of each complex number are placed in alternate
144 neighboring elements.  For example, the following definition of a packed
145 array of length 6,
146
147 @example
148 double x[3*2];
149 gsl_complex_packed_array data = x;
150 @end example
151
152 @noindent
153 can be used to hold an array of three complex numbers, @code{z[3]}, in
154 the following way,
155
156 @example
157 data[0] = Re(z[0])
158 data[1] = Im(z[0])
159 data[2] = Re(z[1])
160 data[3] = Im(z[1])
161 data[4] = Re(z[2])
162 data[5] = Im(z[2])
163 @end example
164
165 @noindent
166 The array indices for the data have the same ordering as those
167 in the definition of the DFT---i.e. there are no index transformations
168 or permutations of the data.
169
170 A @dfn{stride} parameter allows the user to perform transforms on the
171 elements @code{z[stride*i]} instead of @code{z[i]}.  A stride greater
172 than 1 can be used to take an in-place FFT of the column of a matrix. A
173 stride of 1 accesses the array without any additional spacing between
174 elements.  
175
176 To perform an FFT on a vector argument, such as @code{gsl_vector_complex
177 * v}, use the following definitions (or their equivalents) when calling
178 the functions described in this chapter:
179
180 @example
181 gsl_complex_packed_array data = v->data;
182 size_t stride = v->stride;
183 size_t n = v->size;
184 @end example
185
186 For physical applications it is important to remember that the index
187 appearing in the DFT does not correspond directly to a physical
188 frequency.  If the time-step of the DFT is @math{\Delta} then the
189 frequency-domain includes both positive and negative frequencies,
190 ranging from @math{-1/(2\Delta)} through 0 to @math{+1/(2\Delta)}.  The
191 positive frequencies are stored from the beginning of the array up to
192 the middle, and the negative frequencies are stored backwards from the
193 end of the array.
194
195 Here is a table which shows the layout of the array @var{data}, and the
196 correspondence between the time-domain data @math{z}, and the
197 frequency-domain data @math{x}.
198
199 @example
200 index    z               x = FFT(z)
201
202 0        z(t = 0)        x(f = 0)
203 1        z(t = 1)        x(f = 1/(N Delta))
204 2        z(t = 2)        x(f = 2/(N Delta))
205 .        ........        ..................
206 N/2      z(t = N/2)      x(f = +1/(2 Delta),
207                                -1/(2 Delta))
208 .        ........        ..................
209 N-3      z(t = N-3)      x(f = -3/(N Delta))
210 N-2      z(t = N-2)      x(f = -2/(N Delta))
211 N-1      z(t = N-1)      x(f = -1/(N Delta))
212 @end example
213
214 @noindent
215 When @math{N} is even the location @math{N/2} contains the most positive
216 and negative frequencies (@math{+1/(2 \Delta)}, @math{-1/(2 \Delta)})
217 which are equivalent.  If @math{N} is odd then general structure of the
218 table above still applies, but @math{N/2} does not appear.
219
220
221 @node Radix-2 FFT routines for complex data
222 @section Radix-2 FFT routines for complex data
223 @cindex FFT of complex data, radix-2 algorithm
224 @cindex Radix-2 FFT, complex data
225
226 The radix-2 algorithms described in this section are simple and compact,
227 although not necessarily the most efficient.  They use the Cooley-Tukey
228 algorithm to compute in-place complex FFTs for lengths which are a power
229 of 2---no additional storage is required.  The corresponding
230 self-sorting mixed-radix routines offer better performance at the
231 expense of requiring additional working space.
232
233 All the functions described in this section are declared in the header file @file{gsl_fft_complex.h}.
234
235 @deftypefun int gsl_fft_complex_radix2_forward (gsl_complex_packed_array @var{data}, size_t @var{stride}, size_t @var{n})
236
237 @deftypefunx int gsl_fft_complex_radix2_transform (gsl_complex_packed_array @var{data}, size_t @var{stride}, size_t @var{n}, gsl_fft_direction @var{sign})
238
239 @deftypefunx int gsl_fft_complex_radix2_backward (gsl_complex_packed_array @var{data}, size_t @var{stride}, size_t @var{n})
240
241 @deftypefunx int gsl_fft_complex_radix2_inverse (gsl_complex_packed_array @var{data}, size_t @var{stride}, size_t @var{n})
242
243 These functions compute forward, backward and inverse FFTs of length
244 @var{n} with stride @var{stride}, on the packed complex array @var{data}
245 using an in-place radix-2 decimation-in-time algorithm.  The length of
246 the transform @var{n} is restricted to powers of two.  For the
247 @code{transform} version of the function the @var{sign} argument can be
248 either @code{forward} (@math{-1}) or @code{backward} (@math{+1}).
249
250 The functions return a value of @code{GSL_SUCCESS} if no errors were
251 detected, or @code{GSL_EDOM} if the length of the data @var{n} is not a
252 power of two.
253 @end deftypefun
254
255 @deftypefun int gsl_fft_complex_radix2_dif_forward (gsl_complex_packed_array @var{data}, size_t @var{stride}, size_t @var{n})
256
257 @deftypefunx int gsl_fft_complex_radix2_dif_transform (gsl_complex_packed_array @var{data}, size_t @var{stride}, size_t @var{n}, gsl_fft_direction @var{sign})
258
259 @deftypefunx int gsl_fft_complex_radix2_dif_backward (gsl_complex_packed_array @var{data}, size_t @var{stride}, size_t @var{n})
260
261 @deftypefunx int gsl_fft_complex_radix2_dif_inverse (gsl_complex_packed_array @var{data}, size_t @var{stride}, size_t @var{n})
262
263 These are decimation-in-frequency versions of the radix-2 FFT functions.
264
265 @end deftypefun
266
267
268 @comment @node Example of using radix-2 FFT routines for complex data
269 @comment @subsection Example of using radix-2 FFT routines for complex data
270
271 Here is an example program which computes the FFT of a short pulse in a
272 sample of length 128.  To make the resulting fourier transform real the
273 pulse is defined for equal positive and negative times (@math{-10}
274 @dots{} @math{10}), where the negative times wrap around the end of the
275 array.
276
277 @example
278 @verbatiminclude examples/fft.c
279 @end example
280
281 @noindent
282 Note that we have assumed that the program is using the default error
283 handler (which calls @code{abort} for any errors).  If you are not using
284 a safe error handler you would need to check the return status of
285 @code{gsl_fft_complex_radix2_forward}.
286
287 The transformed data is rescaled by @math{1/\sqrt N} so that it fits on
288 the same plot as the input.  Only the real part is shown, by the choice
289 of the input data the imaginary part is zero.  Allowing for the
290 wrap-around of negative times at @math{t=128}, and working in units of
291 @math{k/N}, the DFT approximates the continuum fourier transform, giving
292 a modulated sine function.
293 @iftex
294 @tex
295 \beforedisplay
296 $$
297 \int_{-a}^{+a} e^{-2 \pi i k x} dx = {\sin(2\pi k a) \over\pi k}
298 $$
299 \afterdisplay
300 @end tex
301
302 @sp 1
303 @center @image{fft-complex-radix2-t,2.8in} 
304 @center @image{fft-complex-radix2-f,2.8in}
305 @quotation
306 A pulse and its discrete fourier transform, output from
307 the example program.
308 @end quotation
309 @end iftex
310
311 @node Mixed-radix FFT routines for complex data
312 @section Mixed-radix FFT routines for complex data
313 @cindex FFT of complex data, mixed-radix algorithm
314 @cindex Mixed-radix FFT, complex data
315
316 This section describes mixed-radix FFT algorithms for complex data.  The
317 mixed-radix functions work for FFTs of any length.  They are a
318 reimplementation of Paul Swarztrauber's Fortran @sc{fftpack} library.
319 The theory is explained in the review article @cite{Self-sorting
320 Mixed-radix FFTs} by Clive Temperton.  The routines here use the same
321 indexing scheme and basic algorithms as @sc{fftpack}.
322
323 The mixed-radix algorithm is based on sub-transform modules---highly
324 optimized small length FFTs which are combined to create larger FFTs.
325 There are efficient modules for factors of 2, 3, 4, 5, 6 and 7.  The
326 modules for the composite factors of 4 and 6 are faster than combining
327 the modules for @math{2*2} and @math{2*3}.
328
329 For factors which are not implemented as modules there is a fall-back to
330 a general length-@math{n} module which uses Singleton's method for
331 efficiently computing a DFT. This module is @math{O(n^2)}, and slower
332 than a dedicated module would be but works for any length @math{n}.  Of
333 course, lengths which use the general length-@math{n} module will still
334 be factorized as much as possible.  For example, a length of 143 will be
335 factorized into @math{11*13}.  Large prime factors are the worst case
336 scenario, e.g. as found in @math{n=2*3*99991}, and should be avoided
337 because their @math{O(n^2)} scaling will dominate the run-time (consult
338 the document @cite{GSL FFT Algorithms} included in the GSL distribution
339 if you encounter this problem).
340
341 The mixed-radix initialization function @code{gsl_fft_complex_wavetable_alloc}
342 returns the list of factors chosen by the library for a given length
343 @math{N}.  It can be used to check how well the length has been
344 factorized, and estimate the run-time.  To a first approximation the
345 run-time scales as @math{N \sum f_i}, where the @math{f_i} are the
346 factors of @math{N}.  For programs under user control you may wish to
347 issue a warning that the transform will be slow when the length is
348 poorly factorized.  If you frequently encounter data lengths which
349 cannot be factorized using the existing small-prime modules consult
350 @cite{GSL FFT Algorithms} for details on adding support for other
351 factors.
352
353 @comment First, the space for the trigonometric lookup tables and scratch area is
354 @comment allocated by a call to one of the @code{alloc} functions.  We
355 @comment call the combination of factorization, scratch space and trigonometric
356 @comment lookup arrays a @dfn{wavetable}.  It contains the sine and cosine
357 @comment waveforms for the all the frequencies that will be used in the FFT.
358
359 @comment The wavetable is initialized by a call to the corresponding @code{init}
360 @comment function.  It factorizes the data length, using the implemented
361 @comment subtransforms as preferred factors wherever possible.  The trigonometric
362 @comment lookup table for the chosen factorization is also computed.
363
364 @comment An FFT is computed by a call to one of the @code{forward},
365 @comment @code{backward} or @code{inverse} functions, with the data, length and
366 @comment wavetable as arguments.
367
368 All the functions described in this section are declared in the header
369 file @file{gsl_fft_complex.h}.
370
371 @deftypefun {gsl_fft_complex_wavetable *} gsl_fft_complex_wavetable_alloc (size_t @var{n})
372 This function prepares a trigonometric lookup table for a complex FFT of
373 length @var{n}. The function returns a pointer to the newly allocated
374 @code{gsl_fft_complex_wavetable} if no errors were detected, and a null
375 pointer in the case of error.  The length @var{n} is factorized into a
376 product of subtransforms, and the factors and their trigonometric
377 coefficients are stored in the wavetable. The trigonometric coefficients
378 are computed using direct calls to @code{sin} and @code{cos}, for
379 accuracy.  Recursion relations could be used to compute the lookup table
380 faster, but if an application performs many FFTs of the same length then
381 this computation is a one-off overhead which does not affect the final
382 throughput.
383
384 The wavetable structure can be used repeatedly for any transform of the
385 same length.  The table is not modified by calls to any of the other FFT
386 functions.  The same wavetable can be used for both forward and backward
387 (or inverse) transforms of a given length.
388 @end deftypefun
389
390 @deftypefun void gsl_fft_complex_wavetable_free (gsl_fft_complex_wavetable * @var{wavetable})
391 This function frees the memory associated with the wavetable
392 @var{wavetable}.  The wavetable can be freed if no further FFTs of the
393 same length will be needed.
394 @end deftypefun
395
396 @noindent
397 These functions operate on a @code{gsl_fft_complex_wavetable} structure
398 which contains internal parameters for the FFT.  It is not necessary to
399 set any of the components directly but it can sometimes be useful to
400 examine them.  For example, the chosen factorization of the FFT length
401 is given and can be used to provide an estimate of the run-time or
402 numerical error. The wavetable structure is declared in the header file
403 @file{gsl_fft_complex.h}.
404
405 @deftp {Data Type} gsl_fft_complex_wavetable
406 This is a structure that holds the factorization and trigonometric
407 lookup tables for the mixed radix fft algorithm.  It has the following
408 components:
409
410 @table @code
411 @item size_t n
412 This is the number of complex data points
413
414 @item size_t nf
415 This is the number of factors that the length @code{n} was decomposed into.
416
417 @item size_t factor[64]
418 This is the array of factors.  Only the first @code{nf} elements are
419 used. 
420
421 @comment (FIXME: This is a fixed length array and therefore probably in
422 @comment violation of the GNU Coding Standards).
423
424 @item gsl_complex * trig
425 This is a pointer to a preallocated trigonometric lookup table of
426 @code{n} complex elements.
427
428 @item gsl_complex * twiddle[64]
429 This is an array of pointers into @code{trig}, giving the twiddle
430 factors for each pass.
431 @end table
432 @end deftp
433
434 @noindent
435 The mixed radix algorithms require additional working space to hold
436 the intermediate steps of the transform.
437
438 @deftypefun {gsl_fft_complex_workspace *} gsl_fft_complex_workspace_alloc (size_t @var{n})
439 This function allocates a workspace for a complex transform of length
440 @var{n}.
441 @end deftypefun
442
443 @deftypefun void gsl_fft_complex_workspace_free (gsl_fft_complex_workspace * @var{workspace})
444 This function frees the memory associated with the workspace
445 @var{workspace}. The workspace can be freed if no further FFTs of the
446 same length will be needed.
447 @end deftypefun
448
449 @comment @deftp {Data Type} gsl_fft_complex_workspace
450 @comment This is a structure that holds the workspace for the mixed radix fft
451 @comment algorithm.  It has the following components:
452 @comment
453 @comment @table @code
454 @comment @item gsl_complex * scratch
455 @comment This is a pointer to a workspace of @code{n} complex elements,
456 @comment capable of holding intermediate copies of the original data set.
457 @comment @end table
458 @comment @end deftp
459
460 @noindent
461 The following functions compute the transform,
462
463 @deftypefun int gsl_fft_complex_forward (gsl_complex_packed_array @var{data}, size_t @var{stride}, size_t @var{n}, const gsl_fft_complex_wavetable * @var{wavetable}, gsl_fft_complex_workspace * @var{work})
464 @deftypefunx int gsl_fft_complex_transform (gsl_complex_packed_array @var{data}, size_t @var{stride}, size_t @var{n}, const gsl_fft_complex_wavetable * @var{wavetable}, gsl_fft_complex_workspace * @var{work}, gsl_fft_direction @var{sign})
465 @deftypefunx int gsl_fft_complex_backward (gsl_complex_packed_array @var{data}, size_t @var{stride}, size_t @var{n}, const gsl_fft_complex_wavetable * @var{wavetable}, gsl_fft_complex_workspace * @var{work})
466 @deftypefunx int gsl_fft_complex_inverse (gsl_complex_packed_array @var{data}, size_t @var{stride}, size_t @var{n}, const gsl_fft_complex_wavetable * @var{wavetable}, gsl_fft_complex_workspace * @var{work})
467
468 These functions compute forward, backward and inverse FFTs of length
469 @var{n} with stride @var{stride}, on the packed complex array
470 @var{data}, using a mixed radix decimation-in-frequency algorithm.
471 There is no restriction on the length @var{n}.  Efficient modules are
472 provided for subtransforms of length 2, 3, 4, 5, 6 and 7.  Any remaining
473 factors are computed with a slow, @math{O(n^2)}, general-@math{n}
474 module. The caller must supply a @var{wavetable} containing the
475 trigonometric lookup tables and a workspace @var{work}.  For the
476 @code{transform} version of the function the @var{sign} argument can be
477 either @code{forward} (@math{-1}) or @code{backward} (@math{+1}).
478
479 The functions return a value of @code{0} if no errors were detected. The
480 following @code{gsl_errno} conditions are defined for these functions:
481
482 @table @code
483 @item GSL_EDOM
484 The length of the data @var{n} is not a positive integer (i.e. @var{n}
485 is zero).
486
487 @item GSL_EINVAL
488 The length of the data @var{n} and the length used to compute the given
489 @var{wavetable} do not match.
490 @end table
491 @end deftypefun
492
493 @comment @node Example of using mixed-radix FFT routines for complex data
494 @comment @subsection Example of using mixed-radix FFT routines for complex data
495
496 Here is an example program which computes the FFT of a short pulse in a
497 sample of length 630 (@math{=2*3*3*5*7}) using the mixed-radix
498 algorithm.
499
500 @example
501 @verbatiminclude examples/fftmr.c
502 @end example
503
504 @noindent
505 Note that we have assumed that the program is using the default
506 @code{gsl} error handler (which calls @code{abort} for any errors).  If
507 you are not using a safe error handler you would need to check the
508 return status of all the @code{gsl} routines.
509
510 @node Overview of real data FFTs
511 @section Overview of real data FFTs
512 @cindex FFT of real data
513 The functions for real data are similar to those for complex data.
514 However, there is an important difference between forward and inverse
515 transforms.  The fourier transform of a real sequence is not real.  It is
516 a complex sequence with a special symmetry:
517 @tex
518 \beforedisplay
519 $$
520 z_k = z_{N-k}^*
521 $$
522 \afterdisplay
523 @end tex
524 @ifinfo
525
526 @example
527 z_k = z_@{N-k@}^*
528 @end example
529
530 @end ifinfo
531 @noindent
532 A sequence with this symmetry is called @dfn{conjugate-complex} or
533 @dfn{half-complex}.  This different structure requires different
534 storage layouts for the forward transform (from real to half-complex)
535 and inverse transform (from half-complex back to real).  As a
536 consequence the routines are divided into two sets: functions in
537 @code{gsl_fft_real} which operate on real sequences and functions in
538 @code{gsl_fft_halfcomplex} which operate on half-complex sequences.
539
540 Functions in @code{gsl_fft_real} compute the frequency coefficients of a
541 real sequence.  The half-complex coefficients @math{c} of a real sequence
542 @math{x} are given by fourier analysis,
543 @tex
544 \beforedisplay
545 $$
546 c_k = \sum_{j=0}^{N-1} x_j \exp(-2 \pi i j k /N)
547 $$
548 \afterdisplay
549 @end tex
550 @ifinfo
551
552 @example
553 c_k = \sum_@{j=0@}^@{N-1@} x_j \exp(-2 \pi i j k /N)
554 @end example
555
556 @end ifinfo
557 @noindent
558 Functions in @code{gsl_fft_halfcomplex} compute inverse or backwards
559 transforms.  They reconstruct real sequences by fourier synthesis from
560 their half-complex frequency coefficients, @math{c},
561 @tex
562 \beforedisplay
563 $$
564 x_j = {1 \over N} \sum_{k=0}^{N-1} c_k \exp(2 \pi i j k /N)
565 $$
566 \afterdisplay
567 @end tex
568 @ifinfo
569
570 @example
571 x_j = @{1 \over N@} \sum_@{k=0@}^@{N-1@} c_k \exp(2 \pi i j k /N)
572 @end example
573
574 @end ifinfo
575 @noindent
576 The symmetry of the half-complex sequence implies that only half of the
577 complex numbers in the output need to be stored.  The remaining half can
578 be reconstructed using the half-complex symmetry condition. This works
579 for all lengths, even and odd---when the length is even the middle value
580 where @math{k=N/2} is also real.  Thus only @var{N} real numbers are
581 required to store the half-complex sequence, and the transform of a real
582 sequence can be stored in the same size array as the original data.
583
584 The precise storage arrangements depend on the algorithm, and are
585 different for radix-2 and mixed-radix routines.  The radix-2 function
586 operates in-place, which constrains the locations where each element can
587 be stored.  The restriction forces real and imaginary parts to be stored
588 far apart.  The mixed-radix algorithm does not have this restriction, and
589 it stores the real and imaginary parts of a given term in neighboring
590 locations (which is desirable for better locality of memory accesses).
591
592 @node Radix-2 FFT routines for real data
593 @section Radix-2 FFT routines for real data
594 @cindex FFT of real data, radix-2 algorithm
595 @cindex Radix-2 FFT for real data
596
597 This section describes radix-2 FFT algorithms for real data.  They use
598 the Cooley-Tukey algorithm to compute in-place FFTs for lengths which
599 are a power of 2. 
600
601 The radix-2 FFT functions for real data are declared in the header files
602 @file{gsl_fft_real.h} 
603
604 @deftypefun int gsl_fft_real_radix2_transform (double @var{data}[], size_t @var{stride}, size_t @var{n})
605
606 This function computes an in-place radix-2 FFT of length @var{n} and
607 stride @var{stride} on the real array @var{data}.  The output is a
608 half-complex sequence, which is stored in-place.  The arrangement of the
609 half-complex terms uses the following scheme: for @math{k < N/2} the
610 real part of the @math{k}-th term is stored in location @math{k}, and
611 the corresponding imaginary part is stored in location @math{N-k}.  Terms
612 with @math{k > N/2} can be reconstructed using the symmetry 
613 @c{$z_k = z^*_{N-k}$}
614 @math{z_k = z^*_@{N-k@}}. 
615 The terms for @math{k=0} and @math{k=N/2} are both purely
616 real, and count as a special case.  Their real parts are stored in
617 locations @math{0} and @math{N/2} respectively, while their imaginary
618 parts which are zero are not stored.
619
620 The following table shows the correspondence between the output
621 @var{data} and the equivalent results obtained by considering the input
622 data as a complex sequence with zero imaginary part,
623
624 @example
625 complex[0].real    =    data[0] 
626 complex[0].imag    =    0 
627 complex[1].real    =    data[1] 
628 complex[1].imag    =    data[N-1]
629 ...............         ................
630 complex[k].real    =    data[k]
631 complex[k].imag    =    data[N-k] 
632 ...............         ................
633 complex[N/2].real  =    data[N/2]
634 complex[N/2].imag  =    0
635 ...............         ................
636 complex[k'].real   =    data[k]        k' = N - k
637 complex[k'].imag   =   -data[N-k] 
638 ...............         ................
639 complex[N-1].real  =    data[1]
640 complex[N-1].imag  =   -data[N-1]
641 @end example
642 @noindent
643 Note that the output data can be converted into the full complex
644 sequence using the function @code{gsl_fft_halfcomplex_unpack}
645 described in the next section.
646
647 @end deftypefun
648 The radix-2 FFT functions for halfcomplex data are declared in the
649 header file @file{gsl_fft_halfcomplex.h}.
650
651 @deftypefun int gsl_fft_halfcomplex_radix2_inverse (double @var{data}[], size_t @var{stride}, size_t @var{n})
652 @deftypefunx int gsl_fft_halfcomplex_radix2_backward (double @var{data}[], size_t @var{stride}, size_t @var{n})
653
654 These functions compute the inverse or backwards in-place radix-2 FFT of
655 length @var{n} and stride @var{stride} on the half-complex sequence
656 @var{data} stored according the output scheme used by
657 @code{gsl_fft_real_radix2}.  The result is a real array stored in natural
658 order.
659
660 @end deftypefun
661
662
663
664 @node Mixed-radix FFT routines for real data
665 @section Mixed-radix FFT routines for real data
666 @cindex FFT of real data, mixed-radix algorithm
667 @cindex Mixed-radix FFT, real data
668
669 This section describes mixed-radix FFT algorithms for real data.  The
670 mixed-radix functions work for FFTs of any length.  They are a
671 reimplementation of the real-FFT routines in the Fortran @sc{fftpack} library
672 by Paul Swarztrauber.  The theory behind the algorithm is explained in
673 the article @cite{Fast Mixed-Radix Real Fourier Transforms} by Clive
674 Temperton.  The routines here use the same indexing scheme and basic
675 algorithms as @sc{fftpack}.
676
677 The functions use the @sc{fftpack} storage convention for half-complex
678 sequences.  In this convention the half-complex transform of a real
679 sequence is stored with frequencies in increasing order, starting at
680 zero, with the real and imaginary parts of each frequency in neighboring
681 locations.  When a value is known to be real the imaginary part is not
682 stored.  The imaginary part of the zero-frequency component is never
683 stored.  It is known to be zero (since the zero frequency component is
684 simply the sum of the input data (all real)).  For a sequence of even
685 length the imaginary part of the frequency @math{n/2} is not stored
686 either, since the symmetry 
687 @c{$z_k = z_{N-k}^*$}
688 @math{z_k = z_@{N-k@}^*} implies that this is
689 purely real too.
690
691 The storage scheme is best shown by some examples.  The table below
692 shows the output for an odd-length sequence, @math{n=5}.  The two columns
693 give the correspondence between the 5 values in the half-complex
694 sequence returned by @code{gsl_fft_real_transform}, @var{halfcomplex}[] and the
695 values @var{complex}[] that would be returned if the same real input
696 sequence were passed to @code{gsl_fft_complex_backward} as a complex
697 sequence (with imaginary parts set to @code{0}),
698
699 @example
700 complex[0].real  =  halfcomplex[0] 
701 complex[0].imag  =  0
702 complex[1].real  =  halfcomplex[1] 
703 complex[1].imag  =  halfcomplex[2]
704 complex[2].real  =  halfcomplex[3]
705 complex[2].imag  =  halfcomplex[4]
706 complex[3].real  =  halfcomplex[3]
707 complex[3].imag  = -halfcomplex[4]
708 complex[4].real  =  halfcomplex[1]
709 complex[4].imag  = -halfcomplex[2]
710 @end example
711
712 @noindent
713 The upper elements of the @var{complex} array, @code{complex[3]} and
714 @code{complex[4]} are filled in using the symmetry condition.  The
715 imaginary part of the zero-frequency term @code{complex[0].imag} is
716 known to be zero by the symmetry.
717
718 The next table shows the output for an even-length sequence, @math{n=6}
719 In the even case there are two values which are purely real,
720
721 @example
722 complex[0].real  =  halfcomplex[0]
723 complex[0].imag  =  0
724 complex[1].real  =  halfcomplex[1] 
725 complex[1].imag  =  halfcomplex[2] 
726 complex[2].real  =  halfcomplex[3] 
727 complex[2].imag  =  halfcomplex[4] 
728 complex[3].real  =  halfcomplex[5] 
729 complex[3].imag  =  0 
730 complex[4].real  =  halfcomplex[3] 
731 complex[4].imag  = -halfcomplex[4]
732 complex[5].real  =  halfcomplex[1] 
733 complex[5].imag  = -halfcomplex[2] 
734 @end example
735
736 @noindent
737 The upper elements of the @var{complex} array, @code{complex[4]} and
738 @code{complex[5]} are filled in using the symmetry condition.  Both
739 @code{complex[0].imag} and @code{complex[3].imag} are known to be zero.
740
741 All these functions are declared in the header files
742 @file{gsl_fft_real.h} and @file{gsl_fft_halfcomplex.h}.
743
744 @deftypefun {gsl_fft_real_wavetable *} gsl_fft_real_wavetable_alloc (size_t @var{n})
745 @deftypefunx {gsl_fft_halfcomplex_wavetable *} gsl_fft_halfcomplex_wavetable_alloc (size_t @var{n})
746 These functions prepare trigonometric lookup tables for an FFT of size
747 @math{n} real elements.  The functions return a pointer to the newly
748 allocated struct if no errors were detected, and a null pointer in the
749 case of error.  The length @var{n} is factorized into a product of
750 subtransforms, and the factors and their trigonometric coefficients are
751 stored in the wavetable. The trigonometric coefficients are computed
752 using direct calls to @code{sin} and @code{cos}, for accuracy.
753 Recursion relations could be used to compute the lookup table faster,
754 but if an application performs many FFTs of the same length then
755 computing the wavetable is a one-off overhead which does not affect the
756 final throughput.
757
758 The wavetable structure can be used repeatedly for any transform of the
759 same length.  The table is not modified by calls to any of the other FFT
760 functions.  The appropriate type of wavetable must be used for forward
761 real or inverse half-complex transforms.
762 @end deftypefun
763
764 @deftypefun void gsl_fft_real_wavetable_free (gsl_fft_real_wavetable * @var{wavetable})
765 @deftypefunx void gsl_fft_halfcomplex_wavetable_free (gsl_fft_halfcomplex_wavetable * @var{wavetable})
766 These functions free the memory associated with the wavetable
767 @var{wavetable}. The wavetable can be freed if no further FFTs of the
768 same length will be needed.
769 @end deftypefun
770
771 @noindent
772 The mixed radix algorithms require additional working space to hold
773 the intermediate steps of the transform,
774
775 @deftypefun {gsl_fft_real_workspace *} gsl_fft_real_workspace_alloc (size_t @var{n})
776 This function allocates a workspace for a real transform of length
777 @var{n}.  The same workspace can be used for both forward real and inverse
778 halfcomplex transforms.
779 @end deftypefun
780
781 @deftypefun void gsl_fft_real_workspace_free (gsl_fft_real_workspace * @var{workspace})
782 This function frees the memory associated with the workspace
783 @var{workspace}. The workspace can be freed if no further FFTs of the
784 same length will be needed.
785 @end deftypefun
786
787 @noindent
788 The following functions compute the transforms of real and half-complex
789 data,
790
791 @deftypefun int gsl_fft_real_transform (double @var{data}[], size_t @var{stride}, size_t @var{n}, const gsl_fft_real_wavetable * @var{wavetable}, gsl_fft_real_workspace * @var{work})
792 @deftypefunx int gsl_fft_halfcomplex_transform (double @var{data}[], size_t @var{stride}, size_t @var{n}, const gsl_fft_halfcomplex_wavetable * @var{wavetable}, gsl_fft_real_workspace * @var{work})
793 These functions compute the FFT of @var{data}, a real or half-complex
794 array of length @var{n}, using a mixed radix decimation-in-frequency
795 algorithm.  For @code{gsl_fft_real_transform} @var{data} is an array of
796 time-ordered real data.  For @code{gsl_fft_halfcomplex_transform}
797 @var{data} contains fourier coefficients in the half-complex ordering
798 described above.  There is no restriction on the length @var{n}.
799 Efficient modules are provided for subtransforms of length 2, 3, 4 and
800 5.  Any remaining factors are computed with a slow, @math{O(n^2)},
801 general-n module.  The caller must supply a @var{wavetable} containing
802 trigonometric lookup tables and a workspace @var{work}. 
803 @end deftypefun
804
805 @deftypefun int gsl_fft_real_unpack (const double @var{real_coefficient}[], gsl_complex_packed_array @var{complex_coefficient}, size_t @var{stride}, size_t @var{n})
806
807 This function converts a single real array, @var{real_coefficient} into
808 an equivalent complex array, @var{complex_coefficient}, (with imaginary
809 part set to zero), suitable for @code{gsl_fft_complex} routines.  The
810 algorithm for the conversion is simply,
811
812 @example
813 for (i = 0; i < n; i++)
814   @{
815     complex_coefficient[i].real 
816       = real_coefficient[i];
817     complex_coefficient[i].imag 
818       = 0.0;
819   @}
820 @end example
821 @end deftypefun
822
823 @deftypefun int gsl_fft_halfcomplex_unpack (const double @var{halfcomplex_coefficient}[], gsl_complex_packed_array @var{complex_coefficient}, size_t @var{stride}, size_t @var{n})
824
825 This function converts @var{halfcomplex_coefficient}, an array of
826 half-complex coefficients as returned by @code{gsl_fft_real_transform}, into an
827 ordinary complex array, @var{complex_coefficient}.  It fills in the
828 complex array using the symmetry 
829 @c{$z_k = z_{N-k}^*$}
830 @math{z_k = z_@{N-k@}^*}
831 to reconstruct the redundant elements.  The algorithm for the conversion
832 is,
833
834 @example  
835 complex_coefficient[0].real 
836   = halfcomplex_coefficient[0];
837 complex_coefficient[0].imag 
838   = 0.0;
839
840 for (i = 1; i < n - i; i++)
841   @{
842     double hc_real 
843       = halfcomplex_coefficient[2 * i - 1];
844     double hc_imag 
845       = halfcomplex_coefficient[2 * i];
846     complex_coefficient[i].real = hc_real;
847     complex_coefficient[i].imag = hc_imag;
848     complex_coefficient[n - i].real = hc_real;
849     complex_coefficient[n - i].imag = -hc_imag;
850   @}
851
852 if (i == n - i)
853   @{
854     complex_coefficient[i].real 
855       = halfcomplex_coefficient[n - 1];
856     complex_coefficient[i].imag 
857       = 0.0;
858   @}
859 @end example
860 @end deftypefun
861
862 @comment @node Example of using mixed-radix FFT routines for real data
863 @comment @subsection Example of using mixed-radix FFT routines for real data
864
865 Here is an example program using @code{gsl_fft_real_transform} and
866 @code{gsl_fft_halfcomplex_inverse}.  It generates a real signal in the
867 shape of a square pulse.  The pulse is fourier transformed to frequency
868 space, and all but the lowest ten frequency components are removed from
869 the array of fourier coefficients returned by
870 @code{gsl_fft_real_transform}.
871
872 The remaining fourier coefficients are transformed back to the
873 time-domain, to give a filtered version of the square pulse.  Since
874 fourier coefficients are stored using the half-complex symmetry both
875 positive and negative frequencies are removed and the final filtered
876 signal is also real.
877
878 @example
879 @verbatiminclude examples/fftreal.c
880 @end example
881
882 @iftex
883 @sp 1
884 @center @image{fft-real-mixedradix,3.4in}
885
886 @center Low-pass filtered version of a real pulse, 
887 @center output from the example program.
888 @end iftex
889
890 @node FFT References and Further Reading
891 @section References and Further Reading
892
893 A good starting point for learning more about the FFT is the review
894 article @cite{Fast Fourier Transforms: A Tutorial Review and A State of
895 the Art} by Duhamel and Vetterli,
896
897 @itemize @asis
898 @item
899 P. Duhamel and M. Vetterli.
900 Fast fourier transforms: A tutorial review and a state of the art.
901 @cite{Signal Processing}, 19:259--299, 1990.
902 @end itemize
903
904 @noindent
905 To find out about the algorithms used in the GSL routines you may want
906 to consult the document @cite{GSL FFT Algorithms} (it is included
907 in GSL, as @file{doc/fftalgorithms.tex}).  This has general information
908 on FFTs and explicit derivations of the implementation for each
909 routine.  There are also references to the relevant literature.  For
910 convenience some of the more important references are reproduced below.
911
912 @noindent
913 There are several introductory books on the FFT with example programs,
914 such as @cite{The Fast Fourier Transform} by Brigham and @cite{DFT/FFT
915 and Convolution Algorithms} by Burrus and Parks,
916
917 @itemize @asis 
918 @item
919 E. Oran Brigham.
920 @cite{The Fast Fourier Transform}.
921 Prentice Hall, 1974.
922
923 @item
924 C. S. Burrus and T. W. Parks.
925 @cite{DFT/FFT and Convolution Algorithms}.
926 Wiley, 1984.
927 @end itemize
928
929 @noindent
930 Both these introductory books cover the radix-2 FFT in some detail.
931 The mixed-radix algorithm at the heart of the @sc{fftpack} routines is
932 reviewed in Clive Temperton's paper,
933
934 @itemize @asis 
935 @item
936 Clive Temperton.
937 Self-sorting mixed-radix fast fourier transforms.
938 @cite{Journal of Computational Physics}, 52(1):1--23, 1983.
939 @end itemize
940
941 @noindent
942 The derivation of FFTs for real-valued data is explained in the
943 following two articles,
944
945 @itemize @asis
946 @item
947 Henrik V. Sorenson, Douglas L. Jones, Michael T. Heideman, and C. Sidney
948 Burrus.
949 Real-valued fast fourier transform algorithms.
950 @cite{IEEE Transactions on Acoustics, Speech, and Signal Processing},
951 ASSP-35(6):849--863, 1987.
952
953 @item
954 Clive Temperton.
955 Fast mixed-radix real fourier transforms.
956 @cite{Journal of Computational Physics}, 52:340--350, 1983.
957 @end itemize
958
959 @noindent
960 In 1979 the IEEE published a compendium of carefully-reviewed Fortran
961 FFT programs in @cite{Programs for Digital Signal Processing}.  It is a
962 useful reference for implementations of many different FFT
963 algorithms,
964
965 @itemize @asis 
966 @item
967 Digital Signal Processing Committee and IEEE Acoustics, Speech, and Signal
968 Processing Committee, editors.
969 @cite{Programs for Digital Signal Processing}.
970 IEEE Press, 1979.
971 @end itemize
972 @comment  @noindent
973 @comment  There is also an annotated bibliography of papers on the FFT and related
974 @comment  topics by Burrus,
975
976 @comment  @itemize @asis 
977 @comment  @item C. S. Burrus.  Notes on the FFT.
978 @comment  @end itemize
979 @comment  @noindent
980 @comment The notes are available from @url{http://www-dsp.rice.edu/res/fft/fftnote.asc}.
981
982 @noindent
983 For large-scale FFT work we recommend the use of the dedicated FFTW library
984 by Frigo and Johnson.  The FFTW library is self-optimizing---it
985 automatically tunes itself for each hardware platform in order to
986 achieve maximum performance.  It is available under the GNU GPL.
987
988 @itemize @asis
989 @item
990 FFTW Website, @uref{http://www.fftw.org/}
991 @end itemize
992
993 @noindent
994 The source code for @sc{fftpack} is available from Netlib,
995
996 @itemize @asis
997 @item
998 FFTPACK, @uref{http://www.netlib.org/fftpack/}
999 @end itemize
1000
1001