kfr

Fast, modern C++ DSP framework, FFT, Sample Rate Conversion, FIR/IIR/Biquad Filters (SSE, AVX, AVX-512, ARM NEON)
Log | Files | Refs | README

commit bacf6f6498d6ef3d40e8d7e6af97a36ece729f6b
parent 56f4aea6c6fb2716543f806193e19e883e34e914
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date:   Sat, 20 Aug 2016 00:01:58 +0300

Add expression_adjacent

Diffstat:
Minclude/kfr/base/basic_expressions.hpp | 27+++++++++++++++++++++++++++
Mtests/vec_test.cpp | 11+++++++++++
2 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/include/kfr/base/basic_expressions.hpp b/include/kfr/base/basic_expressions.hpp @@ -307,6 +307,24 @@ protected: std::array<size_t, base::size + 2> segments; }; + +template <typename Fn, typename E> +struct expression_adjacent : expression<E> +{ + using value_type = value_type_of<E>; + expression_adjacent(Fn&& fn, E&& e) : expression<E>(std::forward<E>(e)), fn(std::forward<Fn>(fn)) {} + + template <typename T, size_t N> + vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N>) const + { + const vec<T, N> in = this->argument_first(index, vec_t<T, N>()); + const vec<T, N> delayed = insertleft(data, in); + data = in[N - 1]; + return this->fn(in, delayed); + } + Fn fn; + mutable value_type data = value_type(0); +}; } template <typename E1> @@ -339,6 +357,15 @@ CMT_INLINE internal::expression_sequence<decay<E>...> gen_sequence(const size_t } KFR_FN(gen_sequence) +/** + * @brief Returns template expression that returns the result of calling \f$ fn(x_i, x_{i-1}) \f$ + */ +template <typename Fn, typename E1> +CMT_INLINE internal::expression_adjacent<Fn, E1> adjacent(Fn&& fn, E1&& e1) +{ + return internal::expression_adjacent<Fn, E1>(std::forward<Fn>(fn), std::forward<E1>(e1)); +} + namespace internal { template <typename... E> diff --git a/tests/vec_test.cpp b/tests/vec_test.cpp @@ -291,4 +291,15 @@ TEST(test_delay) CHECK(v3[19] == 116); } +TEST(test_adjacent) +{ + univector<int, 20> v1 = adjacent(fn_mul(), typed<int>(counter())); + CHECK(v1[0] == 0); + CHECK(v1[1] == 0); + CHECK(v1[2] == 2); + CHECK(v1[3] == 6); + CHECK(v1[4] == 12); + CHECK(v1[19] == 342); +} + int main(int argc, char** argv) { return testo::run_all("", true); }