• Main Page
  • Related Pages
  • Classes
  • Files
  • File List
  • File Members

cfftw.hh

Go to the documentation of this file.
00001 // #Id: cfftw.hh,v 1.5 2001/05/01 19:20:37 zweck Exp #
00002 
00003 // #####################################################################
00004 //
00005 //    cfftw.cc
00006 //
00007 //    Methods module for the class of objects used as
00008 //    an interface to the FFTW toolkit.
00009 //
00010 //    Copyright:
00011 //       Optical Fiber Communications Laboratory (OFCL)
00012 //       Computer Science & Electrical Engineering Department (CSEE)
00013 //       University of Maryland Baltimore County (UMBC)
00014 //
00015 // #####################################################################
00016 //    Author: Ronald Holzloehner  <holzloehner@umbc.edu>
00017 // #####################################################################
00018 
00019 
00020 //#define _USING_FFTW3_
00021 
00022 
00023 #ifdef _USING_FFTW3_
00024 
00025 //## You should include the next line if you are using an old GNU C++ compiler 
00026 //#define _OLD_CPP_COMPILER_
00027 
00028 #ifndef _CFFTW3_HH_
00029 #define _CFFTW3_HH_
00030 
00031 
00032 
00033 #include <iostream.h>
00034 #include <complex.h>
00035 //#include <string.h>
00036 #include <string>
00037    using namespace std;
00038 #include <malloc.h>
00039 #include <new>
00040 
00041 //#include <fftw.h>
00042 #include <fftw3.h>
00043 
00044 typedef complex<double> cplx; 
00045 
00046 
00047 //## These lines must be commented for the old GNU C++ compiler in malkhut
00048 #ifndef _OLD_CPP_COMPILER_
00049 #ifndef _OVERLOADED_OPERATORS_
00050 #define _OVERLOADED_OPERATORS_
00051 //## Added by Ivan Lima to make the source compatible with g++
00052 //## Most of the new code consists of overloading operators
00053 using namespace std;
00054 
00055 inline cplx operator+( cplx a, double b);
00056 inline cplx operator+( cplx a, double b) 
00057 {
00058    return a + cplx(b);
00059 }  
00060 
00061 inline cplx operator+( double b, cplx a);
00062 inline cplx operator+( double b, cplx a) 
00063 {
00064    return a + cplx(b);
00065 }   
00066 
00067 inline cplx operator*( cplx a, double b);
00068 inline cplx operator*( cplx a, double b) 
00069 {
00070    return a * cplx(b);
00071 }   
00072 
00073 inline cplx operator*( double b, cplx a);
00074 inline cplx operator*( double b, cplx a) 
00075 {
00076    return a * cplx(b);
00077 }   
00078 
00079 inline cplx operator/( cplx a, double b);
00080 inline cplx operator/( cplx a, double b) 
00081 {
00082    return a / cplx(b);
00083 }   
00084 
00085 inline double log (int a);
00086 inline double log(int a)
00087 {
00088    return log( (double) a );
00089 }
00090 
00091 inline double sqrt(int a);
00092 inline double sqrt(int a)
00093 {
00094    return sqrt( (double) a );
00095 }
00096 #endif   // _OVERLOADED_OPERATORS_
00097 #endif   // _OLD_CPP_COMPILER_
00098 //## End of the extra lines that must be added for the new GNU C++ compiler
00099 
00100 
00101 #ifdef GLOBAL_NEW_MEMORY
00102 extern volatile unsigned long GLOBAL_NEW_MEMORY_VAL;
00103 #endif //GLOBAL_NEW_MEMORY
00104 
00105 // overloaded "new" and "new[]" operator
00106 // purpose: allocate memory aligned to 16-byte boundaries
00107 inline void* operator new[](size_t t) throw (std::bad_alloc);
00108 inline void* operator new[](size_t t) throw (std::bad_alloc)
00109 {
00110   void *p = memalign(16, t);
00111   if(!p) {
00112     #ifdef _OLD_CPP_COMPILER_  
00113     throw bad_alloc();
00114     #endif  // _OLD_CPP_COMPILER_
00115   }    
00116   if(((unsigned int)(p))%16)
00117   {
00118     cerr << "\n\noperator new[]: bad pointer alignment (cfftw.hh)\n\n";
00119     exit(-1);
00120   }
00121 
00122 #ifdef GLOBAL_NEW_MEMORY
00123   GLOBAL_NEW_MEMORY_VAL += (unsigned long)(t);
00124 #endif //GLOBAL_NEW_MEMORY
00125 #ifdef DEBUG_NEW
00126   cout << "\nAllocating " << t << " bytes! (new[])" << endl;
00127 #ifdef GLOBAL_NEW_MEMORY
00128   cout << "Total allocated memory: " << GLOBAL_NEW_MEMORY_VAL << " bytes" << endl;
00129 #endif //GLOBAL_NEW_MEMORY
00130 #endif // DEBUG_NEW
00131   return(p);
00132 }
00133 inline void* operator new(size_t t) throw (std::bad_alloc);
00134 inline void* operator new(size_t t) throw (std::bad_alloc)
00135 {
00136   void *p = memalign(16, t);
00137   if(!p) {
00138     #ifdef _OLD_CPP_COMPILER_    
00139     throw bad_alloc();
00140     #endif  // _OLD_CPP_COMPILER_    
00141   }    
00142   if(((unsigned int)(p))%16)
00143   {
00144     cerr << "\n\noperator new: bad pointer alignment (ron_base.hh)\n\n";
00145     exit(-1);
00146   }
00147 #ifdef GLOBAL_NEW_MEMORY
00148   GLOBAL_NEW_MEMORY_VAL += (unsigned long)(t);
00149 #endif //GLOBAL_NEW_MEMORY
00150 #ifdef DEBUG_NEW
00151   cout << "\nAllocating " << t << " bytes! (new)" << endl;
00152 #ifdef GLOBAL_NEW_MEMORY
00153   cout << "Total allocated memory: " << GLOBAL_NEW_MEMORY_VAL << " bytes" << endl;
00154 #endif //GLOBAL_NEW_MEMORY
00155 #endif // DEBUG_NEW
00156   return(p);
00157 }
00158 
00159 inline void operator delete[](void *p) throw() ;
00160 inline void operator delete[](void *p) throw()
00161 {
00162 #ifdef DEBUG_NEW
00163   cout << "Freeing memory (delete[])" << endl;
00164 #endif // DEBUG_NEW
00165   free(p);
00166 }
00167 inline void operator delete(void *p) throw() ;
00168 inline void operator delete(void *p) throw()
00169 {
00170 #ifdef DEBUG_NEW
00171   cout << "Freeing memory (delete)" << endl;
00172 #endif // DEBUG_NEW
00173   free(p);
00174 }
00175 
00176 
00179 
00191 inline cplx* NewCplx(int N)
00192 {
00193 
00194   cplx * fftw_data = (cplx*) fftw_malloc(sizeof(fftw_complex)*N); 
00195 
00196   if (!fftw_data)
00197     {
00198     cerr << "NewCplx: null pointer \n";
00199     exit(-1);
00200     }
00201 
00202   cplx * ptr = fftw_data;
00203   cplx * end_ptr = fftw_data + N;
00204 
00205 
00206   for( ; ptr < end_ptr; ptr++)
00207     *ptr = 0.0;
00208 
00209   return fftw_data;  
00210 };
00211 
00212 // ##############################
00213 
00216 
00226 inline double* NewDouble(int N)
00227 {
00228   double * start_ptr = (double*) memalign(16,N*sizeof(double));
00229 
00230   if((!start_ptr) || ((unsigned int)(start_ptr) % 16))
00231    {
00232      cerr << "NewDouble: null or unaligned pointer\n"; 
00233      exit(-1);
00234    }
00235 
00236   double * ptr = start_ptr;
00237   double * end_ptr = start_ptr + N;
00238 
00239   for( ; ptr < end_ptr; ptr++)
00240     *ptr = 0.0;
00241 
00242   return start_ptr;  
00243 
00244 };
00245 
00246 // ##############################
00247 
00250 
00261 inline int* NewInt(int N)
00262 {
00263   int * start_ptr = (int*) memalign(16,N*sizeof(int));
00264 
00265   if((!start_ptr) || ((unsigned int)(start_ptr) % 16))
00266    {
00267      cerr << "NewInt: null or unaligned pointer\n"; 
00268      exit(-1);
00269    }
00270 
00271   int * ptr = start_ptr;
00272   int * end_ptr = start_ptr + N;
00273 
00274   for( ; ptr < end_ptr; ptr++)
00275     *ptr = 0;
00276 
00277   return start_ptr;  
00278 
00279 };
00280 
00282 
00283 inline void FreeCplx(cplx * ptr) { fftw_free((fftw_complex*)ptr); };
00284 
00286 
00287 inline void FreeDouble(double * ptr) { free(ptr); };
00288 
00290 
00291 inline void FreeInt(int * ptr) { free(ptr); };
00292 
00293 
00294 // ##### This class was created by Ronald Holzloehner
00295 
00296 
00297 class cfftw
00298 {
00299     int N, N_half;
00300     fftw_plan  forw, backw;
00301     cplx  *shift_work;
00302     int shift_len1, shift_len2;
00303     
00304   public:
00305 
00307 
00308     double T;
00309 
00311 
00312     double F;
00313 
00315  
00316     double  delta_f;
00317     double  delta_t;
00318     fftw_complex *fftw_in, *fftw_out; 
00319     cplx * work;
00320 
00322 
00323     cfftw(int N, double T);
00324     
00325     ~cfftw();
00326 
00328     void FFT(cplx *in, cplx *out);
00329 
00331     void IFFT(cplx *in, cplx *out);
00332     void fftshift(cplx *in);
00333     void ifftshift(cplx *in);
00334 
00335     // gives frequency at index i after FFT() ran
00336     // frequencies go like  0 1 2 3 -4 -3 -2 -1  (N=8)
00337     // input in [0, N-1], output in [-N/2, N/2-1]
00338 
00341 
00342     inline double freq(int i) {return delta_f 
00343                 *( (i < N_half)? (i):(i-N) ); };
00344 
00345     // gives index of frequency with index k after FFT() ran
00346     // input in [-N/2, N/2-1], output in [0, N-1]
00347 
00350 
00351     inline int index(int k) {return ( (k >= 0)? (k):(k+N) ); };
00352 
00353     inline int give_N(void) {return N;};
00354 
00355 
00356 };
00357 
00358 //## These lines must be commented for the new GNU C++ compiler
00359 // ##### Additional function used by the methods of cfftw
00360 #ifdef _OLD_CPP_COMPILER_
00361 template <class T> inline T max(T,T);
00362 template <class T> inline T max(T a, T bb)
00363 {
00364   return  ((a >= bb)? a:bb);
00365 }
00366 inline cplx max(cplx &a, cplx &bb);
00367 #endif // _OLD_CPP_COMPILER_
00368 //## End of the lines that must be included for the old GNU C++ compiler of malkhut
00369 
00370 
00371 inline cplx max(cplx &a, cplx &bb)
00372 {
00373   return (norm(a) >= norm(bb))? a:bb;
00374 }
00375 
00376 
00377 // ##### Example of use of cfftw
00378 /*****************************  All these lines are commented
00379 int main(void)     
00380 {
00381 cfftw *fft; 
00382 int N;
00383 cout "\n Enter N: " << endl;
00384 cin >> N;
00385 double T = 1.0;
00386 fft = new cfftw(N, T, FFTW_MEASURE);
00387 int i;
00388 cplx *time = NewCplx(N);
00389 cplx *freq = NewCplx(N);
00390 for(i=0; i<N; i++)
00391   in[i] = i;  // put in something  
00392 fft->FFT(time, freq);
00393 fft->fftshift(freq);
00394 // do something...
00395 fft->ifftshift(freq);
00396 fft->IFFT(freq, time);
00397 }
00398 *************************************/ // end of comment
00399 
00400 #endif /* _CFFTW3_HH_ */ 
00401 
00402 
00403 #endif /* _USING_FFTW3_ */
00404 
00405 
00406 #ifndef _USING_FFTW3_
00407 
00408 
00409 // #####################################################################
00410 //
00411 //    cfftw.cc
00412 //
00413 //    Methods module for the class of objects used as
00414 //    an interface to the FFTW toolkit.
00415 //
00416 //    Copyright:
00417 //       Optical Fiber Communications Laboratory (OFCL)
00418 //       Computer Science & Electrical Engineering Department (CSEE)
00419 //       University of Maryland Baltimore County (UMBC)
00420 //
00421 // #####################################################################
00422 //    Author: Ronald Holzloehner  <holzloehner@umbc.edu>
00423 // #####################################################################
00424 
00425 //## You should include the next line if you are using an old GNU C++ compiler 
00426 //#define _OLD_CPP_COMPILER_
00427 
00428 #ifndef _CFFTW_HH_
00429 #define _CFFTW_HH_
00430 
00431 #include <iostream.h>
00432 #include <complex.h>
00433 //#include <string.h>
00434 #include <string>
00435    using namespace std;
00436 #include <malloc.h>
00437 #include <new>
00438 #include <fftw.h>
00439 
00440 
00441 typedef complex<double> cplx; 
00442 
00443 
00444 //## These lines must be commented for the old GNU C++ compiler in malkhut
00445 #ifndef _OLD_CPP_COMPILER_
00446 #ifndef _OVERLOADED_OPERATORS_
00447 #define _OVERLOADED_OPERATORS_
00448 //## Added by Ivan Lima to make the source compatible with g++
00449 //## Most of the new code consists of overloading operators
00450 using namespace std;
00451 
00452 inline cplx operator+( cplx a, double b);
00453 inline cplx operator+( cplx a, double b) 
00454 {
00455    return a + cplx(b);
00456 }  
00457 
00458 inline cplx operator+( double b, cplx a);
00459 inline cplx operator+( double b, cplx a) 
00460 {
00461    return a + cplx(b);
00462 }   
00463 
00464 inline cplx operator*( cplx a, double b);
00465 inline cplx operator*( cplx a, double b) 
00466 {
00467    return a * cplx(b);
00468 }   
00469 
00470 inline cplx operator*( double b, cplx a);
00471 inline cplx operator*( double b, cplx a) 
00472 {
00473    return a * cplx(b);
00474 }   
00475 
00476 inline cplx operator/( cplx a, double b);
00477 inline cplx operator/( cplx a, double b) 
00478 {
00479    return a / cplx(b);
00480 }   
00481 
00482 inline double log (int a);
00483 inline double log(int a)
00484 {
00485    return log( (double) a );
00486 }
00487 
00488 inline double sqrt(int a);
00489 inline double sqrt(int a)
00490 {
00491    return sqrt( (double) a );
00492 }
00493 #endif   // _OVERLOADED_OPERATORS_
00494 #endif   // _OLD_CPP_COMPILER_
00495 //## End of the extra lines that must be added for the new GNU C++ compiler
00496 
00497 
00498 #ifdef GLOBAL_NEW_MEMORY
00499 extern volatile unsigned long GLOBAL_NEW_MEMORY_VAL;
00500 #endif //GLOBAL_NEW_MEMORY
00501 
00502 // overloaded "new" and "new[]" operator
00503 // purpose: allocate memory aligned to 16-byte boundaries
00504 inline void* operator new[](size_t t) throw (std::bad_alloc);
00505 inline void* operator new[](size_t t) throw (std::bad_alloc)
00506 {
00507   void *p = memalign(16, t);
00508   if(!p) {
00509     #ifdef _OLD_CPP_COMPILER_  
00510     throw bad_alloc();
00511     #endif  // _OLD_CPP_COMPILER_
00512   }    
00513   if(((unsigned int)(p))%16)
00514   {
00515     cerr << "\n\noperator new[]: bad pointer alignment (cfftw.hh)\n\n";
00516     exit(-1);
00517   }
00518 
00519 #ifdef GLOBAL_NEW_MEMORY
00520   GLOBAL_NEW_MEMORY_VAL += (unsigned long)(t);
00521 #endif //GLOBAL_NEW_MEMORY
00522 #ifdef DEBUG_NEW
00523   cout << "\nAllocating " << t << " bytes! (new[])" << endl;
00524 #ifdef GLOBAL_NEW_MEMORY
00525   cout << "Total allocated memory: " << GLOBAL_NEW_MEMORY_VAL << " bytes" << endl;
00526 #endif //GLOBAL_NEW_MEMORY
00527 #endif // DEBUG_NEW
00528   return(p);
00529 }
00530 inline void* operator new(size_t t) throw (std::bad_alloc);
00531 inline void* operator new(size_t t) throw (std::bad_alloc)
00532 {
00533   void *p = memalign(16, t);
00534   if(!p) {
00535     #ifdef _OLD_CPP_COMPILER_    
00536     throw bad_alloc();
00537     #endif  // _OLD_CPP_COMPILER_    
00538   }    
00539   if(((unsigned int)(p))%16)
00540   {
00541     cerr << "\n\noperator new: bad pointer alignment (ron_base.hh)\n\n";
00542     exit(-1);
00543   }
00544 #ifdef GLOBAL_NEW_MEMORY
00545   GLOBAL_NEW_MEMORY_VAL += (unsigned long)(t);
00546 #endif //GLOBAL_NEW_MEMORY
00547 #ifdef DEBUG_NEW
00548   cout << "\nAllocating " << t << " bytes! (new)" << endl;
00549 #ifdef GLOBAL_NEW_MEMORY
00550   cout << "Total allocated memory: " << GLOBAL_NEW_MEMORY_VAL << " bytes" << endl;
00551 #endif //GLOBAL_NEW_MEMORY
00552 #endif // DEBUG_NEW
00553   return(p);
00554 }
00555 
00556 inline void operator delete[](void *p) throw() ;
00557 inline void operator delete[](void *p) throw()
00558 {
00559 #ifdef DEBUG_NEW
00560   cout << "Freeing memory (delete[])" << endl;
00561 #endif // DEBUG_NEW
00562   free(p);
00563 }
00564 inline void operator delete(void *p) throw() ;
00565 inline void operator delete(void *p) throw()
00566 {
00567 #ifdef DEBUG_NEW
00568   cout << "Freeing memory (delete)" << endl;
00569 #endif // DEBUG_NEW
00570   free(p);
00571 }
00572 
00573 
00574 
00575 
00576 
00577 
00580 
00592 inline cplx* NewCplx(int N)
00593 {
00594   cplx * start_ptr = (cplx*) memalign(16,N*sizeof(cplx));
00595 
00596   if (!start_ptr)
00597     {
00598     cerr << "NewCplx: null pointer \n";
00599     exit(-1);
00600     }
00601 
00602   if((unsigned int)(start_ptr) % 16)
00603    {
00604      cerr << "NewCplx: Unaligned pointer\n"; 
00605      exit(-1);
00606    }
00607 
00608   cplx * ptr = start_ptr;
00609   cplx * end_ptr = start_ptr + N;
00610 
00611   for( ; ptr < end_ptr; ptr++)
00612     *ptr = 0.0;
00613 
00614   return start_ptr;  
00615 };
00616 
00617 // ##############################
00618 
00621 
00632 inline double* NewDouble(int N)
00633 {
00634   double * start_ptr = (double*) memalign(16,N*sizeof(double));
00635 
00636   if((!start_ptr) || ((unsigned int)(start_ptr) % 16))
00637    {
00638      cerr << "NewDouble: null or unaligned pointer\n"; 
00639      exit(-1);
00640    }
00641 
00642   double * ptr = start_ptr;
00643   double * end_ptr = start_ptr + N;
00644 
00645   for( ; ptr < end_ptr; ptr++)
00646     *ptr = 0.0;
00647 
00648   return start_ptr;  
00649 
00650 };
00651 
00652 // ##############################
00653 
00656 
00668 inline int* NewInt(int N)
00669 {
00670   int * start_ptr = (int*) memalign(16,N*sizeof(int));
00671 
00672   if((!start_ptr) || ((unsigned int)(start_ptr) % 16))
00673    {
00674      cerr << "NewInt: null or unaligned pointer\n"; 
00675      exit(-1);
00676    }
00677 
00678   int * ptr = start_ptr;
00679   int * end_ptr = start_ptr + N;
00680 
00681   for( ; ptr < end_ptr; ptr++)
00682     *ptr = 0;
00683 
00684   return start_ptr;  
00685 
00686 };
00687 
00689 
00690 inline void FreeCplx(cplx * ptr) { free(ptr); };
00691 
00693 
00694 inline void FreeDouble(double * ptr) { free(ptr); };
00695 
00697 
00698 inline void FreeInt(int * ptr) { free(ptr); };
00699 
00700 
00701 // ##### This class was created by Ronald Holzloehner
00702 class cfftw
00703 {
00704     int N, N_half;
00705     fftw_plan  forw, backw;
00706     cplx  *shift_work;
00707     int shift_len1, shift_len2;
00708     
00709   public:
00710 
00712 
00713     double T;
00714 
00716 
00717     double F;
00718 
00720  
00721     double  delta_f;
00722     double  delta_t;
00723     cplx *work;
00724 
00726 
00727     cfftw(int N, double T);
00728     
00729     ~cfftw();
00730 
00732     void FFT(cplx *in, cplx *out);
00733 
00735     void IFFT(cplx *in, cplx *out);
00736     void fftshift(cplx *in);
00737     void ifftshift(cplx *in);
00738 
00739 
00740     void timewindow(cplx *in, double T_half, double T_001);
00741 
00742     // gives frequency at index i after FFT() ran
00743     // frequencies go like  0 1 2 3 -4 -3 -2 -1  (N=8)
00744     // input in [0, N-1], output in [-N/2, N/2-1]
00745 
00748 
00749     inline double freq(int i) {return delta_f 
00750                 *( (i < N_half)? (i):(i-N) ); };
00751 
00752     // gives index of frequency with index k after FFT() ran
00753     // input in [-N/2, N/2-1], output in [0, N-1]
00754 
00757 
00758     inline int index(int k) {return ( (k >= 0)? (k):(k+N) ); };
00759 
00760     inline int give_N(void) {return N;};
00761 
00762     // return true if we are using FFTW-GEL, false if not
00763 
00764     inline bool is_GEL(void) {return(strstr(fftw_version, "GEL")!=0);};
00765 
00766 };
00767 
00768 //## These lines must be commented for the new GNU C++ compiler
00769 // ##### Additional function used by the methods of cfftw
00770 #ifdef _OLD_CPP_COMPILER_
00771 template <class T> inline T max(T,T);
00772 template <class T> inline T max(T a, T bb)
00773 {
00774   return  ((a >= bb)? a:bb);
00775 }
00776 inline cplx max(cplx &a, cplx &bb);
00777 #endif // _OLD_CPP_COMPILER_
00778 //## End of the lines that must be included for the old GNU C++ compiler of malkhut
00779 
00780 
00781 inline cplx max(cplx &a, cplx &bb)
00782 {
00783   return (norm(a) >= norm(bb))? a:bb;
00784 }
00785 
00786 
00787 // ##### Example of use of cfftw
00788 /*****************************  All these lines are commented
00789 int main(void)     
00790 {
00791 cfftw *fft; 
00792 int N;
00793 cout "\n Enter N: " << endl;
00794 cin >> N;
00795 double T = 1.0;
00796 fft = new cfftw(N, T, FFTW_ESTIMATE);
00797 int i;
00798 cplx *time = new cplx[N];
00799 cplx *freq = new cplx[N];
00800 for(i=0; i<N; i++)
00801   in[i] = i;  // put in something  
00802 fft->FFT(time, freq);
00803 fft->fftshift(freq);
00804 // do something...
00805 fft->ifftshift(freq);
00806 fft->IFFT(freq, time);
00807 }
00808 *************************************/ // end of comment
00809 
00810 #endif /* _CFFTW_HH_ */ 
00811 
00812 #endif /* ifndef _USING_FFTW3_ */
00813 
00814 
00815 

Generated on Fri Jul 2 2010 12:57:45 for OCS by  doxygen 1.7.1