numerics
Loading...
Searching...
No Matches
fft.hpp
Go to the documentation of this file.
1/// @file spectral/fft.hpp
2/// @brief FFT interface with backend dispatch.
3///
4/// Each module defines its own backend enum for the choices relevant to it.
5/// This enum covers spectral transforms; linalg uses num::Backend in core/policy.hpp.
6///
7/// Backends:
8/// FFTBackend::seq -- native Cooley-Tukey radix-2 DIT; always available.
9/// Input length must be a power of two.
10/// FFTBackend::fftw -- FFTW3 (AVX / NEON optimised); requires NUMERICS_HAS_FFTW.
11/// Falls back to FFTBackend::seq automatically if FFTW3 is absent.
12///
13/// Conventions (both backends):
14/// Forward DFT: X[k] = sum_{j=0}^{n-1} x[j] * exp(-2*pi*i*j*k/n)
15/// Inverse DFT: unnormalised (FFTW convention). Divide by n to recover x.
16/// rfft output: n/2+1 complex bins (Hermitian symmetry of real input).
17#pragma once
18
19#include "core/types.hpp"
20#include "core/vector.hpp"
21
22namespace num {
23namespace spectral {
24
25/// @brief Selects which backend handles an FFT operation.
26enum class FFTBackend {
27 seq, ///< Native Cooley-Tukey radix-2 DIT -- always available (power-of-two only)
28 simd, ///< Handwritten AVX2 / NEON butterfly -- falls back to seq if unavailable
29 stdsimd, ///< std::experimental::simd butterfly -- requires NUMERICS_HAS_STD_SIMD
30 fftw, ///< FFTW3 (mixed-radix, AVX / NEON optimised) -- requires NUMERICS_HAS_FFTW
31};
32
33// Convenience constants -- use these at call sites:
34// fft(in, out, num::spectral::fftw);
35inline constexpr FFTBackend seq = FFTBackend::seq;
36inline constexpr FFTBackend fftw = FFTBackend::fftw;
39
40/// True when FFTW3 was found at configure time.
41inline constexpr bool has_fftw =
42#ifdef NUMERICS_HAS_FFTW
43 true;
44#else
45 false;
46#endif
47
48/// True when handwritten AVX2 or NEON backend is available.
49inline constexpr bool has_fft_simd =
50#if defined(NUMERICS_HAS_AVX2) || defined(NUMERICS_HAS_NEON)
51 true;
52#else
53 false;
54#endif
55
56/// True when std::experimental::simd is available.
57inline constexpr bool has_fft_stdsimd =
58#ifdef NUMERICS_HAS_STD_SIMD
59 true;
60#else
61 false;
62#endif
63
64/// Automatically selected at configure time: fftw > simd > seq.
66#ifdef NUMERICS_HAS_FFTW
68#elif defined(NUMERICS_HAS_AVX2) || defined(NUMERICS_HAS_NEON)
70#else
72#endif
73
74// -- One-shot transforms --------------------------------------------------
75
76/// @brief Forward complex DFT. out must be pre-allocated to in.size().
77void fft(const CVector& in, CVector& out,
79
80/// @brief Inverse complex DFT (unnormalised: result = n * true_inverse).
81void ifft(const CVector& in, CVector& out,
83
84/// @brief Real-to-complex forward DFT. out must be pre-allocated to n/2+1.
85void rfft(const Vector& in, CVector& out,
87
88/// @brief Complex-to-real inverse DFT (unnormalised).
89/// @param n Length of the real output (must satisfy in.size() == n/2+1).
90void irfft(const CVector& in, int n, Vector& out,
92
93// -- Reusable plan --------------------------------------------------------
94
95/// @brief Precomputed plan for repeated complex transforms of a fixed size.
96///
97/// @code
98/// num::spectral::FFTPlan plan(1024); // forward, default backend
99/// for (auto& frame : frames)
100/// plan.execute(frame, spectrum); // O(n log n), no allocation
101/// @endcode
102class FFTPlan {
103public:
104 /// @param n Transform size (must be power of two for FFTBackend::seq)
105 /// @param forward true = forward DFT, false = inverse DFT
106 /// @param b Backend to use (default: default_fft_backend)
107 explicit FFTPlan(int n, bool forward = true,
109 ~FFTPlan();
110
111 FFTPlan(const FFTPlan&) = delete;
112 FFTPlan& operator=(const FFTPlan&) = delete;
113
114 void execute(const CVector& in, CVector& out) const;
115
116 int size() const { return n_; }
117 FFTBackend backend() const { return backend_; }
118
119private:
120 int n_;
121 FFTBackend backend_;
122 void* impl_; // backends::seq::FFTPlanImpl or backends::fftw::FFTPlanImpl
123};
124
125} // namespace spectral
126} // namespace num
Dense vector with optional GPU storage, templated over scalar type T.
Definition vector.hpp:23
Precomputed plan for repeated complex transforms of a fixed size.
Definition fft.hpp:102
FFTBackend backend() const
Definition fft.hpp:117
FFTPlan(const FFTPlan &)=delete
int size() const
Definition fft.hpp:116
void execute(const CVector &in, CVector &out) const
Definition fft.cpp:124
FFTPlan & operator=(const FFTPlan &)=delete
Core type definitions.
void ifft(const CVector &in, CVector &out, FFTBackend b=default_fft_backend)
Inverse complex DFT (unnormalised: result = n * true_inverse).
Definition fft.cpp:31
void fft(const CVector &in, CVector &out, FFTBackend b=default_fft_backend)
Forward complex DFT. out must be pre-allocated to in.size().
Definition fft.cpp:15
FFTBackend
Selects which backend handles an FFT operation.
Definition fft.hpp:26
@ simd
Handwritten AVX2 / NEON butterfly – falls back to seq if unavailable.
@ stdsimd
std::experimental::simd butterfly – requires NUMERICS_HAS_STD_SIMD
@ seq
Native Cooley-Tukey radix-2 DIT – always available (power-of-two only)
@ 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).
Definition fft.cpp:61
constexpr bool has_fft_simd
True when handwritten AVX2 or NEON backend is available.
Definition fft.hpp:49
constexpr FFTBackend fftw
Definition fft.hpp:36
constexpr FFTBackend fft_stdsimd
Definition fft.hpp:38
constexpr FFTBackend default_fft_backend
Automatically selected at configure time: fftw > simd > seq.
Definition fft.hpp:65
constexpr FFTBackend fft_simd
Definition fft.hpp:37
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.
Definition fft.cpp:46
constexpr bool has_fft_stdsimd
True when std::experimental::simd is available.
Definition fft.hpp:57
constexpr bool has_fftw
True when FFTW3 was found at configure time.
Definition fft.hpp:41
constexpr FFTBackend seq
Definition fft.hpp:35
constexpr T ipow(T x) noexcept
Compute x^N at compile time via repeated squaring.
Vector operations.