File: Mixed_002dradix-FFT-routines-for-complex-data.html

package info (click to toggle)
gsl-ref-html 2.3-1
  • links: PTS
  • area: non-free
  • in suites: bullseye, buster, sid
  • size: 6,876 kB
  • ctags: 4,574
  • sloc: makefile: 35
file content (321 lines) | stat: -rw-r--r-- 15,520 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 The GSL Team.

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with the
Invariant Sections being "GNU General Public License" and "Free Software
Needs Free Documentation", the Front-Cover text being "A GNU Manual",
and with the Back-Cover Text being (a) (see below). A copy of the
license is included in the section entitled "GNU Free Documentation
License".

(a) The Back-Cover Text is: "You have the freedom to copy and modify this
GNU Manual." -->
<!-- Created by GNU Texinfo 5.1, http://www.gnu.org/software/texinfo/ -->
<head>
<title>GNU Scientific Library &ndash; Reference Manual: Mixed-radix FFT routines for complex data</title>

<meta name="description" content="GNU Scientific Library &ndash; Reference Manual: Mixed-radix FFT routines for complex data">
<meta name="keywords" content="GNU Scientific Library &ndash; Reference Manual: Mixed-radix FFT routines for complex data">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="makeinfo">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="index.html#Top" rel="start" title="Top">
<link href="Function-Index.html#Function-Index" rel="index" title="Function Index">
<link href="Fast-Fourier-Transforms.html#Fast-Fourier-Transforms" rel="up" title="Fast Fourier Transforms">
<link href="Overview-of-real-data-FFTs.html#Overview-of-real-data-FFTs" rel="next" title="Overview of real data FFTs">
<link href="Radix_002d2-FFT-routines-for-complex-data.html#Radix_002d2-FFT-routines-for-complex-data" rel="previous" title="Radix-2 FFT routines for complex data">
<style type="text/css">
<!--
a.summary-letter {text-decoration: none}
blockquote.smallquotation {font-size: smaller}
div.display {margin-left: 3.2em}
div.example {margin-left: 3.2em}
div.indentedblock {margin-left: 3.2em}
div.lisp {margin-left: 3.2em}
div.smalldisplay {margin-left: 3.2em}
div.smallexample {margin-left: 3.2em}
div.smallindentedblock {margin-left: 3.2em; font-size: smaller}
div.smalllisp {margin-left: 3.2em}
kbd {font-style:oblique}
pre.display {font-family: inherit}
pre.format {font-family: inherit}
pre.menu-comment {font-family: serif}
pre.menu-preformatted {font-family: serif}
pre.smalldisplay {font-family: inherit; font-size: smaller}
pre.smallexample {font-size: smaller}
pre.smallformat {font-family: inherit; font-size: smaller}
pre.smalllisp {font-size: smaller}
span.nocodebreak {white-space:nowrap}
span.nolinebreak {white-space:nowrap}
span.roman {font-family:serif; font-weight:normal}
span.sansserif {font-family:sans-serif; font-weight:normal}
ul.no-bullet {list-style: none}
-->
</style>


</head>

<body lang="en" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000">
<a name="Mixed_002dradix-FFT-routines-for-complex-data"></a>
<div class="header">
<p>
Next: <a href="Overview-of-real-data-FFTs.html#Overview-of-real-data-FFTs" accesskey="n" rel="next">Overview of real data FFTs</a>, Previous: <a href="Radix_002d2-FFT-routines-for-complex-data.html#Radix_002d2-FFT-routines-for-complex-data" accesskey="p" rel="previous">Radix-2 FFT routines for complex data</a>, Up: <a href="Fast-Fourier-Transforms.html#Fast-Fourier-Transforms" accesskey="u" rel="up">Fast Fourier Transforms</a> &nbsp; [<a href="Function-Index.html#Function-Index" title="Index" rel="index">Index</a>]</p>
</div>
<hr>
<a name="Mixed_002dradix-FFT-routines-for-complex-data-1"></a>
<h3 class="section">16.4 Mixed-radix FFT routines for complex data</h3>
<a name="index-FFT-of-complex-data_002c-mixed_002dradix-algorithm"></a>
<a name="index-Mixed_002dradix-FFT_002c-complex-data"></a>

