#include #include #include #include #include /* * * Helper classes and functions * */ template class Complex { public: constexpr Complex() noexcept : mRe(), mIm() { } constexpr Complex(const value_t& re, const value_t& im) noexcept : mRe(re), mIm(im) { } constexpr Complex operator-() const { return {-mRe, -mIm}; } constexpr Complex operator+(const Complex& other) const { return {mRe + other.mRe, mIm + other.mIm}; } constexpr Complex operator-(const Complex& other) const { return *this + (-other); } constexpr Complex operator*(const Complex& other) const { return {mRe * other.mRe - mIm * other.mIm, mIm * other.mRe + mRe * other.mIm}; } constexpr value_t& real() { return mRe; } constexpr value_t& imag() { return mIm; } private: value_t mRe; value_t mIm; }; using ComplexFloat = Complex; template constexpr void print(std::vector> vec) { for (auto& elem : vec) { std::cout << "\t" << elem.real() << "; " << elem.imag() << std::endl; } } /* * * FFT implementation * */ constexpr std::vector fft(const std::vector& x) { const unsigned N = x.size(); if (N == 1) { return x; } else { /// Compute even and odd ffts const auto& even_x = x | std::views::stride(2); const auto& odd_x = x | std::views::drop(1) | std::views::stride(2); const auto& even_fft = fft(std::vector(even_x.begin(), even_x.end())); const auto& odd_fft = fft(std::vector(odd_x.begin(), odd_x.end())); /// Combine even and odd ffts std::vector factors(N); for (int k = 0; k < N; ++k) { factors[k].real() = std::cos((2 * std::numbers::pi * k) / N); factors[k].imag() = -std::sin((2 * std::numbers::pi * k) / N); } std::vector result(N); for (int k = 0; k < N; ++k) { result[k] = even_fft[k % (N / 2)] + factors[k] * odd_fft[k % (N / 2)]; } return result; } } /* * * Usage * */ int main() { std::vector x = {{1, 0}, {2, 0}, {3, 0}, {4, 0}}; const auto& X = fft(x); std::cout << "================" << std::endl; std::cout << "result: " << std::endl; print(X); return 0; }