23 #ifndef EDSP_CONVOLUTION_HPP 24 #define EDSP_CONVOLUTION_HPP 29 namespace edsp {
inline namespace spectral {
48 template <
typename InputIt,
typename OutputIt,
typename RAllocator = std::allocator<meta::value_type_t<InputIt>>,
49 typename CAllocator = std::allocator<std::complex<meta::value_type_t<OutputIt>>>>
50 inline void conv(InputIt first1, InputIt last1, InputIt first2, OutputIt d_first) {
51 meta::expects(
std::distance(first1, last1) > 0,
"Not expecting empty input");
52 using value_type = meta::value_type_t<InputIt>;
54 const auto nfft = 2 * size;
55 fft_impl<value_type> fft_(nfft);
56 fft_impl<value_type> ifft_(nfft);
58 std::vector<value_type, RAllocator> temp_input1(nfft, static_cast<value_type>(0)),
59 temp_input2(nfft, static_cast<value_type>(0)), temp_output(nfft);
60 std::copy(first1, last1, std::begin(temp_input1));
61 std::copy(first2, meta::advance(first2, size), std::begin(temp_input2));
63 std::vector<std::complex<value_type>, CAllocator> fft_data1(
make_fft_size(nfft));
64 std::vector<std::complex<value_type>, CAllocator> fft_data2(
make_fft_size(nfft));
66 fft_.dft(meta::data(temp_input1), meta::data(fft_data1));
67 fft_.dft(meta::data(temp_input2), meta::data(fft_data2));
69 std::transform(std::cbegin(fft_data1), std::cend(fft_data1), std::cbegin(fft_data2), std::begin(fft_data1),
72 ifft_.idft(meta::data(fft_data1), meta::data(temp_output));
73 ifft_.idft_scale(meta::data(temp_output));
74 std::copy(std::cbegin(temp_output), std::cbegin(temp_output) + size, d_first);
79 #endif // EDSP_CONVOLUTION_HPP void conv(InputIt first1, InputIt last1, InputIt first2, OutputIt d_first)
Computes the convolution between the range [first1, last1) and the range [first2, last2)...
Definition: convolution.hpp:50
constexpr Integer make_fft_size(Integer real_size) noexcept
Computes the expected DFT size for a real-to-complex DFT transform.
Definition: dft.hpp:35
constexpr T distance(T x, T y) noexcept
Computes the distance between x and y.
Definition: numeric.hpp:328
Definition: amplifier.hpp:29