<p>This section describes mixed-radix FFT algorithms for complex data.  The
mixed-radix functions work for FFTs of any length.  They are a
reimplementation of Paul Swarztrauber&rsquo;s Fortran <small>FFTPACK</small> library.
The theory is explained in the review article <cite>Self-sorting
Mixed-radix FFTs</cite> by Clive Temperton.  The routines here use the same
indexing scheme and basic algorithms as <small>FFTPACK</small>.
</p>
<p>The mixed-radix algorithm is based on sub-transform modules&mdash;highly
optimized small length FFTs which are combined to create larger FFTs.
There are efficient modules for factors of 2, 3, 4, 5, 6 and 7.  The
modules for the composite factors of 4 and 6 are faster than combining
the modules for <em>2*2</em> and <em>2*3</em>.
</p>
<p>For factors which are not implemented as modules there is a fall-back to
a general length-<em>n</em> module which uses Singleton&rsquo;s method for
efficiently computing a DFT. This module is <em>O(n^2)</em>, and slower
than a dedicated module would be but works for any length <em>n</em>.  Of
course, lengths which use the general length-<em>n</em> module will still
be factorized as much as possible.  For example, a length of 143 will be
factorized into <em>11*13</em>.  Large prime factors are the worst case
scenario, e.g. as found in <em>n=2*3*99991</em>, and should be avoided
because their <em>O(n^2)</em> scaling will dominate the run-time (consult
the document <cite>GSL FFT Algorithms</cite> included in the GSL distribution
if you encounter this problem).
</p>
<p>The mixed-radix initialization function <code>gsl_fft_complex_wavetable_alloc</code>
returns the list of factors chosen by the library for a given length
<em>n</em>.  It can be used to check how well the length has been
factorized, and estimate the run-time.  To a first approximation the
run-time scales as <em>n \sum f_i</em>, where the <em>f_i</em> are the
factors of <em>n</em>.  For programs under user control you may wish to
issue a warning that the transform will be slow when the length is
poorly factorized.  If you frequently encounter data lengths which
cannot be factorized using the existing small-prime modules consult
<cite>GSL FFT Algorithms</cite> for details on adding support for other
factors.
</p>



<p>All the functions described in this section are declared in the header
file <samp>gsl_fft_complex.h</samp>.
</p>
<dl>
<dt><a name="index-gsl_005ffft_005fcomplex_005fwavetable_005falloc"></a>Function: <em>gsl_fft_complex_wavetable *</em> <strong>gsl_fft_complex_wavetable_alloc</strong> <em>(size_t <var>n</var>)</em></dt>
<dd><p>This function prepares a trigonometric lookup table for a complex FFT of
length <var>n</var>. The function returns a pointer to the newly allocated
<code>gsl_fft_complex_wavetable</code> if no errors were detected, and a null
pointer in the case of error.  The length <var>n</var> is factorized into a
product of subtransforms, and the factors and their trigonometric
coefficients are stored in the wavetable. The trigonometric coefficients
are computed using direct calls to <code>sin</code> and <code>cos</code>, for
accuracy.  Recursion relations could be used to compute the lookup table
faster, but if an application performs many FFTs of the same length then
this computation is a one-off overhead which does not affect the final
throughput.
</p>
<p>The wavetable structure can be used repeatedly for any transform of the
same length.  The table is not modified by calls to any of the other FFT
functions.  The same wavetable can be used for both forward and backward
(or inverse) transforms of a given length.
</p></dd></dl>

<dl>
<dt><a name="index-gsl_005ffft_005fcomplex_005fwavetable_005ffree"></a>Function: <em>void</em> <strong>gsl_fft_complex_wavetable_free</strong> <em>(gsl_fft_complex_wavetable * <var>wavetable</var>)</em></dt>
<dd><p>This function frees the memory associated with the wavetable
<var>wavetable</var>.  The wavetable can be freed if no further FFTs of the
same length will be needed.
</p></dd></dl>

