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 32
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 static EMfftw3_cache plan_cache;
00234 #endif
00235 };
00236 }
00237 #endif //FFTW3
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 #ifdef NATIVE_FFT
00260 namespace EMAN
00261 {
00264 class EMfft
00265 {
00266 public:
00267 static int real_to_complex_1d(float *real_data, float *complex_data, int n);
00268 static int complex_to_real_1d(float *complex_data, float *real_data, int n);
00269
00270 static int real_to_complex_nd(float *real_data, float *complex_data, int nx, int ny, int nz);
00271 static int complex_to_real_nd(float *complex_data, float *real_data, int nx, int ny, int nz);
00272 };
00273 }
00274 #endif //NATIVE_FFT
00275
00276 #ifdef ACML
00277 #include <acml.h>
00278 #include <functional>
00279
00280 namespace EMAN
00281 {
00284 class EMfft
00285 {
00286 public:
00287 static int real_to_complex_1d(float *real_data, float *complex_data, int n);
00288 static int complex_to_real_1d(float *complex_data, float *real_data, int n);
00289
00290 static int real_to_complex_nd(float *real_data, float *complex_data, int nx, int ny, int nz);
00291 static int complex_to_real_nd(float *complex_data, float *real_data, int nx, int ny, int nz);
00292
00293 private:
00294 static int real_to_complex_2d(float *real_data, float *complex_data, int nx, int ny);
00295 static int complex_to_real_2d(float *complex_data, float *real_data, int nx, int ny);
00296 static int real_to_complex_3d(float *real_data, float *complex_data, int nx, int ny, int nz);
00297 static int complex_to_real_3d(float *complex_data, float *real_data, int nx, int ny, int nz);
00298
00299 class time_sqrt_n : public std::unary_function<float, float> {
00300 public:
00301 time_sqrt_n(int n) : n_(n), factor(sqrt(float(n_))) {}
00302 float operator()(float x) const {return x*factor;}
00303 private:
00304 const int n_;
00305 const float factor;
00306 };
00307
00308 class divide_sqrt_n : public std::unary_function<float, float> {
00309 public:
00310 divide_sqrt_n(int n) : n_(n), factor(sqrt(float(n_))) {}
00311 float operator()(float x) const {return x/factor;}
00312 private:
00313 const int n_;
00314 const float factor;
00315 };
00316 };
00317 }
00318 #endif //ACML
00319
00320 #endif //eman_emfft_h__