Program Listing for File FFT.h

↰ Return to documentation for file (ADS/numeric/FFT.h)

/*--------------------------------------------------------------------------*/
/*------------------------------- File FFT.h -------------------------------*/
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/*----------------------------- DEFINITIONS --------------------------------*/
/*--------------------------------------------------------------------------*/

#ifndef __ADS_FFT
 #define __ADS_FFT
                      /* self-identification: #endif constant */

/*--------------------------------------------------------------------------*/
/*------------------------------ INCLUDES ----------------------------------*/
/*--------------------------------------------------------------------------*/

#include "ADS/Contract.h"

#include <algorithm>
#include <array>
#include <bit>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <iterator>
#include <memory>
#include <numbers>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>

#ifndef ADS_FFT_SIMD
 #if defined( __GNUC__ ) || defined( __clang__ )
  #if defined( __AVX__ )
   #define ADS_FFT_SIMD 4
  #elif defined( __SSE2__ ) || defined( __ARM_NEON )
   #define ADS_FFT_SIMD 2
  #else
   #define ADS_FFT_SIMD 0
  #endif
 #elif defined( _MSC_VER ) && ( defined( _M_X64 ) || defined( _M_IX86 ) )
  #if defined( __AVX__ )
   #define ADS_FFT_SIMD 4
  #elif defined( _M_X64 ) || ( defined( _M_IX86_FP ) && _M_IX86_FP >= 2 )
   #define ADS_FFT_SIMD 2
  #else
   #define ADS_FFT_SIMD 0
  #endif
 #else
  #define ADS_FFT_SIMD 0
 #endif
#endif

#ifndef ADS_FFT_INTRINSICS
 #if ( ADS_FFT_SIMD > 1 ) && ! ( defined( __GNUC__ ) || defined( __clang__ ) )
  #define ADS_FFT_INTRINSICS 1
 #else
  #define ADS_FFT_INTRINSICS 0
 #endif
#endif

#ifndef ADS_FFT_LEAN
 #if defined( __GNUC__ ) || defined( __clang__ )
  #define ADS_FFT_LEAN 0
 #else
  #define ADS_FFT_LEAN 1
 #endif
#endif

#if ADS_FFT_INTRINSICS
 #if ADS_FFT_SIMD > 4
  #error "ADS_FFT_INTRINSICS has the registers of SSE2 and AVX only"
 #endif
 #include <immintrin.h>
#endif

/*--------------------------------------------------------------------------*/
/*--------------------------- NAMESPACE ------------------------------------*/
/*--------------------------------------------------------------------------*/

namespace ADS {

using Complex = std::complex< double >;

[[nodiscard]] inline std::vector< Complex > dft(
                         const std::vector< Complex > & a , bool inverse );

template< class T >
inline void fft( std::complex< T > * a , std::size_t n , bool inverse );

template< class T >
inline void fft( std::vector< std::complex< T > > & a , bool inverse );

template< class T >
inline void fftMany( std::complex< T > * a , std::size_t n ,
                     std::size_t howmany , bool inverse );

template< class T >
inline void fftn( std::complex< T > * a ,
                  const std::vector< std::size_t > & dims , bool inverse );

template< class T >
inline void fft2( std::complex< T > * a , std::size_t rows ,
                  std::size_t cols , bool inverse );

template< class T >
inline void rfft( const T * x , std::size_t n , std::complex< T > * X );

template< class T >
[[nodiscard]] inline std::vector< std::complex< T > > rfft(
                                                const std::vector< T > & x );

template< class T >
inline void irfft( const std::complex< T > * X , std::size_t n , T * x );

template< class T >
[[nodiscard]] inline std::vector< T > irfft(
                                  const std::vector< std::complex< T > > & X ,
                                  std::size_t n );

template< class T >
inline void dct( T * x , std::size_t n , unsigned type );

template< class T >
inline void dct( std::vector< T > & x , unsigned type );

template< class T >
inline void dst( T * x , std::size_t n , unsigned type );

template< class T >
inline void dst( std::vector< T > & x , unsigned type );

[[nodiscard]] inline std::vector< double > convolve(
                                          const std::vector< double > & p ,
                                          const std::vector< double > & q );

template< class T >
[[nodiscard]] inline std::vector< T > convolve( const std::vector< T > & p ,
                                                const std::vector< T > & q );

/*--------------------------------------------------------------------------*/

}  // end( namespace ADS )

/*--------------------------------------------------------------------------*/
/*-------------------------- IMPLEMENTATION --------------------------------*/
/*--------------------------------------------------------------------------*/

#include "ADS/numeric/impl/FFT.tpp"

/*--------------------------------------------------------------------------*/

#endif  /* FFT.h included */

/*--------------------------------------------------------------------------*/
/*----------------------------- End File FFT.h -----------------------------*/
/*--------------------------------------------------------------------------*/