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
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 private:
00057 #ifdef FFTW_PLAN_CACHING
00058 #define EMFFTW2_ND_CACHE_SIZE 20
00059 #define EMFFTW2_1D_CACHE_SIZE 20
00060 static const int EMAN2_REAL_2_COMPLEX;
00061 static const int EMAN2_COMPLEX_2_REAL;
00062 static const int EMAN2_FFTW2_INPLACE;
00063 static const int EMAN2_FFTW2_OUT_OF_PLACE;
00074 class EMfftw2_cache_nd
00075 {
00076 public:
00077 EMfftw2_cache_nd();
00078 ~EMfftw2_cache_nd();
00079
00091 rfftwnd_plan get_plan(const int rank, const int x, const int y, const int z, const int r2c_flag, int ip_flag);
00092 private:
00093
00094 void debug_plans();
00095
00096
00097 int num_plans;
00098
00099
00100 int rank[EMFFTW2_ND_CACHE_SIZE];
00101
00102 int plan_dims[EMFFTW2_ND_CACHE_SIZE][3];
00103
00104 int r2c[EMFFTW2_ND_CACHE_SIZE];
00105
00106 int ip[EMFFTW2_ND_CACHE_SIZE];
00107
00108 rfftwnd_plan rfftwnd_plans[EMFFTW2_ND_CACHE_SIZE];
00109 };
00110
00120 class EMfftw2_cache_1d
00121 {
00122 public:
00123 EMfftw2_cache_1d();
00124 ~EMfftw2_cache_1d();
00125
00132 rfftw_plan get_plan(const int x, const int r2c_flag);
00133 private:
00134
00135 void debug_plans();
00136
00137
00138 int num_plans;
00139
00140
00141 int plan_dims[EMFFTW2_1D_CACHE_SIZE];
00142
00143 int r2c[EMFFTW2_1D_CACHE_SIZE];
00144
00145 rfftw_plan rfftw1d_plans[EMFFTW2_1D_CACHE_SIZE];
00146 };
00147
00148 static EMfftw2_cache_nd plan_nd_cache;
00149 static EMfftw2_cache_1d plan_1d_cache;
00150 #endif
00151 };
00152 }
00153 #endif //FFTW2
00154
00155 #ifdef FFTW3
00156
00157 #include <fftw3.h>
00158
00159 namespace EMAN
00160 {
00163 class EMfft
00164 {
00165 public:
00166 static int real_to_complex_1d(float *real_data, float *complex_data, int n);
00167 static int complex_to_real_1d(float *complex_data, float *real_data, int n);
00168
00169 static int real_to_complex_nd(float *real_data, float *complex_data, int nx, int ny,
00170 int nz);
00171 static int complex_to_real_nd(float *complex_data, float *real_data, int nx, int ny,
00172 int nz);
00173 private:
00174 #ifdef FFTW_PLAN_CACHING
00175 #define EMFFTW3_CACHE_SIZE 20
00176 static const int EMAN2_REAL_2_COMPLEX;
00177 static const int EMAN2_COMPLEX_2_REAL;
00178 static const int EMAN2_FFTW2_INPLACE;
00179 static const int EMAN2_FFTW2_OUT_OF_PLACE;
00191 class EMfftw3_cache
00192 {
00193 public:
00194 EMfftw3_cache();
00195 ~EMfftw3_cache();
00196
00210 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);
00211 private:
00212
00213 void debug_plans();
00214
00215
00216 int num_plans;
00217
00218
00219 int rank[EMFFTW3_CACHE_SIZE];
00220
00221 int plan_dims[EMFFTW3_CACHE_SIZE][3];
00222
00223 int r2c[EMFFTW3_CACHE_SIZE];
00224
00225 fftwf_plan fftwplans[EMFFTW3_CACHE_SIZE];
00226
00227 int ip[EMFFTW3_CACHE_SIZE];
00228
00229 };
00230
00231 static EMfftw3_cache plan_cache;
00232 #endif
00233 };
00234 }
00235 #endif //FFTW3
00236
00237 #ifdef CUDA_FFT
00238 class EMfft
00239 {
00240 public:
00241 static int real_to_complex_1d(float *real_data, float *complex_data, int n);
00242 static int complex_to_real_1d(float *complex_data, float *real_data, int n);
00243
00244 static int real_to_complex_nd(float *real_data, float *complex_data, int nx, int ny,
00245 int nz);
00246 static int complex_to_real_nd(float *complex_data, float *real_data, int nx, int ny,
00247 int nz);
00248 private:
00249 static const int EMAN2_REAL_2_COMPLEX;
00250 static const int EMAN2_COMPLEX_2_REAL;
00251 static const int EMAN2_FFTW2_INPLACE;
00252 static const int EMAN2_FFTW2_OUT_OF_PLACE;
00253 };
00254 #endif //CUDA_FFT
00255
00256
00257 #ifdef NATIVE_FFT
00258 namespace EMAN
00259 {
00262 class EMfft
00263 {
00264 public:
00265 static int real_to_complex_1d(float *real_data, float *complex_data, int n);
00266 static int complex_to_real_1d(float *complex_data, float *real_data, int n);
00267
00268 static int real_to_complex_nd(float *real_data, float *complex_data, int nx, int ny, int nz);
00269 static int complex_to_real_nd(float *complex_data, float *real_data, int nx, int ny, int nz);
00270 };
00271 }
00272 #endif //NATIVE_FFT
00273
00274 #ifdef ACML
00275 #include <acml.h>
00276 #include <functional>
00277
00278 namespace EMAN
00279 {
00282 class EMfft
00283 {
00284 public:
00285 static int real_to_complex_1d(float *real_data, float *complex_data, int n);
00286 static int complex_to_real_1d(float *complex_data, float *real_data, int n);
00287
00288 static int real_to_complex_nd(float *real_data, float *complex_data, int nx, int ny, int nz);
00289 static int complex_to_real_nd(float *complex_data, float *real_data, int nx, int ny, int nz);
00290
00291 private:
00292 static int real_to_complex_2d(float *real_data, float *complex_data, int nx, int ny);
00293 static int complex_to_real_2d(float *complex_data, float *real_data, int nx, int ny);
00294 static int real_to_complex_3d(float *real_data, float *complex_data, int nx, int ny, int nz);
00295 static int complex_to_real_3d(float *complex_data, float *real_data, int nx, int ny, int nz);
00296
00297 class time_sqrt_n : public std::unary_function<float, float> {
00298 public:
00299 time_sqrt_n(int n) : n_(n), factor(sqrt(float(n_))) {}
00300 float operator()(float x) const {return x*factor;}
00301 private:
00302 const int n_;
00303 const float factor;
00304 };
00305
00306 class divide_sqrt_n : public std::unary_function<float, float> {
00307 public:
00308 divide_sqrt_n(int n) : n_(n), factor(sqrt(float(n_))) {}
00309 float operator()(float x) const {return x/factor;}
00310 private:
00311 const int n_;
00312 const float factor;
00313 };
00314 };
00315 }
00316 #endif //ACML
00317
00318 #endif //eman_emfft_h__