EMAN2
emfft.h
Go to the documentation of this file.
00001 
00005 /*
00006  * Author: Steven Ludtke, 04/10/2003 (sludtke@bcm.edu)
00007  * Copyright (c) 2000-2006 Baylor College of Medicine
00008  * 
00009  * This software is issued under a joint BSD/GNU license. You may use the
00010  * source code in this file under either license. However, note that the
00011  * complete EMAN2 and SPARX software packages have some GPL dependencies,
00012  * so you are responsible for compliance with the licenses of these packages
00013  * if you opt to use BSD licensing. The warranty disclaimer below holds
00014  * in either instance.
00015  * 
00016  * This complete copyright notice must be included in any revised version of the
00017  * source code. Additional authorship citations may be added, but existing
00018  * author citations must be preserved.
00019  * 
00020  * This program is free software; you can redistribute it and/or modify
00021  * it under the terms of the GNU General Public License as published by
00022  * the Free Software Foundation; either version 2 of the License, or
00023  * (at your option) any later version.
00024  * 
00025  * This program is distributed in the hope that it will be useful,
00026  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00027  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00028  * GNU General Public License for more details.
00029  * 
00030  * You should have received a copy of the GNU General Public License
00031  * along with this program; if not, write to the Free Software
00032  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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);//ming add
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); // ming add
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                         // Prints useful debug information to standard out
00096                         void debug_plans();
00097                 
00098                         // Store the number of plans currently contained in this EMfftw3_cache object
00099                         int num_plans;
00100 
00101                         // Store the rank of the plan
00102                         int rank[EMFFTW2_ND_CACHE_SIZE];
00103                         // Store the dimensions of the plan (always in 3D, if dimensions are "unused" they are taken to be 1)
00104                         int plan_dims[EMFFTW2_ND_CACHE_SIZE][3];
00105                         // store whether the plan was real to complex or vice versa
00106                         int r2c[EMFFTW2_ND_CACHE_SIZE];
00107                         // Store whether or not the plan was inplace
00108                         int ip[EMFFTW2_ND_CACHE_SIZE];
00109                         // Store the plans themselves
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                         // Prints useful debug information to standard out
00137                         void debug_plans();
00138         
00139                         // Store the number of plans currently contained in this EMfftw3_cache object
00140                         int num_plans;
00141 
00142                         // Store the dimensions of the plan (always in 3D, if dimensions are "unused" they are taken to be 1)
00143                         int plan_dims[EMFFTW2_1D_CACHE_SIZE];
00144                         // store whether the plan was real to complex or vice versa
00145                         int r2c[EMFFTW2_1D_CACHE_SIZE];
00146                         // Store the plans themselves
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); // ming add
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);// ming add
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                         // Prints useful debug information to standard out
00216                         void debug_plans();
00217                         
00218                         // Store the number of plans currently contained in this EMfftw3_cache object
00219                         int num_plans;
00220 
00221                         // Store the rank of the plan
00222                         int rank[EMFFTW3_CACHE_SIZE];
00223                         // Store the dimensions of the plan (always in 3D, if dimensions are "unused" they are taken to be 1)
00224                         int plan_dims[EMFFTW3_CACHE_SIZE][3];
00225                         // store whether the plan was real to complex or vice versa
00226                         int r2c[EMFFTW3_CACHE_SIZE];
00227                         // Store the plans themselves
00228                         fftwf_plan fftwplans[EMFFTW3_CACHE_SIZE];
00229                         // Store whether or not the plan was inplace
00230                         int ip[EMFFTW3_CACHE_SIZE];
00231                 };
00232 
00233                 static EMfftw3_cache plan_cache;
00234 #endif 
00235         };
00236 }
00237 #endif  //FFTW3
00238 
00239 //#ifdef CUDA_FFT
00240 //class EMfft
00241 //      {
00242 //      public:
00243 //              static int real_to_complex_1d(float *real_data, float *complex_data, int n);
00244 //              static int complex_to_real_1d(float *complex_data, float *real_data, int n);
00245 
00246 //              static int real_to_complex_nd(float *real_data, float *complex_data, int nx, int ny,
00247 //                                                                        int nz);
00248 //              static int complex_to_real_nd(float *complex_data, float *real_data, int nx, int ny,
00249 //                                                                        int nz);
00250 //      private:
00251 //              static const int EMAN2_REAL_2_COMPLEX;
00252 //              static const int EMAN2_COMPLEX_2_REAL;
00253 //              static const int EMAN2_FFTW2_INPLACE;
00254 //              static const int EMAN2_FFTW2_OUT_OF_PLACE;
00255 //      };
00256 //#endif //CUDA_FFT
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__