Main Page   Namespace List   Compound List   File List   Namespace Members   Compound Members  

support.h

Go to the documentation of this file.
00001 
00120 #ifndef __SUPPORT_FFT__
00121 #define __SUPPORT_FFT__
00122 
00123 #include <errno.h>
00124 #include <stdio.h>
00125 
00126 #include <sstream>
00127 #include <string>
00128 
00129 #include "fftw3.h"
00130 
00131 #include "msg_stream.h"
00132 
00133 
00134 namespace FFT{
00135 
00136   /*
00137      #################
00138      # class Support #
00139      #################
00140   */
00141 
00142 
00143   
00145   class Support {
00146     
00147   public:
00148 
00149     typedef unsigned int  size_type;
00150 
00151     typedef double        real_type;
00152     typedef fftw_complex  complex_type;
00153     
00154     typedef real_type*    space_data_type;
00155     typedef complex_type* frequency_data_type;
00156     typedef void*         buffer_type;
00157     
00158     
00161     inline Support(const size_type w,
00162                    const size_type h);
00163 
00164     inline ~Support();
00165 
00166 
00168 
00169     inline size_type x_space_size() const;
00170     inline size_type y_space_size() const;
00172 
00174 
00175     inline size_type x_frequency_size() const;
00176     inline size_type y_frequency_size() const;
00178    
00180     inline buffer_type create_buffer() const;
00181 
00183     inline void destroy_buffer(buffer_type buffer) const;
00184 
00185 
00186 
00187     
00189     template <typename Real_data_2D_array>
00190     void save_space_data(Real_data_2D_array* const array) const;
00191 
00193     template <typename Real_data_2D_array>
00194     void load_space_data(const Real_data_2D_array& array);
00195 
00196 
00197     
00198     
00200     template <typename Complex_data_2D_array>
00201     void save_frequency_data(Complex_data_2D_array* const array) const;
00202 
00204     template <typename Complex_data_2D_array>
00205     void load_frequency_data(const Complex_data_2D_array& array);
00206 
00207 
00208     
00209     
00211     inline void save_space_data_into_buffer(buffer_type buffer) const;
00212 
00214     inline void load_space_data_from_buffer(buffer_type buffer);
00215     
00216 
00217 
00218 
00220     inline void save_frequency_data_into_buffer(buffer_type buffer) const;
00221 
00223     inline void load_frequency_data_from_buffer(buffer_type buffer);
00224 
00225 
00226     
00227 
00229     inline void space_to_frequency();
00230 
00232     inline void frequency_to_space();
00233 
00234     
00235 
00236 
00239     inline void multiply_frequency_data_by_buffer(buffer_type buffer,
00240                                                   const bool  scale = false);
00241 
00242 
00243 
00244 
00245     
00246 
00247     // ####################
00248     // # Static functions #
00249     // ####################
00250 
00251 
00253     static inline void set_fftw_flags(const unsigned flags);
00254 
00255     
00257     static inline void set_wisdom_file(const std::string file_name);
00258 
00259     
00260   private:
00261 
00263 
00264     fftw_plan forward, backward;
00266 
00268     space_data_type     space_data;
00269 
00271     frequency_data_type frequency_data;
00272 
00274 
00275     
00276     const size_type width;
00277     const size_type height;
00279 
00281 
00282     
00283     const size_type support_w;
00284     const size_type support_h;
00285     const size_type mem_size;
00287     
00288     static inline size_type index(const size_type x,
00289                                   const size_type y,
00290                                   const size_type w,
00291                                   const size_type h);
00292    
00293 
00294     // ####################
00295     // # Static functions #
00296     // ####################
00297 
00298 
00300     static unsigned fftw_flags;
00301 
00303     static std::string wisdom_file;
00304 
00306     static size_type support_number;
00307 
00309     static inline void new_support();
00310 
00312     static inline void delete_support();
00313   };
00314 
00315 
00316 
00317 /*
00318   ###########################################################
00319   ###########################################################
00320   ###########################################################
00321   ##############                               ##############
00322   ##############  I M P L E M E N T A T I O N  ##############
00323   ##############                               ##############
00324   ###########################################################
00325   ###########################################################
00326   ###########################################################
00327 */
00328 
00329 
00330   
00331 
00332   // ##################
00333   // # Static section #
00334   // ##################
00335 
00336   // Static values initialization
00337   
00338   unsigned           Support::fftw_flags     = FFTW_EXHAUSTIVE;
00339   std::string        Support::wisdom_file    = std::string("");
00340   Support::size_type Support::support_number = 0;
00341 
00342   
00343   
00344 
00345   // ######################
00346   // # Non-static section #
00347   // ######################
00348 
00349 
00350   void Support::set_fftw_flags(const unsigned flags){
00351     fftw_flags = flags;
00352   }
00353 
00354   void Support::set_wisdom_file(const std::string file_name){
00355     wisdom_file = file_name;
00356   }
00357 
00358 
00359 
00360   void Support::new_support(){
00361     support_number++;
00362 
00363     // Job is done if not the first support or if not file support required.
00364     if ((support_number > 1)||(wisdom_file.size() == 0)){
00365       return;
00366     }
00367 
00368     
00369     // If it is the first support, try to load the wisdom data.
00370 
00371     
00372     // Opening the wisdom file.
00373     FILE* f = fopen(wisdom_file.c_str(),"r");
00374     
00375     if (f != NULL){ // System says "ok"
00376       if(fftw_import_wisdom_from_file(f) == 0){ // But FFTW says "error".
00377         Message::warning<<"error while reading FFTW wisdom file \""
00378                         <<wisdom_file<<"\""<<Message::done;
00379       }
00380       fclose(f);
00381     }
00382     else if (errno != ENOENT){ // System says "error".
00383       Message::warning<<"error while opening (read mode) FFTW wisdom file \""
00384                       <<wisdom_file<<"\""<<Message::done;
00385     }
00386     // Wisdom is now initialized.
00387   }
00388 
00389 
00390   
00391   void Support::delete_support(){
00392     support_number--;
00393 
00394     // Job is done if not the last support.
00395     if ((support_number > 0)||(wisdom_file.size() == 0)){
00396       return;
00397     }
00398 
00399     // If it is the last support, try to save the wisdom data.
00400 
00401     // Save wisdom.
00402     FILE* f = fopen(wisdom_file.c_str(),"w");
00403 
00404     if (f != NULL){ // System says "ok".
00405       fftw_export_wisdom_to_file(f);
00406         fclose(f);
00407     }
00408     else{ // System says "error".
00409       Message::warning<<"error while opening (write mode) FFTW wisdom file \""
00410                       <<wisdom_file<<"\"\n"
00411                       <<"no file saved"<<Message::done;
00412     }
00413   }
00414 
00423   Support::Support(const size_type w,
00424                    const size_type h):
00425     width(w),
00426     height(h),
00427     
00428     support_w(w),
00429     support_h(h/2+1),
00430     mem_size(w*(h/2+1)*sizeof(complex_type)) {
00431 
00432     new_support();
00433     
00434     // Pointer to the space data.
00435     space_data = reinterpret_cast<space_data_type>(fftw_malloc(mem_size));
00436 
00437     // Same pointer to perform "in place" computation.
00438     frequency_data = reinterpret_cast<frequency_data_type>(space_data);
00439 
00440     
00441     // We make the best measurement possible because we use the wisdom system.
00442     forward  = fftw_plan_dft_r2c_2d(width,height,
00443                                     space_data,frequency_data,
00444                                     fftw_flags);
00445     
00446     backward = fftw_plan_dft_c2r_2d(width,height,
00447                                     frequency_data,space_data,
00448                                     fftw_flags);
00449   }
00450 
00451 
00452 
00453 
00454 
00455   
00456   Support::~Support(){
00457 
00458     delete_support();
00459     
00460     // Free memory.
00461     fftw_destroy_plan(forward);
00462     fftw_destroy_plan(backward);
00463 
00464     fftw_free(space_data);
00465   }
00466 
00467 
00468 
00469   
00470   Support::size_type Support::x_space_size() const{
00471     return width;
00472   }
00473 
00474 
00475   
00476   Support::size_type Support::y_space_size() const{
00477     return height;
00478   }
00479 
00480 
00481   Support::size_type Support::x_frequency_size() const{
00482     return support_w;
00483   }
00484 
00485 
00486   Support::size_type Support::y_frequency_size() const{
00487     return support_h;
00488   }
00489 
00490 
00491   
00492   Support::size_type Support::index(const size_type x,
00493                                     const size_type y,
00494                                     const size_type w,
00495                                     const size_type h){
00496     return y + x*h;
00497   }
00498 
00499 
00500   
00501   
00502   Support::buffer_type Support::create_buffer() const{
00503 
00504     return fftw_malloc(mem_size);
00505   }
00506 
00507   void Support::destroy_buffer(buffer_type buffer) const{
00508     
00509     fftw_free(buffer);
00510   }
00511 
00512   
00513 
00514   
00519   template <typename Real_data_2D_array>
00520   void Support::save_space_data(Real_data_2D_array* const array) const{
00521 
00522     array->resize(width,height);
00523 
00524     for(size_type x=0;x<width;x++){
00525       for(size_type y=0;y<height;y++){
00526         const size_type i = index(x,y,support_w,2*support_h);
00527 
00528         (*array)(x,y) = space_data[i];
00529       }
00530     }
00531   }
00532 
00537   template <typename Real_data_2D_array>
00538   void Support::load_space_data(const Real_data_2D_array& array){
00539 
00540     if ((array.x_size()!=width)||(array.y_size()!=height)){
00541       Message::error<<"Support::load_space_data : size does not match"
00542                     <<Message::done;
00543     }
00544 
00545     for(size_type x=0;x<width;x++){
00546       for(size_type y=0;y<height;y++){
00547         const size_type i = index(x,y,support_w,2*support_h);
00548 
00549         space_data[i] = array(x,y);
00550       }
00551     }
00552 
00553   }
00554 
00555 
00556 
00557   
00563   template <typename Complex_data_2D_array>
00564   void Support::save_frequency_data(Complex_data_2D_array* const array) const{
00565 
00566     typedef typename Complex_data_2D_array::value_type cplx_type;
00567     
00568     array->resize(support_w,support_h);
00569 
00570     for(size_type x=0;x<support_w;x++){
00571       for(size_type y=0;y<support_h;y++){
00572         const size_type i = index(x,y,support_w,support_h);
00573 
00574         (*array)(x,y) = cplx_type(frequency_data[i][0],frequency_data[i][1]);
00575       }
00576     }
00577   }
00578 
00585   template <typename Complex_data_2D_array>
00586   void Support::load_frequency_data(const Complex_data_2D_array& array){
00587 
00588     if ((array.x_size()!=support_w)||(array.y_size()!=support_h)){
00589       Message::error<<"Support::load_frequency_data : size does not match"
00590                     <<Message::done;
00591     }
00592 
00593     for(size_type x=0;x<support_w;x++){
00594       for(size_type y=0;y<support_h;y++){
00595         const size_type i = index(x,y,support_w,support_h);
00596 
00597         frequency_data[i][0] = array(x,y).real();
00598         frequency_data[i][1] = array(x,y).imag();
00599       }
00600     }
00601 
00602   }
00603 
00604 
00605 
00606   
00607   
00608   void Support::save_space_data_into_buffer(buffer_type buffer) const{
00609     memcpy(buffer,space_data,mem_size);
00610   }
00611 
00612   void Support::load_space_data_from_buffer(buffer_type buffer){
00613     memcpy(space_data,buffer,mem_size);
00614   }
00615 
00616   
00617 
00618   
00619   void Support::save_frequency_data_into_buffer(buffer_type buffer) const{
00620     memcpy(buffer,frequency_data,mem_size);
00621   }
00622 
00623   void Support::load_frequency_data_from_buffer(buffer_type buffer){
00624     memcpy(frequency_data,buffer,mem_size);
00625   }
00626 
00627 
00628 
00629 
00630 
00631   void Support::space_to_frequency(){
00632     fftw_execute(forward);
00633   }
00634 
00635 
00636   void Support::frequency_to_space(){
00637     fftw_execute(backward);
00638   }
00639 
00640 
00641 
00642 
00643   void Support::multiply_frequency_data_by_buffer(buffer_type buffer,
00644                                                   const bool  scale){
00645     
00646     const size_type size = support_w*support_h;
00647     const frequency_data_type freq_buffer =
00648       reinterpret_cast<frequency_data_type>(buffer);
00649 
00650     const real_type s = scale ? 1.0/(width*height) : 1.0;
00651     
00652     for(size_type i=0;i<size;i++){
00653 
00654       const double a_re = frequency_data[i][0];
00655       const double a_im = frequency_data[i][1];
00656       
00657       const double b_re = freq_buffer[i][0];
00658       const double b_im = freq_buffer[i][1];
00659       
00660       frequency_data[i][0] = (a_re*b_re - a_im*b_im)*s;
00661       frequency_data[i][1] = (a_re*b_im + a_im*b_re)*s;
00662       
00663     }
00664     
00665   }
00666 
00667 }
00668 
00669 
00670 #endif

Generated on Thu Aug 19 15:55:51 2004 by doxygen1.2.18