Initial commit

This commit is contained in:
2026-02-18 21:32:22 +01:00
commit ea3a39f550
15 changed files with 903 additions and 0 deletions

85
fft/recursive_fft.cpp Normal file
View File

@@ -0,0 +1,85 @@
#include <cassert>
#include <iostream>
#include <math.h>
#include <numbers>
#include <ranges>
#include <tuple>
#include <vector>
constexpr void print(auto& x_re, auto& x_im) {
for (std::tuple<const float&, const float&> elem :
std::views::zip(x_re, x_im)) {
const auto re = std::get<0>(elem);
const auto im = std::get<1>(elem);
std::cout << "\t" << re << "; " << im << std::endl;
}
}
constexpr std::pair<std::vector<float>, std::vector<float>>
fft(const std::vector<float>& x_re, const std::vector<float>& x_im) {
// TODO: Make sure this is ignored in release mode
assert(x_re.size() == x_im.size());
const unsigned N = x_re.size();
if (N == 1) {
return {x_re, x_im};
} else {
const auto& even_x_re = x_re | std::views::stride(2);
const auto& even_x_im = x_im | std::views::stride(2);
const auto& odd_x_re =
x_re | std::views::drop(1) | std::views::stride(2);
const auto& odd_x_im =
x_im | std::views::drop(1) | std::views::stride(2);
const auto& [even_fft_re, even_fft_im] =
fft(std::vector<float>(even_x_re.begin(), even_x_re.end()),
std::vector<float>(even_x_im.begin(), even_x_im.end()));
const auto& [odd_fft_re, odd_fft_im] =
fft(std::vector<float>(odd_x_re.begin(), odd_x_re.end()),
std::vector<float>(odd_x_im.begin(), odd_x_im.end()));
/// Combine even and odd ffts
std::vector<float> factors_re(N);
std::vector<float> factors_im(N);
for (int k = 0; k < N; ++k) {
factors_re[k] = std::cos((2 * std::numbers::pi * k) / N);
factors_im[k] = -std::sin((2 * std::numbers::pi * k) / N);
}
std::vector<float> result_re(N);
std::vector<float> result_im(N);
for (int k = 0; k < N / 2; ++k) {
result_re[k] = even_fft_re[k] + factors_re[k] * odd_fft_re[k] -
factors_im[k] * odd_fft_im[k];
result_im[k] = even_fft_im[k] + factors_im[k] * odd_fft_re[k] +
factors_re[k] * odd_fft_im[k];
}
for (int k = 0; k < N / 2; ++k) {
result_re[N / 2 + k] = even_fft_re[k] +
factors_re[N / 2 + k] * odd_fft_re[k] -
factors_im[k] * odd_fft_im[k];
result_im[N / 2 + k] = even_fft_im[k] +
factors_im[N / 2 + k] * odd_fft_re[k] +
factors_re[k] * odd_fft_im[k];
}
return {result_re, result_im};
}
}
int main() {
std::vector<float> x_re = {1, 2, 3, 4};
std::vector<float> x_im = {0, 0, 0, 0};
const auto [X_re, X_im] = fft(x_re, x_im);
return 0;
}