13static constexpr double TWO_PI = 6.283185307179586476925286766559;
17 for (
num::idx i = 1, j = 0; i < n; ++i) {
19 for (; j & bit; bit >>= 1) j ^= bit;
21 if (i < j) std::swap(a[i], a[j]);
27 if (n == 0 || (n & (n - 1)))
28 throw std::invalid_argument(
"FFT: length must be a power of two");
30 for (
num::idx len = 2; len <= n; len <<= 1) {
31 double ang = TWO_PI /
static_cast<double>(len) * (invert ? 1.0 : -1.0);
32 num::cplx wlen{std::cos(ang), std::sin(ang)};
33 for (
num::idx i = 0; i < n; i += len) {
35 for (
num::idx j = 0; j < len / 2; ++j) {
39 a[i + j + len / 2] = u - v;
59 for (
num::idx i = 0; i < n; ++i) tmp[i] = {in[i], 0.0};
61 for (
num::idx k = 0; k < n / 2 + 1; ++k) out[k] = tmp[k];
66 for (
num::idx k = 0; k < static_cast<num::idx>(n / 2 + 1); ++k)
68 for (
num::idx k = 1; k < static_cast<num::idx>((n - 1) / 2 + 1); ++k)
69 tmp[
static_cast<num::idx>(n) - k] = std::conj(in[k]);
71 for (
num::idx i = 0; i < static_cast<num::idx>(n); ++i) out[i] = tmp[i].real();
81 if (n_ == 0 || (n_ & (n_ - 1)))
82 throw std::invalid_argument(
"FFTPlan: length must be a power of two");
83 for (
int len = 2; len <= n_; len <<= 1) {
84 double ang = TWO_PI /
static_cast<double>(len) * (inv ? 1.0 : -1.0);
85 num::cplx wlen{std::cos(ang), std::sin(ang)};
86 std::vector<num::cplx> tw(len / 2);
88 for (
int j = 0; j < len / 2; ++j) { tw[j] = w; w *= wlen; }
96 for (
int len = 2; len <=
n; len <<= 1, ++stage) {
98 for (
int i = 0; i <
n; i += len) {
99 for (
int j = 0; j < len / 2; ++j) {
101 num::cplx v = a[i + j + len / 2] * tw[j];
103 a[i + j + len / 2] = u - v;
Dense vector with optional GPU storage, templated over scalar type T.
constexpr idx size() const noexcept
FFT interface with backend dispatch.
void cooley_tukey(num::CVector &a, bool invert)
void bit_reverse(num::CVector &a)
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)
std::complex< real > cplx
void execute(num::CVector &a) const
FFTPlanImpl(int n_, bool inv)
std::vector< std::vector< num::cplx > > twiddles