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 |