23 #ifndef EDSP_AUTOCORRELATION_HPP 24 #define EDSP_AUTOCORRELATION_HPP 29 namespace edsp {
inline namespace spectral {
58 template <
typename InputIt,
typename OutputIt,
typename RAllocator = std::allocator<meta::value_type_t<InputIt>>,
59 typename CAllocator = std::allocator<std::complex<meta::value_type_t<OutputIt>>>>
61 meta::expects(
std::distance(first, last) > 0,
"Not expecting empty input");
62 using value_type = meta::value_type_t<InputIt>;
64 const auto nfft = 2 * size;
65 fft_impl<value_type> fft_(nfft);
66 fft_impl<value_type> ifft_(nfft);
68 std::vector<value_type, RAllocator> temp_input(nfft, static_cast<value_type>(0)), temp_output(nfft);
69 std::copy(first, last, std::begin(temp_input));
71 std::vector<std::complex<value_type>, CAllocator> fft_data_(
make_fft_size(nfft));
72 fft_.dft(meta::data(temp_input), meta::data(fft_data_));
75 std::cbegin(fft_data_), std::cend(fft_data_), std::begin(fft_data_),
76 [](
const std::complex<value_type>& val) -> std::complex<value_type> {
return val *
std::conj(val); });
78 ifft_.idft(meta::data(fft_data_), meta::data(temp_output));
80 std::transform(std::cbegin(temp_output), std::cbegin(temp_output) + size, d_first,
81 [factor](value_type val) {
return val / factor; });
103 template <
typename InputIt,
typename OutputIt,
typename RAllocator = std::allocator<meta::value_type_t<InputIt>>,
104 typename CAllocator = std::allocator<std::complex<meta::value_type_t<OutputIt>>>>
105 inline void xcorr(InputIt first1, InputIt last1, InputIt first2, OutputIt d_first,
107 meta::expects(
std::distance(first1, last1) > 0,
"Not expecting empty input");
108 using value_type = meta::value_type_t<InputIt>;
110 const auto nfft = 2 * size;
111 fft_impl<value_type> fft_(nfft);
112 fft_impl<value_type> ifft_(nfft);
114 std::vector<value_type, RAllocator> temp_input1(nfft, static_cast<value_type>(0)),
115 temp_input2(nfft, static_cast<value_type>(0)), temp_output(nfft);
116 std::copy(first1, last1, std::begin(temp_input1));
117 std::copy(first2, meta::advance(first2, size), std::begin(temp_input2));
119 std::vector<std::complex<value_type>, CAllocator> fft_data1(
make_fft_size(nfft));
120 std::vector<std::complex<value_type>, CAllocator> fft_data2(
make_fft_size(nfft));
122 fft_.dft(meta::data(temp_input1), meta::data(fft_data1));
123 fft_.dft(meta::data(temp_input2), meta::data(fft_data2));
125 std::transform(std::cbegin(fft_data1), std::cend(fft_data1), std::cbegin(fft_data2), std::begin(fft_data1),
126 [](
const std::complex<value_type>& left,
const std::complex<value_type>& right)
127 -> std::complex<value_type> {
return left *
std::conj(right); });
129 ifft_.idft(meta::data(fft_data1), meta::data(temp_output));
131 std::transform(std::cbegin(temp_output), std::cbegin(temp_output) + size, d_first,
132 [factor](value_type val) {
return val / factor; });
136 #endif // EDSP_AUTOCORRELATION_HPP 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
void xcorr(InputIt first, InputIt last, OutputIt d_first, CorrelationScale scale=CorrelationScale::None)
Computes the autocorrelation of the range [first, last) and stores the result in another range...
Definition: correlation.hpp:60
constexpr std::complex< T > conj(const std::complex< T > &z)
Computes the complex conjugate of the complex number z.
Definition: complex.hpp:80
CorrelationScale
The ScaleOpt enum defines the normalization option of the correlation function.
Definition: correlation.hpp:34
Definition: amplifier.hpp:29