LAL  7.5.0.1-b72065a
RealFFT.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2007 Jolien Creighton, Kipp Cannon, Josh Willis
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with with program; see the file COPYING. If not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 */
19 
20 #include <config.h>
21 
22 #include <complex.h>
23 #include <fftw3.h>
24 #include <string.h>
25 
26 #include <lal/LALDatatypes.h>
27 #include <lal/FFTWMutex.h>
28 #include <lal/LALConfig.h> /* Needed to know whether aligning memory */
29 #include <lal/LALMalloc.h>
30 #include <lal/RealFFT.h>
31 #include <lal/SeqFactories.h>
32 #include <lal/XLALError.h>
33 
34 /**
35  * \addtogroup RealFFT_h
36  *
37  * ## LAL-style functions [DEPRECATED] ##
38  *
39  * This package also provides a (deprecated!) LAL-style interface with the FFTW fast Fourier
40  * transform package \cite fj_1998 .
41  *
42  * The routines LALCreateForwardRealFFTPlan() and
43  * LALCreateReverseRealFFTPlan() create plans for computing the
44  * forward (real-to-complex) and reverse (complex-to-real) FFTs of a specified
45  * size. The optimum plan is either estimated (reasonably fast) if the measure
46  * flag is zero, or measured (can be time-consuming, but gives better
47  * performance) if the measure flag is non-zero. The routine
48  * LALDestroyRealFFTPlan() destroys any of these flavours of plans.
49  *
50  * The routines LALForwardRealFFT() and LALReverseRealFFT()
51  * perform the forward (real-to-complex) and reverse (complex-to-real) FFTs
52  * using the plans. The discrete Fourier transform \f$H_k\f$,
53  * \f$k=0\ldots\lfloor{n/2}\rfloor\f$ (\f$n/2\f$ rounded down), of a vector \f$h_j\f$,
54  * \f$j=0\ldots n-1\f$, of length \f$n\f$ is defined by
55  * \f[
56  * H_k = \sum_{j=0}^{n-1} h_j e^{-2\pi ijk/n}
57  * \f]
58  * and, similarly, the \e inverse Fourier transform is defined by
59  * \f[
60  * h_j = \frac{1}{n} \sum_{k=0}^{n-1} H_k e^{2\pi ijk/n}
61  * \f]
62  * where \f$H_k\f$ for \f$\lfloor{n/2}\rfloor<k<n\f$ can be obtained from the relation
63  * \f$H_k=H_{n-k}^\ast\f$. The present implementation of the \e reverse FFT
64  * omits the factor of \f$1/n\f$.
65  *
66  * The routines in this package require that the vector \f$h_j\f$, \f$j=0\ldots n-1\f$
67  * be real; consequently, \f$H_k=H_{n-k}^\ast\f$ (\f$0\le k\le\lfloor n/2\rfloor\f$),
68  * i.e., the negative frequency Fourier components are the complex conjugate of
69  * the positive frequency Fourier components when the data is real. Therefore,
70  * one need compute and store only the first \f$\lfloor n/2\rfloor+1\f$ components
71  * of \f$H_k\f$; only the values of \f$H_k\f$ for \f$k=0\ldots \lfloor n/2\rfloor\f$ are
72  * returned (integer division is rounded down, e.g., \f$\lfloor 7/2\rfloor=3\f$).
73  *
74  * The routine LALRealPowerSpectrum() computes the power spectrum
75  * \f$P_k=2|H_k|^2\f$, \f$k=1\ldots \lfloor (n-1)/2\rfloor\f$,
76  * \f$P_0=|H_0|^2\f$, and \f$P_{n/2}=|H_{n/2}|^2\f$ if \f$n\f$ is even, of the data \f$h_j\f$,
77  * \f$j=0\ldots n-1\f$. The factor of two except at DC and Nyquist accounts for
78  * the power in negative frequencies.
79  *
80  * The routine LALREAL4VectorFFT() is essentially a direct calls to
81  * FFTW routines without any re-packing of the data. This routine should not
82  * be used unless the user understands the packing used in FFTW.
83  *
84  * ### Operating Instructions ###
85  *
86  * \code
87  * const UINT4 n = 32;
88  * static LALStatus status;
89  * RealFFTPlan *pfwd = NULL;
90  * RealFFTPlan *prev = NULL;
91  * REAL4Vector *hvec = NULL;
92  * COMPLEX8Vector *Hvec = NULL;
93  * REAL4Vector *Pvec = NULL;
94  *
95  * LALCreateForwardRealFFTPlan( &status, &pfwd, n );
96  * LALCreateReverseRealFFTPlan( &status, &prev, n );
97  * LALSCreateVector( &status, &hvec, n );
98  * LALCCreateVector( &status, &Hvec, n/2 + 1 );
99  * LALSCreateVector( &status, &Pvec, n/2 + 1 );
100  *
101  * <assign data>
102  *
103  * LALRealPowerSpectrum( &status, Pvec, hvec, pfwd );
104  * LALForwardRealFFT( &status, Hvec, hvec, pfwd );
105  * LALReverseRealFFT( &status, hvec, Hvec, pinv );
106  *
107  * LALDestroyRealFFTPlan( &status, &pfwd );
108  * LALDestroyRealFFTPlan( &status, &pinv );
109  * LALSDestroyVector( &status, &hvec );
110  * LALCDestroyVector( &status, &Hvec );
111  * LALSDestroyVector( &status, &Pvec );
112  * \endcode
113  *
114  * ### Algorithm ###
115  *
116  * The FFTW \cite fj_1998 is used.
117  *
118  * ### Uses ###
119  *
120  *
121  * ### Notes ###
122  *
123  * <ol>
124  * <li> The sign convention used here is the opposite of
125  * <em>Numerical Recipes</em> \cite ptvf1992 , but agrees with the one used
126  * by FFTW \cite fj_1998 and the other LIGO software components.
127  * </li>
128  * <li> The result of the reverse FFT must be multiplied by \f$1/n\f$ to recover
129  * the original vector. This is unlike the <em>Numerical
130  * Recipes</em> \cite ptvf1992 convension where the factor is \f$2/n\f$ for real
131  * FFTs. This is different from the \c datacondAPI where the
132  * normalization constant is applied by default.
133  * </li>
134  * <li> The size \f$n\f$ of the transform can be any positive integer; the
135  * performance is \f$O(n\log n)\f$. However, better performance is obtained if \f$n\f$
136  * is the product of powers of 2, 3, 5, 7, and zero or one power of either 11
137  * or 13. Transforms when \f$n\f$ is a power of 2 are especially fast. See
138  * \cite fj_1998 .
139  * </li>
140  * <li> All of these routines leave the input array undamaged. (Except for LALREAL4VectorFFT().)
141  * </li>
142  * <li> LALMalloc() is used by all the fftw routines.
143  * </li>
144  * </ol>
145  *
146  */
147 /** @{ */
148 
149 /**
150  * \brief Plan to perform FFT of REAL4 data.
151  */
152 struct
154 {
155  INT4 sign; /**< sign in transform exponential, -1 for forward, +1 for reverse */
156  UINT4 size; /**< length of the real data vector for this plan */
157  fftwf_plan plan; /**< the FFTW plan */
158 };
159 
160 /**
161  * \brief Plan to perform FFT of REAL8 data.
162  */
163 struct
165 {
166  INT4 sign; /**< sign in transform exponential, -1 for forward, +1 for reverse */
167  UINT4 size; /**< length of the real data vector for this plan */
168  fftw_plan plan; /**< the FFTW plan */
169 };
170 
171 
172 
173 /* single- and double-precision routines */
174 
175 #define SINGLE_PRECISION
176 #include "RealFFT_source.c"
177 #undef SINGLE_PRECISION
178 #include "RealFFT_source.c"
179 
180 /** @} */
static int sign(int s)
Definition: LALStringTest.c:27
uint32_t UINT4
Four-byte unsigned integer.
int32_t INT4
Four-byte signed integer.
Plan to perform FFT of REAL4 data.
Definition: CudaRealFFT.c:40
fftwf_plan plan
the FFTW plan
Definition: RealFFT.c:157
Plan to perform FFT of REAL8 data.
Definition: CudaRealFFT.c:50