5#include "cplib/conv/fft.hpp"
6#include "cplib/port/bit.hpp"
12inline bool conv_naive_is_efficient(std::size_t n, std::size_t m) {
return std::min(n, m) <= 32; }
15void conv_naive_inplace(std::vector<T>& a,
const std::vector<T>& b) {
16 if (a.empty() || b.empty()) {
20 using usize = std::size_t;
21 usize a_deg = a.size() - 1, b_deg = b.size() - 1;
22 a.resize(a_deg + b_deg + 1, T(0));
23 for (usize i = a_deg + b_deg; i > 0; i--) {
27 usize j_low = i <= a_deg ? 1 : i - a_deg;
28 usize j_high = i <= b_deg ? i : b_deg;
29 for (usize j = j_low; j <= j_high; j++) {
30 a[i] += a[i - j] * b[j];
37void conv_fft_inplace2(std::vector<T>& a, std::vector<T>& b) {
38 using usize = std::size_t;
39 usize out_size = a.size() + b.size() - 1;
40 usize padded_out_size = port::bit_ceil(out_size);
41 a.resize(padded_out_size, T(0));
42 b.resize(padded_out_size, T(0));
45 for (
size_t i = 0; i < padded_out_size; i++) {
69 if (impl::conv_naive_is_efficient(a.size(), b.size())) {
70 impl::conv_naive_inplace(a, b);
72 impl::conv_fft_inplace2(a, b);
86 if (impl::conv_naive_is_efficient(a.size(), b.size())) {
87 impl::conv_naive_inplace(a, b);
90 impl::conv_fft_inplace2(a, b_copy);
100std::vector<T>
convolve(
const std::vector<T>& a,
const std::vector<T>& b) {
void convolve_inplace2(std::vector< T > &a, std::vector< T > &b)
In-place convolution where both arrays are modified.
Definition: conv.hpp:68
void ifft_inplace(RandomIt first, RandomIt last)
In-place inverse fast Fourier transform (IFFT).
Definition: fft.hpp:146
void convolve_inplace(std::vector< T > &a, const std::vector< T > &b)
In-place convolution where one array is modified.
Definition: conv.hpp:85
std::vector< T > convolve(const std::vector< T > &a, const std::vector< T > &b)
Returns the convolution of two arrays.
Definition: conv.hpp:100
void fft_inplace(RandomIt first, RandomIt last)
In-place fast Fourier transform (FFT).
Definition: fft.hpp:108