commit db2b24572df2f0fcae53c5fc059e069665ac2b34
parent 3b0b3915beb3c10bedc0654e40bb76782993351f
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date: Mon, 18 Jul 2016 14:14:01 +0300
Feature added: Convolution
Diffstat:
5 files changed, 98 insertions(+), 0 deletions(-)
diff --git a/include/kfr/all.hpp b/include/kfr/all.hpp
@@ -84,6 +84,7 @@
#include "vec.hpp"
#include "dft/bitrev.hpp"
+#include "dft/conv.hpp"
#include "dft/fft.hpp"
#include "dft/ft.hpp"
#include "dft/reference_dft.hpp"
diff --git a/include/kfr/dft/conv.hpp b/include/kfr/dft/conv.hpp
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2016 D Levin (http://www.kfrlib.com)
+ * This file is part of KFR
+ *
+ * KFR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * KFR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with KFR.
+ *
+ * If GPL is not suitable for your project, you must purchase a commercial license to use KFR.
+ * Buying a commercial license is mandatory as soon as you develop commercial activities without
+ * disclosing the source code of your own applications.
+ * See http://www.kfrlib.com for details.
+ */
+#pragma once
+
+#include "../base/complex.hpp"
+#include "../base/constants.hpp"
+#include "../base/memory.hpp"
+#include "../base/read_write.hpp"
+#include "../base/vec.hpp"
+#include "../expressions/operators.hpp"
+
+#include "fft.hpp"
+
+#pragma clang diagnostic push
+#if CID_HAS_WARNING("-Wshadow")
+#pragma clang diagnostic ignored "-Wshadow"
+#endif
+
+namespace kfr
+{
+
+template <typename T, size_t Tag1, size_t Tag2>
+KFR_INTRIN univector<T> convolve(const univector<T, Tag1>& src1, const univector<T, Tag2>& src2)
+{
+ const size_t size = next_poweroftwo(src1.size() + src2.size() - 1);
+ univector<complex<T>> src1padded = src1;
+ univector<complex<T>> src2padded = src2;
+ src1padded.resize(size, 0);
+ src2padded.resize(size, 0);
+ dft_plan<T> plan(size);
+ univector<u8> temp(plan.temp_size);
+ plan.execute(src1padded, src1padded, temp);
+ plan.execute(src2padded, src2padded, temp);
+ src1padded = src1padded * src2padded;
+ plan.execute(src1padded, src1padded, temp, true);
+ return typed<T>( real(src1padded), src1.size() + src2.size() - 1 ) / T(size);
+}
+}
+#pragma clang diagnostic pop
diff --git a/sources.cmake b/sources.cmake
@@ -50,6 +50,7 @@ set(
${PROJECT_SOURCE_DIR}/include/kfr/dft/fft.hpp
${PROJECT_SOURCE_DIR}/include/kfr/dft/ft.hpp
${PROJECT_SOURCE_DIR}/include/kfr/dft/reference_dft.hpp
+ ${PROJECT_SOURCE_DIR}/include/kfr/dft/conv.hpp
${PROJECT_SOURCE_DIR}/include/kfr/dispatch/cpuid.hpp
${PROJECT_SOURCE_DIR}/include/kfr/dispatch/runtimedispatch.hpp
${PROJECT_SOURCE_DIR}/include/kfr/dsp/biquad.hpp
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
@@ -26,6 +26,7 @@ include_directories(../include)
add_executable(basic_vector_test basic_vector_test.cpp ${KFR_SRC})
add_executable(dft_test dft_test.cpp ${KFR_SRC})
+add_executable(conv_test conv_test.cpp ${KFR_SRC})
add_executable(empty_test empty_test.cpp ${KFR_SRC})
add_executable(complex_test complex_test.cpp ${KFR_SRC})
add_executable(vec_test vec_test.cpp ${KFR_SRC})
@@ -34,6 +35,8 @@ enable_testing()
add_test(NAME dft_test
COMMAND ${PROJECT_BINARY_DIR}/tests/dft_test)
+add_test(NAME conv_test
+ COMMAND ${PROJECT_BINARY_DIR}/tests/conv_test)
add_test(NAME complex_test
COMMAND ${PROJECT_BINARY_DIR}/tests/complex_test)
add_test(NAME vec_test
diff --git a/tests/conv_test.cpp b/tests/conv_test.cpp
@@ -0,0 +1,34 @@
+/**
+ * KFR (http://kfrlib.com)
+ * Copyright (C) 2016 D Levin
+ * See LICENSE.txt for details
+ */
+
+// library_version()
+#include <kfr/io/tostring.hpp>
+#include <kfr/version.hpp>
+
+#include <kfr/expressions/reduce.hpp>
+
+#include <tuple>
+
+#include "testo/testo.hpp"
+#include <kfr/dft/conv.hpp>
+
+using namespace kfr;
+
+TEST(test_convolve)
+{
+ univector<double, 5> a({ 1, 2, 3, 4, 5 });
+ univector<double, 5> b({ 0.25, 0.5, 1.0, 0.5, 0.25 });
+ univector<double> c = convolve(a, b);
+ CHECK(c.size() == 9);
+ CHECK(native::rms(c - univector<double>({ 0.25, 1., 2.75, 5., 7.5, 8.5, 7.75, 3.5, 1.25 })) < 0.0001);
+}
+
+int main(int argc, char** argv)
+{
+ println(library_version());
+
+ return testo::run_all("", true);
+}