00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef eman_emfft_h__
00037 #define eman_emfft_h__
00038
00039 #ifdef FFTW2
00040
00041 #include <srfftw.h>
00042 namespace EMAN
00043 {
00046 class EMfft
00047 {
00048 public:
00049 static int real_to_complex_1d(float *real_data, float *complex_data, int n);
00050 static int complex_to_real_1d(float *complex_data, float *real_data, int n);
00051 static int complex_to_complex_1d(float *complex_data_in, float *complex_data_out, int n);
00052 static int real_to_complex_nd(float *real_data, float *complex_data, int nx, int ny,
00053 int nz);
00054 static int complex_to_real_nd(float *complex_data, float *real_data, int nx, int ny,
00055 int nz);
00056 static int complex_to_complex_nd(float *complex_data_in, float *complex_data_out, int nx, int ny,
00057 int nz);
00058 private:
00059 #ifdef FFTW_PLAN_CACHING
00060 #define EMFFTW2_ND_CACHE_SIZE 20
00061 #define EMFFTW2_1D_CACHE_SIZE 20
00062 static const int EMAN2_REAL_2_COMPLEX;
00063 static const int EMAN2_COMPLEX_2_REAL;
00064 static const int EMAN2_FFTW2_INPLACE;
00065 static const int EMAN2_FFTW2_OUT_OF_PLACE;
00076 class EMfftw2_cache_nd
00077 {
00078 public:
00079 EMfftw2_cache_nd();
00080 ~EMfftw2_cache_nd();
00081
00093 rfftwnd_plan get_plan(const int rank, const int x, const int y, const int z, const int r2c_flag, int ip_flag);
00094 private:
00095
00096 void debug_plans();
00097
00098
00099 int num_plans;
00100
00101
00102 int rank[EMFFTW2_ND_CACHE_SIZE];
00103
00104 int plan_dims[EMFFTW2_ND_CACHE_SIZE][3];
00105
00106 int r2c[EMFFTW2_ND_CACHE_SIZE];
00107
00108 int ip[EMFFTW2_ND_CACHE_SIZE];
00109
00110 rfftwnd_plan rfftwnd_plans[EMFFTW2_ND_CACHE_SIZE];
00111 };
00112
00122 class EMfftw2_cache_1d
00123 {
00124 public:
00125 EMfftw2_cache_1d();
00126 ~EMfftw2_cache_1d();
00127
00134 rfftw_plan get_plan(const int x, const int r2c_flag);
00135 private:
00136
00137 void debug_plans();
00138
00139
00140 int num_plans;
00141
00142
00143 int plan_dims[EMFFTW2_1D_CACHE_SIZE];
00144
00145 int r2c[EMFFTW2_1D_CACHE_SIZE];
00146
00147 rfftw_plan rfftw1d_plans[EMFFTW2_1D_CACHE_SIZE];
00148 };
00149
00150 static EMfftw2_cache_nd plan_nd_cache;
00151 static EMfftw2_cache_1d plan_1d_cache;
00152 #endif
00153 };
00154 }
00155 #endif //FFTW2
00156
00157 #ifdef FFTW3
00158
00159 #include <fftw3.h>
00160
00161 namespace EMAN
00162 {
00165 class EMfft
00166 {
00167 public:
00168 static int real_to_complex_1d(float *real_data, float *complex_data, int n);
00169 static int complex_to_real_1d(float *complex_data, float *real_data, int n);
00170 static int complex_to_complex_1d(float *in, float *out, int n);
00171 static int real_to_complex_nd(float *real_data, float *complex_data, int nx, int ny,
00172 int nz);
00173 static int complex_to_real_nd(float *complex_data, float *real_data, int nx, int ny,
00174 int nz);
00175 static int complex_to_complex_nd(float *complex_data_in, float *complex_data_out, int nx,int ny,int nz);
00176 private:
00177 #ifdef FFTW_PLAN_CACHING
00178 #define EMFFTW3_CACHE_SIZE 20
00179 static const int EMAN2_REAL_2_COMPLEX;
00180 static const int EMAN2_COMPLEX_2_REAL;
00181 static const int EMAN2_FFTW2_INPLACE;
00182 static const int EMAN2_FFTW2_OUT_OF_PLACE;
00194 class EMfftw3_cache
00195 {
00196 public:
00197 EMfftw3_cache();
00198 ~EMfftw3_cache();
00199
00213 fftwf_plan get_plan(const int rank, const int x, const int y, const int z, const int r2c_flag,const int ip_flag, fftwf_complex* complex_data, float* real_data);
00214 private:
00215
00216 void debug_plans();
00217
00218
00219 int num_plans;
00220
00221
00222 int rank[EMFFTW3_CACHE_SIZE];
00223
00224 int plan_dims[EMFFTW3_CACHE_SIZE][3];
00225
00226 int r2c[EMFFTW3_CACHE_SIZE];
00227
00228 fftwf_plan fftwplans[EMFFTW3_CACHE_SIZE];
00229
00230 int ip[EMFFTW3_CACHE_SIZE];
00231
00232 };
00233
00234 static EMfftw3_cache plan_cache;
00235 #endif
00236 };
00237 }
00238 #endif //FFTW3
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 #ifdef NATIVE_FFT
00261 namespace EMAN
00262 {
00265 class EMfft
00266 {
00267 public:
00268 static int real_to_complex_1d(float *real_data, float *complex_data, int n);
00269 static int complex_to_real_1d(float *complex_data, float *real_data, int n);
00270
00271 static int real_to_complex_nd(float *real_data, float *complex_data, int nx, int ny, int nz);
00272 static int complex_to_real_nd(float *complex_data, float *real_data, int nx, int ny, int nz);
00273 };
00274 }
00275 #endif //NATIVE_FFT
00276
00277 #ifdef ACML
00278 #include <acml.h>
00279 #include <functional>
00280
00281 namespace EMAN
00282 {
00285 class EMfft
00286 {
00287 public:
00288 static int real_to_complex_1d(float *real_data, float *complex_data, int n);
00289 static int complex_to_real_1d(float *complex_data, float *real_data, int n);
00290
00291 static int real_to_complex_nd(float *real_data, float *complex_data, int nx, int ny, int nz);
00292 static int complex_to_real_nd(float *complex_data, float *real_data, int nx, int ny, int nz);
00293
00294 private:
00295 static int real_to_complex_2d(float *real_data, float *complex_data, int nx, int ny);
00296 static int complex_to_real_2d(float *complex_data, float *real_data, int nx, int ny);
00297 static int real_to_complex_3d(float *real_data, float *complex_data, int nx, int ny, int nz);
00298 static int complex_to_real_3d(float *complex_data, float *real_data, int nx, int ny, int nz);
00299
00300 class time_sqrt_n : public std::unary_function<float, float> {
00301 public:
00302 time_sqrt_n(int n) : n_(n), factor(sqrt(float(n_))) {}
00303 float operator()(float x) const {return x*factor;}
00304 private:
00305 const int n_;
00306 const float factor;
00307 };
00308
00309 class divide_sqrt_n : public std::unary_function<float, float> {
00310 public:
00311 divide_sqrt_n(int n) : n_(n), factor(sqrt(float(n_))) {}
00312 float operator()(float x) const {return x/factor;}
00313 private:
00314 const int n_;
00315 const float factor;
00316 };
00317 };
00318 }
00319 #endif //ACML
00320
00321 #endif //eman_emfft_h__