<p>These functions operate on a <code>gsl_fft_complex_wavetable</code> structure
which contains internal parameters for the FFT.  It is not necessary to
set any of the components directly but it can sometimes be useful to
examine them.  For example, the chosen factorization of the FFT length
is given and can be used to provide an estimate of the run-time or
numerical error. The wavetable structure is declared in the header file
<samp>gsl_fft_complex.h</samp>.
</p>
<dl>
<dt><a name="index-gsl_005ffft_005fcomplex_005fwavetable"></a>Data Type: <strong>gsl_fft_complex_wavetable</strong></dt>
<dd><p>This is a structure that holds the factorization and trigonometric
lookup tables for the mixed radix fft algorithm.  It has the following
components:
</p>
<dl compact="compact">
<dt><code>size_t n</code></dt>
<dd><p>This is the number of complex data points
</p>
</dd>
<dt><code>size_t nf</code></dt>
<dd><p>This is the number of factors that the length <code>n</code> was decomposed into.
</p>
</dd>
<dt><code>size_t factor[64]</code></dt>
<dd><p>This is the array of factors.  Only the first <code>nf</code> elements are
used. 
</p>

</dd>
<dt><code>gsl_complex * trig</code></dt>
<dd><p>This is a pointer to a preallocated trigonometric lookup table of
<code>n</code> complex elements.
</p>
</dd>
<dt><code>gsl_complex * twiddle[64]</code></dt>
<dd><p>This is an array of pointers into <code>trig</code>, giving the twiddle
factors for each pass.
</p></dd>
</dl>
</dd></dl>

<p>The mixed radix algorithms require additional working space to hold
the intermediate steps of the transform.
</p>
<dl>
<dt><a name="index-gsl_005ffft_005fcomplex_005fworkspace_005falloc"></a>Function: <em>gsl_fft_complex_workspace *</em> <strong>gsl_fft_complex_workspace_alloc</strong> <em>(size_t <var>n</var>)</em></dt>
<dd><a name="index-gsl_005ffft_005fcomplex_005fworkspace"></a>
<p>This function allocates a workspace for a complex transform of length
<var>n</var>.
</p></dd></dl>

<dl>
<dt><a name="index-gsl_005ffft_005fcomplex_005fworkspace_005ffree"></a>Function: <em>void</em> <strong>gsl_fft_complex_workspace_free</strong> <em>(gsl_fft_complex_workspace * <var>workspace</var>)</em></dt>
<dd><p>This function frees the memory associated with the workspace
<var>workspace</var>. The workspace can be freed if no further FFTs of the
same length will be needed.
</p></dd></dl>


<p>The following functions compute the transform,
</p>
<dl>
<dt><a name="index-gsl_005ffft_005fcomplex_005fforward"></a>Function: <em>int</em> <strong>gsl_fft_complex_forward</strong> <em>(gsl_complex_packed_array <var>data</var>, size_t <var>stride</var>, size_t <var>n</var>, const gsl_fft_complex_wavetable * <var>wavetable</var>, gsl_fft_complex_workspace * <var>work</var>)</em></dt>
<dt><a name="index-gsl_005ffft_005fcomplex_005ftransform"></a>Function: <em>int</em> <strong>gsl_fft_complex_transform</strong> <em>(gsl_complex_packed_array <var>data</var>, size_t <var>stride</var>, size_t <var>n</var>, const gsl_fft_complex_wavetable * <var>wavetable</var>, gsl_fft_complex_workspace * <var>work</var>, gsl_fft_direction <var>sign</var>)</em></dt>
<dt><a name="index-gsl_005ffft_005fcomplex_005fbackward"></a>Function: <em>int</em> <strong>gsl_fft_complex_backward</strong> <em>(gsl_complex_packed_array <var>data</var>, size_t <var>stride</var>, size_t <var>n</var>, const gsl_fft_complex_wavetable * <var>wavetable</var>, gsl_fft_complex_workspace * <var>work</var>)</em></dt>
<dt><a name="index-gsl_005ffft_005fcomplex_005finverse"></a>Function: <em>int</em> <strong>gsl_fft_complex_inverse</strong> <em>(gsl_complex_packed_array <var>data</var>, size_t <var>stride</var>, size_t <var>n</var>, const gsl_fft_complex_wavetable * <var>wavetable</var>, gsl_fft_complex_workspace * <var>work</var>)</em></dt>
<dd>
<p>These functions compute forward, backward and inverse FFTs of length
<var>n</var> with stride <var>stride</var>, on the packed complex array
<var>data</var>, using a mixed radix decimation-in-frequency algorithm.
There is no restriction on the length <var>n</var>.  Efficient modules are
provided for subtransforms of length 2, 3, 4, 5, 6 and 7.  Any remaining
factors are computed with a slow, <em>O(n^2)</em>, general-<em>n</em>
module. The caller must supply a <var>wavetable</var> containing the
trigonometric lookup tables and a workspace <var>work</var>.  For the
<code>transform</code> version of the function the <var>sign</var> argument can be
either <code>forward</code> (<em>-1</em>) or <code>backward</code> (<em>+1</em>).
</p>
<p>The functions return a value of <code>0</code> if no errors were detected. The
following <code>gsl_errno</code> conditions are defined for these functions:
</p>
<dl compact="compact">
<dt><code>GSL_EDOM</code></dt>
<dd><p>The length of the data <var>n</var> is not a positive integer (i.e. <var>n</var>
is zero).
</p>
</dd>
<dt><code>GSL_EINVAL</code></dt>
<dd><p>The length of the data <var>n</var> and the length used to compute the given
<var>wavetable</var> do not match.
</p></dd>
</dl>
</dd></dl>


