Rev Author Line No. Line
178 kaklik 1 #ifndef __FFTW_H
2 #define __FFTW_H
3  
4 #include <boost/multi_array.hpp>
5 #include <complex>
6 #include <functional>
7  
8 namespace mimas {
9  
10 /** @defgroup fourierTransforms Fourier transformations using boost::multi_array
11 Several functions offered by the fftw3 library are wrapped using
12 \c boost::multi_array.
13 There are several types of fourier-transforms. The current implementation
14 only allows fourier-transforms on double precision numbers.
15 \li \c fft is the complex-to-complex fourier transform.
16 \li \c invfft is the inverse complex-to-complex fourier transform.
17 \li \c rfft is the real-to-complex fourier transform (last dimension
18 of input-array must be even).
19 \li \c invrfft is the inverse real-to-complex fourier transform.
20  
21 The real-to-complex fourier transform will result in an array of about
22 half the size, because the fourier transform of a real function always is
23 symmetric:
24 \f$\mathrm{mm\_rfft}:\mathbf{R}^{n_1\times n_2\times\ldots n_d}\rightarrow
25 \mathbf{C}^{n_1\times n_2\times\ldots (n_d/2+1)}\f$
26  
27 \include fftw/main.cc
28  
29 Have a look at the <A HREF="info:/fftw">fftw info-pages</A>.
30 Also see <A HREF="http://www.fftw.org">fftw docs</A> and
31 <A HREF="http://www.cs.rug.nl/~cosmin/tip/">TiP-0.0.1</A>.
32 @author Bala Amavasai (bpa@amavasai.org)
33 @author Jan Wedekind (jan@wedesoft.de)
34 @date Wed Aug 04 22:48:27 UTC 2004
35 @{ */
36 /** Discrete fourier transform using fftw.
37 @see fft */
38 template< typename Real, std::size_t Dim, typename TPtr >
39 struct fft_t:
40 public std::unary_function< boost::const_multi_array_ref< std::complex< Real >, Dim, TPtr >,
41 boost::multi_array< std::complex< Real >, Dim > >
42 {
43 ///
44 boost::multi_array< std::complex< Real >, Dim > operator()
45 ( const boost::const_multi_array_ref< std::complex< Real >, Dim, TPtr > &field );
46 };
47  
48 /** Discrete fourier transform of boost::multi_array.
49 @see fft_t */
50 template< typename Real, std::size_t Dim, typename TPtr >
51 boost::multi_array< std::complex< Real >, Dim >
52 fft( const boost::const_multi_array_ref< std::complex< Real >, Dim, TPtr > &field )
53 {
54 return fft_t< Real, Dim, TPtr >()( field );
55 }
56  
57 /** Inverse discrete fourier transform using fftw.
58 @see invfft */
59 template< typename Real, std::size_t Dim, typename TPtr >
60 struct invfft_t:
61 public std::unary_function< boost::const_multi_array_ref< std::complex< Real >, Dim, TPtr >,
62 boost::multi_array< std::complex< Real >, Dim > >
63 {
64 boost::multi_array< std::complex< Real >, Dim > operator()
65 ( const boost::const_multi_array_ref< std::complex< Real >, Dim, TPtr > &field );
66 };
67  
68 /** Inverse discrete fourier transform of boost::multi_array.
69 @see invfft_t */
70 template< typename Real, std::size_t Dim, typename TPtr >
71 boost::multi_array< std::complex< Real >, Dim >
72 invfft( const boost::const_multi_array_ref< std::complex< Real >, Dim, TPtr > &field )
73 {
74 return invfft_t< Real, Dim, TPtr >()( field );
75 }
76  
77 /** Discrete fourier transform of real values using fftw.
78 The fourier transform of a real (multidimensional) function is
79 point-symmetric. Thus it is sufficient to compute only half of the
80 values of the corresponding discrete fourier transform.
81  
82 If the input array is an element of \f$\mathbf{R}^{n_1\times n_2\times
83 \ldots\times n_d}\f$, then the result will be element of
84 \f$\mathbf{C}^{n_1\times n_2\times\ldots\times (n_d/2+1)}\f$.
85  
86 In this implementation \f$n_d\f$ always must be even, so that no additional
87 information for a later inverse transform is required!
88 @see rfft */
89 template< typename Real, std::size_t Dim, typename TPtr >
90 struct rfft_t:
91 public std::unary_function< boost::const_multi_array_ref< Real, Dim, TPtr >,
92 boost::multi_array< std::complex< Real >, Dim > >
93 {
94 ///
95 boost::multi_array< std::complex< Real >, Dim > operator()
96 ( const boost::const_multi_array_ref< Real, Dim, TPtr > &field );
97 };
98  
99 /** Discrete fourier transform of real-valued boost::multi_array.
100 @see rfft_t */
101 template< typename Real, std::size_t Dim, typename TPtr >
102 boost::multi_array< std::complex< Real >, Dim >
103 rfft( const boost::const_multi_array_ref< Real, Dim, TPtr > &field )
104 {
105 return rfft_t< Real, Dim, TPtr >()( field );
106 }
107  
108  
109 /** Inverse discrete fourier transform of symmetric complex array using fftw.
110 The fourier transform of a real (multidimensional) function is
111 point-symmetric. Thus it is sufficient to compute only half of the
112 values of the corresponding discrete fourier transform.
113  
114 If the input array is an element of \f$\mathbf{C}^{n_1\times n_2\times
115 \ldots\times n_d}\f$, then the result will be element of
116 \f$\mathbf{R}^{n_1\times n_2\times\ldots\times (n_d-1)*2)}\f$.
117  
118 In this implementation the nth dimension of the resulting array is assumed
119 to be even!
120 @see invrfft */
121 template< typename Real, std::size_t Dim, typename TPtr >
122 struct invrfft_t:
123 public std::unary_function< boost::const_multi_array_ref< std::complex< Real >, Dim, TPtr >,
124 boost::multi_array< Real, Dim > >
125 {
126 boost::multi_array< Real, Dim > operator()
127 ( const boost::const_multi_array_ref< std::complex< Real >, Dim, TPtr > &field );
128 };
129  
130 /** Inverse discrete fourier resulting in real-valued boost::multi_array.
131 @see invrfft_t */
132 template< typename Real, std::size_t Dim, typename TPtr >
133 boost::multi_array< Real, Dim >
134 invrfft( const boost::const_multi_array_ref< std::complex< Real >, Dim, TPtr > &field )
135 {
136 return invrfft_t< Real, Dim, TPtr >()( field );
137 }
138  
139 ///@}
140  
141 };
142  
143 #include "fourier.tcc"
144  
145 #endif