52inline void radix2(std::vector<std::complex<double>>& a,
bool conjugate) {
53 const std::size_t n = a.size();
55 for (std::size_t i = 1, j = 0; i < n; ++i) {
56 std::size_t bit = n >> 1;
57 for (; j & bit; bit >>= 1) j ^= bit;
59 if (i < j) std::swap(a[i], a[j]);
61 const double pi = 3.14159265358979323846;
62 for (std::size_t len = 2; len <= n; len <<= 1) {
63 const double ang = 2.0 * pi /
static_cast<double>(len) * (conjugate ? 1.0 : -1.0);
64 const std::complex<double> wlen(std::cos(ang), std::sin(ang));
65 for (std::size_t i = 0; i < n; i += len) {
66 std::complex<double> w(1.0, 0.0);
67 for (std::size_t k = 0; k < len / 2; ++k) {
68 const std::complex<double> u = a[i + k];
69 const std::complex<double> v = a[i + k + len / 2] * w;
71 a[i + k + len / 2] = u - v;
78inline bool is_power_of_two(std::size_t n) {
return n != 0 && (n & (n - 1)) == 0; }
81inline void bluestein(std::vector<std::complex<double>>& a,
bool conjugate) {
82 const std::size_t n = a.size();
83 const double pi = 3.14159265358979323846;
84 const double sign = conjugate ? 1.0 : -1.0;
88 std::vector<std::complex<double>> chirp(n);
89 for (std::size_t k = 0; k < n; ++k) {
90 const std::size_t kk = (k * k) % (2 * n);
91 const double ang = sign * pi *
static_cast<double>(kk) /
static_cast<double>(n);
92 chirp[k] = std::complex<double>(std::cos(ang), std::sin(ang));
96 while (m < 2 * n - 1) m <<= 1;
97 std::vector<std::complex<double>> x(m, std::complex<double>(0.0, 0.0));
98 std::vector<std::complex<double>> y(m, std::complex<double>(0.0, 0.0));
99 for (std::size_t k = 0; k < n; ++k) x[k] = a[k] * chirp[k];
100 y[0] = std::conj(chirp[0]);
101 for (std::size_t k = 1; k < n; ++k) {
102 y[k] = std::conj(chirp[k]);
103 y[m - k] = std::conj(chirp[k]);
108 for (std::size_t k = 0; k < m; ++k) x[k] *= y[k];
110 const double scale = 1.0 /
static_cast<double>(m);
111 for (std::size_t k = 0; k < n; ++k) a[k] = x[k] * scale * chirp[k];
120inline void dft(std::vector<std::complex<double>>& a,
bool inverse) {
121 const std::size_t n = a.size();
123 if (fft_detail::is_power_of_two(n)) {
124 fft_detail::radix2(a,
inverse);
126 fft_detail::bluestein(a,
inverse);
129 const double scale = 1.0 /
static_cast<double>(n);
130 for (std::size_t k = 0; k < n; ++k) a[k] *= scale;
The exception types the port throws.
Matrix< T > inverse(const Matrix< T > &A)
Inverse by LU with one factorization and n back substitutions.
void dft(std::vector< std::complex< double > > &a, bool inverse)
In-place DFT of a.