<p>Here is an example program which computes the FFT of a short pulse in a
sample of length 630 (<em>=2*3*3*5*7</em>) using the mixed-radix
algorithm.
</p>
<div class="example">
<pre class="verbatim">#include &lt;stdio.h&gt;
#include &lt;math.h&gt;
#include &lt;gsl/gsl_errno.h&gt;
#include &lt;gsl/gsl_fft_complex.h&gt;

#define REAL(z,i) ((z)[2*(i)])
#define IMAG(z,i) ((z)[2*(i)+1])

int
main (void)
{
  int i;
  const int n = 630;
  double data[2*n];

  gsl_fft_complex_wavetable * wavetable;
  gsl_fft_complex_workspace * workspace;

  for (i = 0; i &lt; n; i++)
    {
      REAL(data,i) = 0.0;
      IMAG(data,i) = 0.0;
    }

  data[0] = 1.0;

  for (i = 1; i &lt;= 10; i++)
    {
      REAL(data,i) = REAL(data,n-i) = 1.0;
    }

  for (i = 0; i &lt; n; i++)
    {
      printf (&quot;%d: %e %e\n&quot;, i, REAL(data,i), 
                                IMAG(data,i));
    }
  printf (&quot;\n&quot;);

  wavetable = gsl_fft_complex_wavetable_alloc (n);
  workspace = gsl_fft_complex_workspace_alloc (n);

  for (i = 0; i &lt; (int) wavetable-&gt;nf; i++)
    {
       printf (&quot;# factor %d: %zu\n&quot;, i, 
               wavetable-&gt;factor[i]);
    }

  gsl_fft_complex_forward (data, 1, n, 
                           wavetable, workspace);

  for (i = 0; i &lt; n; i++)
    {
      printf (&quot;%d: %e %e\n&quot;, i, REAL(data,i), 
                                IMAG(data,i));
    }

  gsl_fft_complex_wavetable_free (wavetable);
  gsl_fft_complex_workspace_free (workspace);
  return 0;
}
</pre></div>

<p>Note that we have assumed that the program is using the default
<code>gsl</code> error handler (which calls <code>abort</code> for any errors).  If
you are not using a safe error handler you would need to check the
return status of all the <code>gsl</code> routines.
</p>
<hr>
<div class="header">
<p>
Next: <a href="Overview-of-real-data-FFTs.html#Overview-of-real-data-FFTs" accesskey="n" rel="next">Overview of real data FFTs</a>, Previous: <a href="Radix_002d2-FFT-routines-for-complex-data.html#Radix_002d2-FFT-routines-for-complex-data" accesskey="p" rel="previous">Radix-2 FFT routines for complex data</a>, Up: <a href="Fast-Fourier-Transforms.html#Fast-Fourier-Transforms" accesskey="u" rel="up">Fast Fourier Transforms</a> &nbsp; [<a href="Function-Index.html#Function-Index" title="Index" rel="index">Index</a>]</p>
</div>



</body>
</html>