1%perlcode %{
2@EXPORT_complex = qw/
3               gsl_fft_complex_radix2_forward
4               gsl_fft_complex_radix2_backward
5               gsl_fft_complex_radix2_inverse
6               gsl_fft_complex_radix2_transform
7               gsl_fft_complex_radix2_dif_forward
8               gsl_fft_complex_radix2_dif_backward
9               gsl_fft_complex_radix2_dif_inverse
10               gsl_fft_complex_radix2_dif_transform
11               gsl_fft_complex_wavetable_alloc
12               gsl_fft_complex_wavetable_free
13               gsl_fft_complex_workspace_alloc
14               gsl_fft_complex_workspace_free
15               gsl_fft_complex_memcpy
16               gsl_fft_complex_forward
17               gsl_fft_complex_backward
18               gsl_fft_complex_inverse
19               gsl_fft_complex_transform
20               /;
21@EXPORT_halfcomplex = qw/
22               gsl_fft_halfcomplex_radix2_backward
23               gsl_fft_halfcomplex_radix2_inverse
24               gsl_fft_halfcomplex_radix2_transform
25               gsl_fft_halfcomplex_wavetable_alloc
26               gsl_fft_halfcomplex_wavetable_free
27               gsl_fft_halfcomplex_backward
28               gsl_fft_halfcomplex_inverse
29               gsl_fft_halfcomplex_transform
30               gsl_fft_halfcomplex_unpack
31               gsl_fft_halfcomplex_radix2_unpack
32               /;
33@EXPORT_real = qw/
34               gsl_fft_real_radix2_transform
35               gsl_fft_real_wavetable_alloc
36               gsl_fft_real_wavetable_free
37               gsl_fft_real_workspace_alloc
38               gsl_fft_real_workspace_free
39               gsl_fft_real_transform
40               gsl_fft_real_unpack
41             /;
42@EXPORT_vars = qw/
43                $gsl_fft_forward
44                $gsl_fft_backward
45                /;
46@EXPORT_OK =   (
47                @EXPORT_real,
48                @EXPORT_complex,
49                @EXPORT_halfcomplex,
50                @EXPORT_vars,
51                );
52%EXPORT_TAGS = (
53                all         => \@EXPORT_OK,
54                real        => \@EXPORT_real,
55                complex     => \@EXPORT_complex,
56                halfcomplex => \@EXPORT_halfcomplex,
57                vars        => \@EXPORT_vars,
58               );
59__END__
60
61=encoding utf8
62
63=head1 NAME
64
65Math::GSL::FFT - Fast Fourier Transforms (FFT)
66
67=head1 SYNOPSIS
68
69    use Math::GSL::FFT qw /:all/;
70    my $input1              = [ 0 .. 7 ];
71    my $N1                  = @$input1;
72    my ($status1, $output1) = gsl_fft_real_radix2_transform ($input, 1, $N1);
73    my ($status2, $output2) = gsl_fft_halfcomplex_radix2_inverse($output2, 1, $N1);
74    # $input1 == $output2
75
76    my $input2              = [ 0 .. 6 ];
77    my $N2                  = @$input;
78    my $workspace1          = gsl_fft_real_workspace_alloc($N2);
79    my $wavetable1          = gsl_fft_real_wavetable_alloc($N2);
80    my ($status3,$output3)  = gsl_fft_real_transform ($input, 1, $N2, $wavetable1, $workspace1);
81    my $wavetable4          = gsl_fft_halfcomplex_wavetable_alloc($N2);
82    my $workspace4          = gsl_fft_real_workspace_alloc($N2);
83    my ($status4,$output4)  = gsl_fft_halfcomplex_inverse($output, 1, $N2, $wavetable4, $workspace4);
84
85    # $input2 == $output4
86
87=head1 DESCRIPTION
88
89=over
90
91=item * C<gsl_fft_complex_radix2_forward($data, $stride, $n) >
92
93This function computes the forward FFTs of length $n with stride $stride, on
94the array reference $data using an in-place radix-2 decimation-in-time
95algorithm. The length of the transform $n is restricted to powers of two. For
96the transform version of the function the sign argument can be either forward
97(-1) or backward (+1). The functions return a value of $GSL_SUCCESS if no
98errors were detected, or $GSL_EDOM if the length of the data $n is not a power
99of two.
100
101=item * C<gsl_fft_complex_radix2_backward >
102
103=item * C<gsl_fft_complex_radix2_inverse >
104
105=item * C<gsl_fft_complex_radix2_transform >
106
107=item * C<gsl_fft_complex_radix2_dif_forward >
108
109=item * C<gsl_fft_complex_radix2_dif_backward >
110
111=item * C<gsl_fft_complex_radix2_dif_inverse >
112
113=item * C<gsl_fft_complex_radix2_dif_transform >
114
115=item * C<gsl_fft_complex_wavetable_alloc($n)>
116
117This function prepares a trigonometric lookup table for a complex FFT of length
118$n. The function returns a pointer to the newly allocated
119gsl_fft_complex_wavetable if no errors were detected, and a null pointer in the
120case of error. The length $n is factorized into a product of subtransforms, and
121the factors and their trigonometric coefficients are stored in the wavetable.
122The trigonometric coefficients are computed using direct calls to sin and cos,
123for accuracy. Recursion relations could be used to compute the lookup table
124faster, but if an application performs many FFTs of the same length then this
125computation is a one-off overhead which does not affect the final throughput.
126The wavetable structure can be used repeatedly for any transform of the same
127length. The table is not modified by calls to any of the other FFT functions.
128The same wavetable can be used for both forward and backward (or inverse)
129transforms of a given length.
130
131=item * C<gsl_fft_complex_wavetable_free($wavetable)>
132
133This function frees the memory associated with the wavetable $wavetable. The
134wavetable can be freed if no further FFTs of the same length will be needed.
135
136=item * C<gsl_fft_complex_workspace_alloc($n)>
137
138This function allocates a workspace for a complex transform of length $n.
139
140=item * C<gsl_fft_complex_workspace_free($workspace) >
141
142This function frees the memory associated with the workspace $workspace. The
143workspace can be freed if no further FFTs of the same length will be needed.
144
145=item * C<gsl_fft_complex_memcpy >
146
147=item * C<gsl_fft_complex_forward >
148
149=item * C<gsl_fft_complex_backward >
150
151=item * C<gsl_fft_complex_inverse >
152
153=item * C<gsl_fft_complex_transform >
154
155=item * C<gsl_fft_halfcomplex_radix2_backward($data, $stride, $n)>
156
157This function computes the backwards in-place radix-2 FFT of length $n and
158stride $stride on the half-complex sequence data stored according the output
159scheme used by gsl_fft_real_radix2. The result is a real array stored in
160natural order.
161
162=item * C<gsl_fft_halfcomplex_radix2_inverse($data, $stride, $n)>
163
164This function computes the inverse in-place radix-2 FFT of length $n and stride
165$stride on the half-complex sequence data stored according the output scheme
166used by gsl_fft_real_radix2. The result is a real array stored in natural
167order.
168
169=item * C<gsl_fft_halfcomplex_radix2_transform>
170
171=item * C<gsl_fft_halfcomplex_wavetable_alloc($n)>
172
173This function prepares trigonometric lookup tables for an FFT of size $n real
174elements. The functions return a pointer to the newly allocated struct if no
175errors were detected, and a null pointer in the case of error. The length $n is
176factorized into a product of subtransforms, and the factors and their
177trigonometric coefficients are stored in the wavetable. The trigonometric
178coefficients are computed using direct calls to sin and cos, for accuracy.
179Recursion relations could be used to compute the lookup table faster, but if an
180application performs many FFTs of the same length then computing the wavetable
181is a one-off overhead which does not affect the final throughput.  The
182wavetable structure can be used repeatedly for any transform of the same
183length. The table is not modified by calls to any of the other FFT functions.
184The appropriate type of wavetable must be used for forward real or inverse
185half-complex transforms.
186
187=item * C<gsl_fft_halfcomplex_wavetable_free($wavetable)>
188
189This function frees the memory associated with the wavetable $wavetable. The
190wavetable can be freed if no further FFTs of the same length will be needed.
191
192=item * C<gsl_fft_halfcomplex_backward >
193
194=item * C<gsl_fft_halfcomplex_inverse >
195
196=item * C<gsl_fft_halfcomplex_transform >
197
198=item * C<gsl_fft_halfcomplex_unpack >
199
200=item * C<gsl_fft_halfcomplex_radix2_unpack >
201
202=item * C<gsl_fft_real_radix2_transform($data, $stride, $n) >
203
204This function computes an in-place radix-2 FFT of length $n and stride $stride
205on the real array reference $data. The output is a half-complex sequence, which
206is stored in-place. The arrangement of the half-complex terms uses the
207following scheme: for k < N/2 the real part of the k-th term is stored in
208location k, and the corresponding imaginary part is stored in location N-k.
209Terms with k > N/2 can be reconstructed using the symmetry z_k = z^*_{N-k}. The
210terms for k=0 and k=N/2 are both purely real, and count as a special case.
211Their real parts are stored in locations 0 and N/2 respectively, while their
212imaginary parts which are zero are not stored. The following table shows the
213correspondence between the output data and the equivalent results obtained by
214considering the input data as a complex sequence with zero imaginary part,
215
216          complex[0].real    =    data[0]
217          complex[0].imag    =    0
218          complex[1].real    =    data[1]
219          complex[1].imag    =    data[N-1]
220          ...............         ................
221          complex[k].real    =    data[k]
222          complex[k].imag    =    data[N-k]
223          ...............         ................
224          complex[N/2].real  =    data[N/2]
225          complex[N/2].imag  =    0
226          ...............         ................
227          complex[k'].real   =    data[k]        k' = N - k
228          complex[k'].imag   =   -data[N-k]
229          ...............         ................
230          complex[N-1].real  =    data[1]
231          complex[N-1].imag  =   -data[N-1]
232
233=for notyou #'
234
235Note that the output data can be converted into the full complex sequence using
236the function gsl_fft_halfcomplex_unpack.
237
238=item * C<gsl_fft_real_wavetable_alloc($n)>
239
240This function prepares trigonometric lookup tables for an FFT of size $n real
241elements. The functions return a pointer to the newly allocated struct if no
242errors were detected, and a null pointer in the case of error. The length $n is
243factorized into a product of subtransforms, and the factors and their
244trigonometric coefficients are stored in the wavetable. The trigonometric
245coefficients are computed using direct calls to sin and cos, for accuracy.
246Recursion relations could be used to compute the lookup table faster, but if an
247application performs many FFTs of the same length then computing the wavetable
248is a one-off overhead which does not affect the final throughput.  The
249wavetable structure can be used repeatedly for any transform of the same
250length. The table is not modified by calls to any of the other FFT functions.
251The appropriate type of wavetable must be used for forward real or inverse
252half-complex transforms.
253
254=item * C<gsl_fft_real_wavetable_free($wavetable)>
255
256This function frees the memory associated with the wavetable $wavetable. The
257wavetable can be freed if no further FFTs of the same length will be needed.
258
259=item * C<gsl_fft_real_workspace_alloc($n)>
260
261This function allocates a workspace for a real transform of length $n. The same
262workspace can be used for both forward real and inverse halfcomplex transforms.
263
264=item * C<gsl_fft_real_workspace_free($workspace)>
265
266This function frees the memory associated with the workspace $workspace. The
267workspace can be freed if no further FFTs of the same length will be needed.
268
269=item * C<gsl_fft_real_transform >
270
271=item * C<gsl_fft_real_unpack >
272
273=back
274
275This module also includes the following constants :
276
277=over
278
279=item * C<$gsl_fft_forward>
280
281=item * C<$gsl_fft_backward>
282
283=back
284
285For more informations on the functions, we refer you to the GSL official
286documentation: L<http://www.gnu.org/software/gsl/manual/html_node/>
287
288
289
290
291=head1 AUTHORS
292
293Jonathan "Duke" Leto <jonathan@leto.net> and Thierry Moisan <thierry.moisan@gmail.com>
294
295=head1 COPYRIGHT AND LICENSE
296
297Copyright (C) 2008-2021 Jonathan "Duke" Leto and Thierry Moisan
298
299This program is free software; you can redistribute it and/or modify it
300under the same terms as Perl itself.
301
302=cut
303
304%}
305