2#include "backends/seq/impl.hpp"
5#ifdef NUMERICS_HAS_STD_SIMD
16 if (
out.size() !=
in.size())
17 throw std::invalid_argument(
"fft: in and out must have the same size");
18#ifdef NUMERICS_HAS_FFTW
21#if defined(NUMERICS_HAS_AVX2) || defined(NUMERICS_HAS_NEON)
24#ifdef NUMERICS_HAS_STD_SIMD
32 if (
out.size() !=
in.size())
33 throw std::invalid_argument(
"ifft: in and out must have the same size");
34#ifdef NUMERICS_HAS_FFTW
37#if defined(NUMERICS_HAS_AVX2) || defined(NUMERICS_HAS_NEON)
40#ifdef NUMERICS_HAS_STD_SIMD
47 if (
static_cast<int>(
out.size()) !=
static_cast<int>(
in.size()) / 2 + 1)
48 throw std::invalid_argument(
"rfft: out must have size n/2+1");
49#ifdef NUMERICS_HAS_FFTW
52#if defined(NUMERICS_HAS_AVX2) || defined(NUMERICS_HAS_NEON)
55#ifdef NUMERICS_HAS_STD_SIMD
62 if (
static_cast<int>(
in.size()) != n / 2 + 1)
63 throw std::invalid_argument(
"irfft: in must have size n/2+1");
64 if (
static_cast<int>(
out.size()) != n)
65 throw std::invalid_argument(
"irfft: out must have size n");
66#ifdef NUMERICS_HAS_FFTW
69#if defined(NUMERICS_HAS_AVX2) || defined(NUMERICS_HAS_NEON)
72#ifdef NUMERICS_HAS_STD_SIMD
81#ifdef NUMERICS_HAS_FFTW
83 impl_ =
new backends::fftw::FFTPlanImpl(n,
forward);
87#if defined(NUMERICS_HAS_AVX2) || defined(NUMERICS_HAS_NEON)
93#ifdef NUMERICS_HAS_STD_SIMD
95 impl_ =
new backends::stdsimd::FFTPlanImpl(n, !
forward);
103#ifdef NUMERICS_HAS_FFTW
105 delete static_cast<backends::fftw::FFTPlanImpl*
>(impl_);
109#if defined(NUMERICS_HAS_AVX2) || defined(NUMERICS_HAS_NEON)
115#ifdef NUMERICS_HAS_STD_SIMD
117 delete static_cast<backends::stdsimd::FFTPlanImpl*
>(impl_);
125 if (
static_cast<int>(
in.size()) != n_ ||
static_cast<int>(
out.size()) != n_)
126 throw std::invalid_argument(
"FFTPlan::execute: size mismatch");
127#ifdef NUMERICS_HAS_FFTW
129 static_cast<backends::fftw::FFTPlanImpl*
>(impl_)->
execute(
in,
out);
133#if defined(NUMERICS_HAS_AVX2) || defined(NUMERICS_HAS_NEON)
140#ifdef NUMERICS_HAS_STD_SIMD
143 static_cast<backends::stdsimd::FFTPlanImpl*
>(impl_)->
execute(
out);
Dense vector with optional GPU storage, templated over scalar type T.
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.
@ simd
Handwritten AVX2 / NEON butterfly – falls back to seq if unavailable.
@ stdsimd
std::experimental::simd butterfly – requires NUMERICS_HAS_STD_SIMD
@ fftw
FFTW3 (mixed-radix, AVX / NEON optimised) – requires NUMERICS_HAS_FFTW.
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.
constexpr T ipow(T x) noexcept
Compute x^N at compile time via repeated squaring.
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.