2#include "backends/seq/impl.hpp"
5#ifdef NUMERICS_HAS_STD_SIMD
17 throw std::invalid_argument(
"fft: in and out must have the same size");
18#ifdef NUMERICS_HAS_FFTW
20 backends::fftw::fft(in, out);
24#if defined(NUMERICS_HAS_AVX2) || defined(NUMERICS_HAS_NEON)
30#ifdef NUMERICS_HAS_STD_SIMD
32 backends::stdsimd::fft(in, out);
42 throw std::invalid_argument(
"ifft: in and out must have the same size");
43#ifdef NUMERICS_HAS_FFTW
45 backends::fftw::ifft(in, out);
49#if defined(NUMERICS_HAS_AVX2) || defined(NUMERICS_HAS_NEON)
55#ifdef NUMERICS_HAS_STD_SIMD
57 backends::stdsimd::ifft(in, out);
65 if (
static_cast<int>(out.
size()) !=
static_cast<int>(in.
size()) / 2 + 1)
66 throw std::invalid_argument(
"rfft: out must have size n/2+1");
67#ifdef NUMERICS_HAS_FFTW
69 backends::fftw::rfft(in, out);
73#if defined(NUMERICS_HAS_AVX2) || defined(NUMERICS_HAS_NEON)
79#ifdef NUMERICS_HAS_STD_SIMD
81 backends::stdsimd::rfft(in, out);
89 if (
static_cast<int>(in.
size()) != n / 2 + 1)
90 throw std::invalid_argument(
"irfft: in must have size n/2+1");
91 if (
static_cast<int>(out.
size()) != n)
92 throw std::invalid_argument(
"irfft: out must have size n");
93#ifdef NUMERICS_HAS_FFTW
95 backends::fftw::irfft(in, n, out);
99#if defined(NUMERICS_HAS_AVX2) || defined(NUMERICS_HAS_NEON)
105#ifdef NUMERICS_HAS_STD_SIMD
107 backends::stdsimd::irfft(in, n, out);
119#ifdef NUMERICS_HAS_FFTW
121 impl_ =
new backends::fftw::FFTPlanImpl(n, forward);
125#if defined(NUMERICS_HAS_AVX2) || defined(NUMERICS_HAS_NEON)
131#ifdef NUMERICS_HAS_STD_SIMD
133 impl_ =
new backends::stdsimd::FFTPlanImpl(n, !forward);
141#ifdef NUMERICS_HAS_FFTW
143 delete static_cast<backends::fftw::FFTPlanImpl*
>(impl_);
147#if defined(NUMERICS_HAS_AVX2) || defined(NUMERICS_HAS_NEON)
153#ifdef NUMERICS_HAS_STD_SIMD
155 delete static_cast<backends::stdsimd::FFTPlanImpl*
>(impl_);
163 if (
static_cast<int>(in.
size()) != n_ ||
static_cast<int>(out.
size()) != n_)
164 throw std::invalid_argument(
"FFTPlan::execute: size mismatch");
165#ifdef NUMERICS_HAS_FFTW
167 static_cast<backends::fftw::FFTPlanImpl*
>(impl_)->
execute(in, out);
171#if defined(NUMERICS_HAS_AVX2) || defined(NUMERICS_HAS_NEON)
173 for (
idx i = 0; i < static_cast<idx>(n_); ++i)
179#ifdef NUMERICS_HAS_STD_SIMD
181 for (
idx i = 0; i < static_cast<idx>(n_); ++i)
183 static_cast<backends::stdsimd::FFTPlanImpl*
>(impl_)->
execute(out);
187 for (
idx i = 0; i < static_cast<idx>(n_); ++i)
Dense vector with optional GPU storage, templated over scalar type T.
constexpr idx size() const noexcept
FFTPlan(int n, bool forward=true, FFTBackend b=default_fft_backend)
void execute(const CVector &in, CVector &out) const
FFT interface with backend dispatch.
void irfft(const num::CVector &in, int n, num::Vector &out)
void ifft(const num::CVector &in, num::CVector &out)
void fft(const num::CVector &in, num::CVector &out)
void rfft(const num::Vector &in, num::CVector &out)
void ifft(const num::CVector &in, num::CVector &out)
void rfft(const num::Vector &in, num::CVector &out)
void irfft(const num::CVector &in, int n, num::Vector &out)
void fft(const num::CVector &in, num::CVector &out)
void ifft(const CVector &in, CVector &out, FFTBackend b=default_fft_backend)
Inverse complex DFT (unnormalised: result = n * true_inverse).
void fft(const CVector &in, CVector &out, FFTBackend b=default_fft_backend)
Forward complex DFT. out must be pre-allocated to in.size().
FFTBackend
Selects which backend handles an FFT operation.
void irfft(const CVector &in, int n, Vector &out, FFTBackend b=default_fft_backend)
Complex-to-real inverse DFT (unnormalised).
void rfft(const Vector &in, CVector &out, FFTBackend b=default_fft_backend)
Real-to-complex forward DFT. out must be pre-allocated to n/2+1.
FFTW3 backend wrappers. Only included by src/spectral/fft.cpp.
Handwritten AVX2 / NEON butterfly for the FFT.
std::experimental::simd butterfly for FFT.
Precomputed twiddle factors + SIMD butterfly execution.