// Copyright (C) 2023 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #ifndef DLIB_FFT_DETAILS_Hh_ #define DLIB_FFT_DETAILS_Hh_ #include <complex> #include "fft_size.h" namespace dlib { // ---------------------------------------------------------------------------------------- constexpr bool is_power_of_two ( const unsigned long n ) /*! ensures - returns true if value contains a power of two and false otherwise. As a special case, we also consider 0 to be a power of two. !*/ { return n == 0 ? true : (n & (n - 1)) == 0; } // ---------------------------------------------------------------------------------------- constexpr long fftr_nc_size( long nc ) /*! ensures - returns the output dimension of a 1D real FFT !*/ { return nc == 0 ? 0 : nc/2+1; } // ---------------------------------------------------------------------------------------- constexpr long ifftr_nc_size( long nc ) /*! ensures - returns the output dimension of an inverse 1D real FFT !*/ { return nc == 0 ? 0 : 2*(nc-1); } // ---------------------------------------------------------------------------------------- template<typename T> void fft(const fft_size& dims, const std::complex<T>* in, std::complex<T>* out, bool is_inverse); /*! requires - T must be either float or double - dims represents the dimensions of both `in` and `out` - dims.num_dims() > 0 ensures - performs an FFT on `in` and stores the result in `out`. - if `is_inverse` is true, a backward FFT is performed, otherwise a forward FFT is performed. !*/ // ---------------------------------------------------------------------------------------- template<typename T> void fftr(const fft_size& dims, const T* in, std::complex<T>* out); /*! requires - T must be either float or double - dims represent the dimensions of `in` - `in` has dimensions {dims[0], dims[1], ..., dims[-2], dims[-1]} - `out` has dimensions {dims[0], dims[1], ..., dims[-2], dims[-1]/2+1} - dims.num_dims() > 0 - dims.back() must be even ensures - performs a real FFT on `in` and stores the result in `out`. !*/ // ---------------------------------------------------------------------------------------- template<typename T> void ifftr(const fft_size& dims, const std::complex<T>* in, T* out); /*! requires - T must be either float or double - dims represent the dimensions of `out` - `in` has dimensions {dims[0], dims[1], ..., dims[-2], dims[-1]/2+1} - `out` has dimensions {dims[0], dims[1], ..., dims[-2], dims[-1]} - dims.num_dims() > 0 - dims.back() must be even ensures - performs an inverse real FFT on `in` and stores the result in `out`. !*/ // ---------------------------------------------------------------------------------------- } #endif //DLIB_FFT_DETAILS_Hh_