38 #ifndef __INCLUDE_FFT_H__
39 #define __INCLUDE_FFT_H__
42 #ifndef __INCLUDE_MIST_H__
46 #ifndef __INCLUDE_MIST_THREAD__
47 #include "../thread.h"
50 #ifndef __INCLUDE_FFT_UTIL_H__
55 #if defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
56 #define USE_CDFT_WINTHREADS
57 #define USE_FFT2D_WINTHREADS
58 #define USE_FFT3D_WINTHREADS
60 #define USE_CDFT_PTHREADS
61 #define USE_FFT2D_PTHREADS
62 #define USE_FFT3D_PTHREADS
86 template <
class T1,
class T2,
class Allocator1,
class Allocator2 >
87 bool _fft(
const array< T1, Allocator1 > &in, array< T2, Allocator2 > &out )
89 if( !__fft_util__::size_check( (
unsigned int ) in.size( ) ) )
95 typedef typename Allocator1::size_type size_type;
97 __fft_util__::FFT_MEMORY1 mem;
99 if( !__fft_util__::allocate_memory( mem,
101 static_cast< size_t >( std::sqrt( static_cast< double >( in.size( ) ) ) + 3 ),
104 __fft_util__::deallocate_memory( mem );
108 double *data = mem.data;
112 for( i = 0 ; i < in.size( ) ; i++ )
114 std::complex< double > c( __fft_util__::convert_complex< T1 >::convert_to( in[ i ] ) );
115 data[ i * 2 ] = c.real( );
116 data[ i * 2 + 1 ] = c.imag( );
121 ooura_fft::cdft( static_cast< int >( in.size( ) * 2 ), -1, data, ip, w );
123 out.resize( in.size( ) );
125 for( i = 0 ; i < out.size( ) ; i++ )
127 out[ i ] = __fft_util__::convert_complex< T2 >::convert_from( data[ 2 * i ], data[ 2 * i + 1 ] );
130 __fft_util__::deallocate_memory( mem );
137 template <
class T1,
class T2,
class Allocator1,
class Allocator2 >
138 bool _ifft(
const array< T1, Allocator1 > &in, array< T2, Allocator2 > &out )
140 if( !__fft_util__::size_check( (
unsigned int ) in.size( ) ) )
146 typedef typename Allocator1::size_type size_type;
148 __fft_util__::FFT_MEMORY1 mem;
150 if( !__fft_util__::allocate_memory( mem,
152 static_cast< size_t >( std::sqrt( static_cast< double >( in.size( ) ) ) + 3 ),
155 __fft_util__::deallocate_memory( mem );
159 double *data = mem.data;
163 for( i = 0 ; i < in.size( ) ; i++ )
165 std::complex< double > c( __fft_util__::convert_complex< T1 >::convert_to( in[ i ] ) );
166 data[ i * 2 ] = c.real( );
167 data[ i * 2 + 1 ] = c.imag( );
172 ooura_fft::cdft( static_cast< int >(in.size( ) * 2), 1, data, ip, w );
174 out.resize( in.size( ) );
176 double __value__ = 1.0 / in.size( );
177 for( i = 0 ; i < out.size( ) ; i++ )
179 out[ i ] = __fft_util__::convert_complex< T2 >::convert_from( data[ 2 * i ] * __value__, data[ 2 * i + 1 ] * __value__ );
182 __fft_util__::deallocate_memory( mem );
199 template <
class T1,
class T2,
class Allocator1,
class Allocator2 >
202 return _fft( in, out );
217 template <
class T1,
class T2,
class Allocator1,
class Allocator2 >
220 return _ifft( in, out );
236 template <
class T1,
class T2,
class Allocator1,
class Allocator2 >
239 if( !__fft_util__::size_check( (
unsigned int ) in.
width( ) ) || !__fft_util__::size_check( (
unsigned int ) in.
height( ) ) )
244 typedef typename Allocator1::size_type size_type;
246 __fft_util__::FFT_MEMORY2 mem;
248 if( !__fft_util__::allocate_memory( mem,
251 8 * in.
width( ) * FFT2D_MAX_THREADS,
252 static_cast< size_t >( std::sqrt( static_cast< double >( size ) ) + 3 ),
255 __fft_util__::deallocate_memory( mem );
259 double **data = mem.data;
264 for( i = 0 ; i < in.
width( ) ; i++ )
266 for( j = 0 ; j < in.
height( ) ; j++ )
268 std::complex< double > c( __fft_util__::convert_complex< T1 >::convert_to( in( i, j ) ) );
269 data[ i ][ 2 * j ] = c.real( );
270 data[ i ][ 2 * j + 1 ] = c.imag( );
276 ooura_fft::cdft2d( static_cast< int >( in.
width( ) ), static_cast< int >( in.
height( ) * 2 ), -1, data, t, ip, w );
281 for( i = 0 ; i < out.
width( ) ; i++ )
283 for( j = 0 ; j < out.
height( ) ; j++ )
285 out( i, j ) = __fft_util__::convert_complex< T2 >::convert_from( data[ i ][ 2 * j ], data[ i ][ 2 * j + 1 ] );
289 __fft_util__::deallocate_memory( mem );
306 template <
class T1,
class T2,
class Allocator1,
class Allocator2 >
309 if( !__fft_util__::size_check( (
unsigned int ) in.
width( ) ) || !__fft_util__::size_check( (
unsigned int ) in.
height( ) ) )
314 typedef typename Allocator1::size_type size_type;
316 __fft_util__::FFT_MEMORY2 mem;
318 if( !__fft_util__::allocate_memory( mem,
321 8 * in.
width( ) * FFT2D_MAX_THREADS,
322 static_cast< size_t >( std::sqrt( static_cast< double >( size ) ) + 3 ),
325 __fft_util__::deallocate_memory( mem );
329 double **data = mem.data;
334 for( i = 0 ; i < in.
width( ) ; i++ )
336 for( j = 0 ; j < in.
height( ) ; j++ )
338 std::complex< double > c( __fft_util__::convert_complex< T1 >::convert_to( in( i, j ) ) );
339 data[ i ][ 2 * j ] = c.real( );
340 data[ i ][ 2 * j + 1 ] = c.imag( );
346 ooura_fft::cdft2d( static_cast< int >(in.
width( )), static_cast< int >(in.
height( ) * 2), 1, data, t, ip, w );
350 double __value__ = 1.0 / in.
size( );
351 for( i = 0 ; i < out.
width( ) ; i++ )
353 for( j = 0 ; j < out.
height( ) ; j++ )
355 out( i, j ) = __fft_util__::convert_complex< T2 >::convert_from( data[ i ][ 2 * j ] * __value__, data[ i ][ 2 * j + 1 ] * __value__ );
359 __fft_util__::deallocate_memory( mem );
377 template <
class T1,
class T2,
class Allocator1,
class Allocator2 >
380 if( !__fft_util__::size_check( (
unsigned int ) in.
width( ) ) ||
381 !__fft_util__::size_check( (
unsigned int ) in.
height( ) ) ||
382 !__fft_util__::size_check( (
unsigned int ) in.
depth( ) ) )
387 typedef typename Allocator1::size_type size_type;
389 __fft_util__::FFT_MEMORY3 mem;
391 if( !__fft_util__::allocate_memory( mem,
395 8 * size * FFT3D_MAX_THREADS,
396 static_cast< size_t >( std::sqrt( static_cast< double >( size ) ) + 3 ),
399 __fft_util__::deallocate_memory( mem );
403 double ***data = mem.data;
408 for( i = 0 ; i < in.
width( ) ; i++ )
410 for( j = 0 ; j < in.
height( ) ; j++ )
412 for( k = 0 ; k < in.
depth( ) ; k++ )
414 std::complex< double > c( __fft_util__::convert_complex< T1 >::convert_to( in( i, j, k ) ) );
415 data[ i ][ j ][ 2 * k ] = c.real( );
416 data[ i ][ j ][ 2 * k + 1 ] = c.imag( );
423 ooura_fft::cdft3d( static_cast< int >( in.
width( ) ), static_cast< int >( in.
height( ) ), static_cast< int >( in.
depth( ) * 2 ), -1, data, t, ip, w );
427 for( i = 0 ; i < out.
width( ) ; i++ )
429 for( j = 0 ; j < out.
height( ) ; j++ )
431 for( k = 0 ; k < out.
depth( ) ; k++ )
433 out( i, j, k ) = __fft_util__::convert_complex< T2 >::convert_from( data[ i ][ j ][ 2 * k ], data[ i ][ j ][ 2 * k + 1 ] );
438 __fft_util__::deallocate_memory( mem );
456 template <
class T1,
class T2,
class Allocator1,
class Allocator2 >
459 if( !__fft_util__::size_check( (
unsigned int ) in.
width( ) ) ||
460 !__fft_util__::size_check( (
unsigned int ) in.
height( ) ) ||
461 !__fft_util__::size_check( (
unsigned int ) in.
depth( ) ) )
466 typedef typename Allocator1::size_type size_type;
468 __fft_util__::FFT_MEMORY3 mem;
470 if( !__fft_util__::allocate_memory( mem,
474 8 * size * FFT3D_MAX_THREADS,
475 static_cast< size_t >( std::sqrt( static_cast< double >( size ) ) + 3 ),
478 __fft_util__::deallocate_memory( mem );
482 double ***data = mem.data;
487 for( i = 0 ; i < in.
width( ) ; i++ )
489 for( j = 0 ; j < in.
height( ) ; j++ )
491 for( k = 0 ; k < in.
depth( ) ; k++ )
493 std::complex< double > c( __fft_util__::convert_complex< T1 >::convert_to( in( i, j, k ) ) );
494 data[ i ][ j ][ 2 * k ] = c.real( );
495 data[ i ][ j ][ 2 * k + 1 ] = c.imag( );
502 ooura_fft::cdft3d( static_cast< int >( in.
width( ) ), static_cast< int >( in.
height( ) ), static_cast< int >( in.
depth( ) * 2 ), 1, data, t, ip, w );
506 double __value__ = 1.0 / in.
size( );
507 for( i = 0 ; i < out.
width( ) ; i++ )
509 for( j = 0 ; j < out.
height( ) ; j++ )
511 for( k = 0 ; k < out.
depth( ) ; k++ )
513 out( i, j, k ) = __fft_util__::convert_complex< T2 >::convert_from( data[ i ][ j ][ 2 * k ] * __value__, data[ i ][ j ][ 2 * k + 1 ] * __value__ );
518 __fft_util__::deallocate_memory( mem );