1 template < typename T >
2 JFFT<T>::JFFT( bool use_threading ) : threading( use_threading ) {
3 static_assert( is_stdlib_container<T>::value, "JFFT::Input must be a container-like object.");
6 template < typename T >
11 template < typename T >
12 void JFFT<T>::SetUp( uint size ) {
21 fft_size = ( size%2 == 0 )?( size / 2 ):( ( size - 1 ) / 2 );
23 norm_factor = static_cast< typename T::value_type >( N );
25 //Setup multi-threading
28 int val = fftwf_init_threads();
30 //if val is equal to zero multithreading cannot be setup
32 std::string err_mesg = __func__;
33 err_mesg += "Could not setup multithreading.";
34 throw std::runtime_error(err_mesg);
36 //set plans to use what OpenMP has decided is a good number of
37 //threads (usually the number of processor cores)
38 fftwf_plan_with_nthreads(omp_get_max_threads());
44 std::string err_mesg = __func__;
45 err_mesg += "Could not allocate memory for FFT input buffer.";
46 throw std::runtime_error(err_mesg);
49 in = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * N);
53 std::string err_mesg = __func__;
54 err_mesg += "Could not allocate memory for FFT output buffer.";
55 throw std::runtime_error(err_mesg);
58 out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * N);
60 fftwf_make_planner_thread_safe();
61 p = fftwf_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
65 template < typename T >
66 void JFFT<T>::TearDown() {
68 fftwf_destroy_plan(p);
74 inline double abs_sqr( const fftwf_complex& z ) {
75 return z[0]*z[0] + z[1]*z[1];
78 template < typename T >
79 T JFFT<T>::PowerSpectrum( const T& input ) {
81 if( set_up == false ) {
82 std::string err_mesg = __func__;
83 err_mesg += "JFFT has not been set-up properly --";
84 err_mesg += " you must call JFFT::SetUp( uint size ) first.";
85 throw std::runtime_error(err_mesg);
88 // get upgradable access
89 boost::upgrade_lock<boost::shared_mutex> lock( monitor );
90 // get exclusive access
91 boost::upgrade_to_unique_lock<boost::shared_mutex> uniqueLock(lock);
93 std::cout << "N " << N << std::endl;
95 for ( uint i = 0; i < N ; i++ ) {
96 in[i][0] = input.at(i); //Real Part
97 in[i][1] = 0.0; //Imaginary part
103 output.reserve( fft_size );
105 auto N_sqr = norm_factor * norm_factor;
107 // Explicitly compute first element
108 auto C_0 = abs_sqr( out[0] );
111 output.push_back( C_0 );
113 for ( uint i = 1; i < fft_size - 1; i++ ) {
115 auto C_i = abs_sqr( out[i] ) + abs_sqr( out[N-i] );;
118 output.push_back( C_i );
122 // Explicitly compute last element
123 auto C_N_half = abs_sqr( out[ fft_size - 1 ] );
126 output.push_back( C_N_half );