From a7b8bdb8fabc5438b90394d64ad5fccfeedeba71 Mon Sep 17 00:00:00 2001 From: Vincent Samy Date: Tue, 29 Oct 2019 16:34:45 +0900 Subject: [PATCH 1/2] Fix naming. --- include/BaseFilter.h | 4 ++-- include/BaseFilter.tpp | 6 +++--- include/GenericFilter.h | 4 ++-- include/differentiators.h | 22 +++++++++++----------- include/typedefs.h | 2 +- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/include/BaseFilter.h b/include/BaseFilter.h index fae084e..c45176b 100644 --- a/include/BaseFilter.h +++ b/include/BaseFilter.h @@ -57,7 +57,7 @@ public: void resetFilter() noexcept { derived().resetFilter(); }; /*!< \brief Return the filter type */ - FilterType type() const noexcept { return (m_center == 0 ? FilterType::Forward : FilterType::Centered); } + FilterType type() const noexcept { return (m_center == 0 ? FilterType::Backward : FilterType::Centered); } /*! \brief Get digital filter coefficients. * * It will automatically resize the given vectors. @@ -110,7 +110,7 @@ private: * \param bCoeff Numerator coefficients of the filter in decreasing order. * \param center */ - BaseFilter(const vectX_t& aCoeff, const vectX_t& bCoeff, FilterType type = FilterType::Forward); + BaseFilter(const vectX_t& aCoeff, const vectX_t& bCoeff, FilterType type = FilterType::Backward); /*! \brief Default destructor. */ virtual ~BaseFilter() = default; diff --git a/include/BaseFilter.tpp b/include/BaseFilter.tpp index 5872077..fd8ceb3 100644 --- a/include/BaseFilter.tpp +++ b/include/BaseFilter.tpp @@ -35,7 +35,7 @@ template void BaseFilter::setType(FilterType type) { Expects(type == FilterType::Centered ? m_bCoeff.size() > 2 && m_bCoeff.size() % 2 == 1 : true); - m_center = (type == FilterType::Forward ? 0 : (m_bCoeff.size() - 1) / 2); + m_center = (type == FilterType::Backward ? 0 : (m_bCoeff.size() - 1) / 2); } template @@ -44,7 +44,7 @@ void BaseFilter::setCoeffs(T2&& aCoeff, T2&& bCoeff) { static_assert(std::is_convertible_v>, "The coefficients types should be convertible to vectX_t"); - Expects(checkCoeffs(aCoeff, bCoeff, (m_center == 0 ? FilterType::Forward : FilterType::Centered))); + Expects(checkCoeffs(aCoeff, bCoeff, (m_center == 0 ? FilterType::Backward : FilterType::Centered))); m_aCoeff = aCoeff; m_bCoeff = bCoeff; normalizeCoeffs(); @@ -69,7 +69,7 @@ BaseFilter::BaseFilter(const vectX_t& aCoeff, const vectX_t& b , m_rawData(bCoeff.size()) { Expects(checkCoeffs(aCoeff, bCoeff, type)); - m_center = (type == FilterType::Forward ? 0 : (bCoeff.size() - 1) / 2); + m_center = (type == FilterType::Backward ? 0 : (bCoeff.size() - 1) / 2); normalizeCoeffs(); resetFilter(); m_isInitialized = true; diff --git a/include/GenericFilter.h b/include/GenericFilter.h index 8653d6e..20f3129 100644 --- a/include/GenericFilter.h +++ b/include/GenericFilter.h @@ -53,7 +53,7 @@ public: protected: GenericFilter() = default; - GenericFilter(const vectX_t& aCoeff, const vectX_t& bCoeff, FilterType type = FilterType::Forward) + GenericFilter(const vectX_t& aCoeff, const vectX_t& bCoeff, FilterType type = FilterType::Backward) : BaseFilter(aCoeff, bCoeff, type) {} }; @@ -80,7 +80,7 @@ public: protected: TVGenericFilter() = default; - TVGenericFilter(int order, const vectX_t& aCoeff, const vectX_t& bCoeff, FilterType type = FilterType::Forward) + TVGenericFilter(int order, const vectX_t& aCoeff, const vectX_t& bCoeff, FilterType type = FilterType::Backward) : BaseFilter(aCoeff, bCoeff, type) , m_order(order) { diff --git a/include/differentiators.h b/include/differentiators.h index 0b5544e..6c75501 100644 --- a/include/differentiators.h +++ b/include/differentiators.h @@ -72,7 +72,7 @@ template vectN_t GetSLNLCoeffs() { return vectN_t{ T(-2 template vectN_t GetSLNLCoeffs() { return vectN_t{ T(-86), T(142), T(193), T(126), T(0), T(-126), T(-193), T(-142), T(86) } / T(1188); } template vectN_t GetSLNLCoeffs() { return vectN_t{ T(-300), T(294), T(532), T(503), T(296), T(0), T(-296), T(-503), T(-532), T(-294), T(300) } / T(5148); } -// Forward Noise-Robust differentiators; http://www.holoborodko.com/pavel/wp-content/uploads/OneSidedNoiseRobustDifferentiators.pdf +// Backward Noise-Robust differentiators; http://www.holoborodko.com/pavel/wp-content/uploads/OneSidedNoiseRobustDifferentiators.pdf template vectN_t GetFNRCoeffs() { @@ -95,7 +95,7 @@ template vectN_t GetFNRCoeffs() { return vectN_t{ T(1), template vectN_t GetFNRCoeffs() { return vectN_t{ T(1), T(7), T(20), T(28), T(14), T(-14), T(-28), T(-20), T(-7), T(-1) } / T(256); } template vectN_t GetFNRCoeffs() { return vectN_t{ T(1), T(8), T(27), T(48), T(42), T(0), T(-42), T(-48), T(-27), T(-8), T(-1) } / T(512); } -// Forward Hybrid Noise-Robust differentiators; http://www.holoborodko.com/pavel/wp-content/uploads/OneSidedNoiseRobustDifferentiators.pdf +// Backward Hybrid Noise-Robust differentiators; http://www.holoborodko.com/pavel/wp-content/uploads/OneSidedNoiseRobustDifferentiators.pdf template vectN_t GetFHNRCoeffs(); template vectN_t GetFHNRCoeffs() { return vectN_t{ T(2), T(-1), T(-2), T(1) } / T(2); } template vectN_t GetFHNRCoeffs() { return vectN_t{ T(7), T(1), T(-10), T(-1), T(3) } / T(10); } @@ -114,9 +114,9 @@ template typename Foo> vectN_t vectN_t GetFNRISDCoeffs() { return GetForwardISDCoeffs(); } -// Forward Hybrid Noise-Robust differentiators for irregular space data +// Backward Hybrid Noise-Robust differentiators for irregular space data template vectN_t GetFHNRISDCoeffs() { return GetForwardISDCoeffs(); } // Centered Noise-Robust differentiators (tangency at 2nd order): http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/smooth-low-noise-differentiators/ @@ -197,7 +197,7 @@ vectN_t GetSOCNRCoeffs() return v; } -// Second-Order Forward Noise-Robust differentiator: http://www.holoborodko.com/pavel/downloads/NoiseRobustSecondDerivative.pdf +// Second-Order Backward Noise-Robust differentiator: http://www.holoborodko.com/pavel/downloads/NoiseRobustSecondDerivative.pdf template vectN_t GetSOFNRCoeffs() { return GetSOCNRCoeffs(); } // Coefficients are the same. @@ -223,7 +223,7 @@ vectN_t GetSOCNRISDCoeffs() return v; } -// Second-Order Forward Noise-Robust Irregular Space Data differentiator: http://www.holoborodko.com/pavel/downloads/NoiseRobustSecondDerivative.pdf +// Second-Order Backward Noise-Robust Irregular Space Data differentiator: http://www.holoborodko.com/pavel/downloads/NoiseRobustSecondDerivative.pdf template vectN_t GetSOFNRISDCoeffs() { return GetSOCNRISDCoeffs(); } // Same coefficients @@ -279,10 +279,10 @@ public: } // namespace details -// Forward differentiators +// Backward differentiators template using ForwardNoiseRobustDiff = ForwardDifferentiator; template using ForwardHybridNoiseRobustDiff = ForwardDifferentiator; -// Time-Varying forward differentiators +// Time-Varying backward differentiators template using TVForwardNoiseRobustDiff = TVForwardDifferentiator; template using TVForwardHybridNoiseRobustDiff = TVForwardDifferentiator; @@ -297,14 +297,14 @@ template using TVCenteredNoiseRobust2Diff = TVCentralDiff template using TVCenteredNoiseRobust4Diff = TVCentralDifferentiator; -// Second-order forward differentiators +// Second-order backward differentiators template using ForwardSecondOrderDiff = ForwardDifferentiator; -// Second-order Time-Varying forward differentiators +// Second-order Time-Varying backward differentiators template using TVForwardSecondOrderDiff = TVForwardDifferentiator; // Second-order central differentiators template using CenteredSecondOrderDiff = CentralDifferentiator; -// Second-order Time-Varying forward differentiators +// Second-order Time-Varying backward differentiators template using TVCenteredSecondOrderDiff = TVCentralDifferentiator; diff --git a/include/typedefs.h b/include/typedefs.h index f85ac96..04d5ac7 100644 --- a/include/typedefs.h +++ b/include/typedefs.h @@ -44,7 +44,7 @@ template using vectXc_t = vectX_t>; /*!< Eigen complex column-vector */ enum class FilterType { - Forward, + Backward, Centered }; From a2c073ae3d3419ea0a9def93da913a7fbd7cc9f7 Mon Sep 17 00:00:00 2001 From: Vincent Samy Date: Tue, 29 Oct 2019 17:55:25 +0900 Subject: [PATCH 2/2] Pass to catch for tests. --- README.md | 18 +++-- tests/ButterworthFilterTests.cpp | 108 +++++++++-------------------- tests/CMakeLists.txt | 16 ++--- tests/DigitalFilterTests.cpp | 20 ++---- tests/GenericFilterTests.cpp | 26 ++++--- tests/MovingAverageFilterTests.cpp | 19 ++--- tests/catch_helper.h | 4 ++ tests/polynome_functions_tests.cpp | 58 ++++++---------- tests/test_functions.h | 15 ++-- 9 files changed, 109 insertions(+), 175 deletions(-) create mode 100644 tests/catch_helper.h diff --git a/README.md b/README.md index 6ee9b36..0271d08 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,14 @@ DiFi++ is a small c++ header-only library for **DI**gital **FI**lters based on The implementation is based on well written article from Neil Robertson. Please check out the followings - * https://www.dsprelated.com/showarticle/1119.php - * https://www.dsprelated.com/showarticle/1135.php - * https://www.dsprelated.com/showarticle/1128.php - * https://www.dsprelated.com/showarticle/1131.php + +* [Butterworth filter](https://www.dsprelated.com/showarticle/1119.php) + +* [Highpass filters](https://www.dsprelated.com/showarticle/1135.php) + +* [Bandpass filters](https://www.dsprelated.com/showarticle/1128.php) + +* [Band-reject filters](https://www.dsprelated.com/showarticle/1131.php) The library has been tested against Matlab results. @@ -30,6 +34,12 @@ cmake .. make install ``` +Testing +----- + +To test you need to install [catch2](https://github.com/catchorg/Catch2) on your system. + Note ----- + The method used is close but somewhat different from Matlab methods and Butterworth band-reject has quite different results (precision of 1e-8). \ No newline at end of file diff --git a/tests/ButterworthFilterTests.cpp b/tests/ButterworthFilterTests.cpp index 1f78a5c..fd4064e 100644 --- a/tests/ButterworthFilterTests.cpp +++ b/tests/ButterworthFilterTests.cpp @@ -25,14 +25,13 @@ // of the authors and should not be interpreted as representing official policies, // either expressed or implied, of the FreeBSD Project. -#define BOOST_TEST_MODULE ButterworthFilterTests - // Note: In term of precision, LP > HP > BP ~= BR #include "difi" #include "test_functions.h" #include "warning_macro.h" -#include +#include "catch_helper.h" +#include DISABLE_CONVERSION_WARNING_BEGIN @@ -64,92 +63,51 @@ struct System { DISABLE_CONVERSION_WARNING_END -BOOST_AUTO_TEST_CASE(FIND_BUTTERWORTH_LP_HP_FLOAT) +TEMPLATE_TEST_CASE("Find butterworth Low pass and High pass", "[lp][hp]", float, double) { // LP - auto butterRequirement = difi::Butterworthf::findMinimumButter(40.f / 500.f, 150.f / 500.f, 3.f, 60.f); - BOOST_REQUIRE_EQUAL(5, butterRequirement.first); - BOOST_REQUIRE_SMALL(std::abs(static_cast(0.081038494957764) - butterRequirement.second), std::numeric_limits::epsilon() * 10); + auto butterRequirement = difi::Butterworth::findMinimumButter(static_cast(40. / 500.), static_cast(150. / 500.), static_cast(3.), static_cast(60.)); + REQUIRE_EQUAL(5, butterRequirement.first); + REQUIRE_SMALL(std::abs(static_cast(0.081038494957764) - butterRequirement.second), std::numeric_limits::epsilon() * 10); // HP - butterRequirement = difi::Butterworthf::findMinimumButter(150.f / 500.f, 40.f / 500.f, 3.f, 60.f); - BOOST_REQUIRE_EQUAL(5, butterRequirement.first); - BOOST_REQUIRE_SMALL(std::abs(static_cast(0.296655824107340) - butterRequirement.second), std::numeric_limits::epsilon() * 10); + butterRequirement = difi::Butterworth::findMinimumButter(static_cast(150. / 500.), static_cast(40. / 500.), static_cast(3.), static_cast(60.)); + REQUIRE_EQUAL(5, butterRequirement.first); + REQUIRE_SMALL(std::abs(static_cast(0.296655824107340) - butterRequirement.second), std::numeric_limits::epsilon() * 10); } -BOOST_AUTO_TEST_CASE(FIND_BUTTERWORTH_LP_HP_DOUBLE) +TEMPLATE_TEST_CASE_METHOD(System, "Butterworth low pass filter", "[lp]", float, double) { - // LP - auto butterRequirement = difi::Butterworthd::findMinimumButter(40. / 500., 150. / 500., 3., 60.); - BOOST_REQUIRE_EQUAL(5, butterRequirement.first); - BOOST_REQUIRE_SMALL(std::abs(0.081038494957764 - butterRequirement.second), std::numeric_limits::epsilon() * 10); - - // HP - butterRequirement = difi::Butterworthd::findMinimumButter(150. / 500., 40. / 500., 3., 60.); - BOOST_REQUIRE_EQUAL(5, butterRequirement.first); - BOOST_REQUIRE_SMALL(std::abs(0.296655824107340 - butterRequirement.second), std::numeric_limits::epsilon() * 10); + System s; + auto bf = difi::Butterworth(s.order, s.fc, s.fs); + REQUIRE_EQUAL(bf.aOrder(), bf.bOrder()); + test_coeffs(s.lpACoeffRes, s.lpBCoeffRes, s.bf, std::numeric_limits::epsilon() * 10); + test_results(s.lpResults, s.data, s.bf, std::numeric_limits::epsilon() * 100); } -BOOST_FIXTURE_TEST_CASE(BUTTERWORTH_LP_FILTER_FLOAT, System) +TEMPLATE_TEST_CASE_METHOD(System, "Butterworth high pass filter", "[hp]", float, double) { - auto bf = difi::Butterworthf(order, fc, fs); - BOOST_REQUIRE_EQUAL(bf.aOrder(), bf.bOrder()); - test_coeffs(lpACoeffRes, lpBCoeffRes, bf, std::numeric_limits::epsilon() * 10); - test_results(lpResults, data, bf, std::numeric_limits::epsilon() * 100); + System s; + auto bf = difi::Butterworth(s.order, s.fc, s.fs, difi::Butterworth::Type::HighPass); + REQUIRE_EQUAL(bf.aOrder(), bf.bOrder()); + test_coeffs(s.hpACoeffRes, s.hpBCoeffRes, s.bf, std::numeric_limits::epsilon() * 10); + test_results(s.hpResults, s.data, s.bf, std::numeric_limits::epsilon() * 1000); } -BOOST_FIXTURE_TEST_CASE(BUTTERWORTH_LP_FILTER_DOUBLE, System) +TEMPLATE_TEST_CASE_METHOD(System, "Butterworth band pass filter", "[bp]", float, double) { - auto bf = difi::Butterworthd(order, fc, fs); - BOOST_REQUIRE_EQUAL(bf.aOrder(), bf.bOrder()); - test_coeffs(lpACoeffRes, lpBCoeffRes, bf, std::numeric_limits::epsilon() * 10); - test_results(lpResults, data, bf, std::numeric_limits::epsilon() * 100); + System s; + auto bf = difi::Butterworth(s.order, s.fLower, s.fUpper, s.fs); + REQUIRE_EQUAL(bf.aOrder(), bf.bOrder()); + test_coeffs(s.bpACoeffRes, s.bpBCoeffRes, s.bf, std::numeric_limits::epsilon() * 1000); + test_results(s.bpResults, s.data, s.bf, std::numeric_limits::epsilon() * 10000); } -BOOST_FIXTURE_TEST_CASE(BUTTERWORTH_HP_FILTER_FLOAT, System) +TEMPLATE_TEST_CASE_METHOD(System, "Butterworth band-reject filter", "[br]", float, double) { - auto bf = difi::Butterworthf(order, fc, fs, difi::Butterworthf::Type::HighPass); - BOOST_REQUIRE_EQUAL(bf.aOrder(), bf.bOrder()); - test_coeffs(hpACoeffRes, hpBCoeffRes, bf, std::numeric_limits::epsilon() * 10); - test_results(hpResults, data, bf, std::numeric_limits::epsilon() * 1000); -} - -BOOST_FIXTURE_TEST_CASE(BUTTERWORTH_HP_FILTER_DOUBLE, System) -{ - auto bf = difi::Butterworthd(order, fc, fs, difi::Butterworthd::Type::HighPass); - BOOST_REQUIRE_EQUAL(bf.aOrder(), bf.bOrder()); - test_coeffs(hpACoeffRes, hpBCoeffRes, bf, std::numeric_limits::epsilon() * 10); - test_results(hpResults, data, bf, std::numeric_limits::epsilon() * 100); -} - -BOOST_FIXTURE_TEST_CASE(BUTTERWORTH_BP_FILTER_FLOAT, System) -{ - auto bf = difi::Butterworthf(order, fLower, fUpper, fs); - BOOST_REQUIRE_EQUAL(bf.aOrder(), bf.bOrder()); - test_coeffs(bpACoeffRes, bpBCoeffRes, bf, std::numeric_limits::epsilon() * 1000); - test_results(bpResults, data, bf, std::numeric_limits::epsilon() * 10000); -} - -BOOST_FIXTURE_TEST_CASE(BUTTERWORTH_BP_FILTER_DOUBLE, System) -{ - auto bf = difi::Butterworthd(order, fLower, fUpper, fs); - BOOST_REQUIRE_EQUAL(bf.aOrder(), bf.bOrder()); - test_coeffs(bpACoeffRes, bpBCoeffRes, bf, std::numeric_limits::epsilon() * 1000); - test_results(bpResults, data, bf, std::numeric_limits::epsilon() * 10000); -} - -BOOST_FIXTURE_TEST_CASE(BUTTERWORTH_BR_FILTER_FLOAT, System) -{ - auto bf = difi::Butterworthf(order, fLower, fUpper, fs, difi::Butterworthf::Type::BandReject); - BOOST_REQUIRE_EQUAL(bf.aOrder(), bf.bOrder()); - test_coeffs(brACoeffRes, brBCoeffRes, bf, 1.f); - test_results(brResults, data, bf, 1.f); -} - -BOOST_FIXTURE_TEST_CASE(BUTTERWORTH_BR_FILTER_DOUBLE, System) -{ - auto bf = difi::Butterworthd(order, fLower, fUpper, fs, difi::Butterworthd::Type::BandReject); - BOOST_REQUIRE_EQUAL(bf.aOrder(), bf.bOrder()); - test_coeffs(brACoeffRes, brBCoeffRes, bf, 1e-8); - test_results(brResults, data, bf, 1e-8); + System s; + auto bf = difi::Butterworth(s.order, s.fLower, s.fUpper, s.fs, difi::Butterworth::Type::BandReject); + REQUIRE_EQUAL(bf.aOrder(), bf.bOrder()); + test_coeffs(s.brACoeffRes, s.brBCoeffRes, s.bf, std::numeric_limits::epsilon() * 1e8); + test_results(s.brResults, s.data, s.bf, std::numeric_limits::epsilon() * 1e8); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 10957d6..490eba7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -27,20 +27,14 @@ enable_testing() -if(${BUILD_TEST_STATIC_BOOST}) - set(Boost_USE_STATIC_LIBS ON) - set(BUILD_SHARED_LIBS OFF) - set(BOOST_DEFS "") -else() - set(Boost_USE_STATIC_LIBS OFF) - set(BUILD_SHARED_LIBS ON) - set(BOOST_DEFS Boost::dynamic_linking) -endif() -find_package(Boost REQUIRED COMPONENTS unit_test_framework) +find_package(Catch2 REQUIRED) macro(addTest testName) add_executable(${testName} ${testName}.cpp) - target_link_libraries(${testName} PRIVATE Boost::unit_test_framework Boost::disable_autolinking ${BOOST_DEFS} ${PROJECT_NAME}) + # target_link_libraries(${testName} PRIVATE Boost::unit_test_framework Boost::disable_autolinking ${BOOST_DEFS} ${PROJECT_NAME}) + target_link_libraries(${testName} PRIVATE Catch2::Catch2) + target_compile_definitions(${testName} PRIVATE CATCH_CONFIG_MAIN) + target_include_directories(${testName} SYSTEM INTERFACE "${EIGEN3_INCLUDE_DIR}") # Adding a project configuration file (for MSVC only) generate_msvc_dot_user_file(${testName}) diff --git a/tests/DigitalFilterTests.cpp b/tests/DigitalFilterTests.cpp index 4404a70..c61b144 100644 --- a/tests/DigitalFilterTests.cpp +++ b/tests/DigitalFilterTests.cpp @@ -25,12 +25,10 @@ // of the authors and should not be interpreted as representing official policies, // either expressed or implied, of the FreeBSD Project. -#define BOOST_TEST_MODULE DigitalFilterTests - #include "difi" #include "test_functions.h" #include "warning_macro.h" -#include +#include "catch2/catch.hpp" DISABLE_CONVERSION_WARNING_BEGIN @@ -44,16 +42,10 @@ struct System { DISABLE_CONVERSION_WARNING_END -BOOST_FIXTURE_TEST_CASE(DIGITAL_FILTER_FLOAT, System) +TEMPLATE_TEST_CASE_METHOD(System, "Digital filter", "[df]", float, double) { - auto df = difi::DigitalFilterf(aCoeff, bCoeff); - test_coeffs(aCoeff, bCoeff, df, std::numeric_limits::epsilon() * 10); - test_results(results, data, df, std::numeric_limits::epsilon() * 10); -} - -BOOST_FIXTURE_TEST_CASE(DIGITAL_FILTER_DOUBLE, System) -{ - auto df = difi::DigitalFilterd(aCoeff, bCoeff); - test_coeffs(aCoeff, bCoeff, df, std::numeric_limits::epsilon() * 10); - test_results(results, data, df, std::numeric_limits::epsilon() * 10); + System s; + auto df = difi::DigitalFilter(aCoeff, bCoeff); + test_coeffs(s.aCoeff, s.bCoeff, s.df, std::numeric_limits::epsilon() * 10); + test_results(s.results, s.data, s.df, std::numeric_limits::epsilon() * 10); } diff --git a/tests/GenericFilterTests.cpp b/tests/GenericFilterTests.cpp index 3abfdca..2d76778 100644 --- a/tests/GenericFilterTests.cpp +++ b/tests/GenericFilterTests.cpp @@ -25,35 +25,33 @@ // of the authors and should not be interpreted as representing official policies, // either expressed or implied, of the FreeBSD Project. -#define BOOST_TEST_MODULE GenericFilterTests - #include "difi" -#include #include #include +#include -BOOST_AUTO_TEST_CASE(FILTER_FAILURES) +TEST_CASE("Filter failures", "[fail]") { // A coeff are missing - BOOST_REQUIRE_THROW(difi::DigitalFilterd(Eigen::VectorXd(), Eigen::VectorXd::Constant(2, 0)), std::logic_error); + REQUIRE_THROW_AS(difi::DigitalFilterd(Eigen::VectorXd(), Eigen::VectorXd::Constant(2, 0)), std::logic_error); // B coeff are missing - BOOST_REQUIRE_THROW(difi::DigitalFilterd(Eigen::VectorXd::Constant(2, 1), Eigen::VectorXd()), std::logic_error); + REQUIRE_THROW_AS(difi::DigitalFilterd(Eigen::VectorXd::Constant(2, 1), Eigen::VectorXd()), std::logic_error); // aCoeff(0) = 0 - BOOST_REQUIRE_THROW(difi::DigitalFilterd(Eigen::VectorXd::Constant(2, 0), Eigen::VectorXd::Constant(2, 0)), std::logic_error); + REQUIRE_THROW_AS(difi::DigitalFilterd(Eigen::VectorXd::Constant(2, 0), Eigen::VectorXd::Constant(2, 0)), std::logic_error); // Filter left uninitialized - BOOST_REQUIRE_NO_THROW(difi::DigitalFilterd()); + REQUIRE_NOTHROW(difi::DigitalFilterd()); auto df = difi::DigitalFilterd(); // Filter data with uninitialized filter - BOOST_REQUIRE_THROW(df.stepFilter(10.), std::logic_error); + REQUIRE_THROW_AS(df.stepFilter(10.), std::logic_error); // window <= 0 - BOOST_REQUIRE_THROW(difi::MovingAveraged(0), std::logic_error); + REQUIRE_THROW_AS(difi::MovingAveraged(0), std::logic_error); // order <= 0 - BOOST_REQUIRE_THROW(difi::Butterworthd(0, 10, 100), std::logic_error); + REQUIRE_THROW_AS(difi::Butterworthd(0, 10, 100), std::logic_error); // fc > 2*fs - BOOST_REQUIRE_THROW(difi::Butterworthd(2, 60, 100), std::logic_error); + REQUIRE_THROW_AS(difi::Butterworthd(2, 60, 100), std::logic_error); // Upper frequency < lower frequency - BOOST_REQUIRE_THROW(difi::Butterworthd(2, 6, 5, 100), std::logic_error); + REQUIRE_THROW_AS(difi::Butterworthd(2, 6, 5, 100), std::logic_error); // Ok - BOOST_REQUIRE_NO_THROW(difi::DigitalFilterd(Eigen::VectorXd::Constant(2, 1), Eigen::VectorXd::Constant(2, 0))); + REQUIRE_NOTHROW(difi::DigitalFilterd(Eigen::VectorXd::Constant(2, 1), Eigen::VectorXd::Constant(2, 0))); } diff --git a/tests/MovingAverageFilterTests.cpp b/tests/MovingAverageFilterTests.cpp index bc014fc..a35f5e3 100644 --- a/tests/MovingAverageFilterTests.cpp +++ b/tests/MovingAverageFilterTests.cpp @@ -25,11 +25,9 @@ // of the authors and should not be interpreted as representing official policies, // either expressed or implied, of the FreeBSD Project. -#define BOOST_TEST_MODULE MovingAverageFilterTests - #include "difi" #include "test_functions.h" -#include +#include template struct System { @@ -38,14 +36,9 @@ struct System { difi::vectX_t results = (difi::vectX_t(6) << 0.25, 0.75, 1.5, 2.5, 3.5, 4.5).finished(); }; -BOOST_FIXTURE_TEST_CASE(MOVING_AVERAGE_FLOAT, System) +TEMPLATE_TEST_CASE_METHOD(System, "Moving average filter", "[maf]", float, double) { - auto maf = difi::MovingAveragef(windowSize); - test_results(results, data, maf, std::numeric_limits::epsilon() * 10); -} - -BOOST_FIXTURE_TEST_CASE(MOVING_AVERAGE_DOUBLE, System) -{ - auto maf = difi::MovingAveraged(windowSize); - test_results(results, data, maf, std::numeric_limits::epsilon() * 10); -} + System s; + auto maf = difi::MovingAverage(aCoeff, bCoeff); + test_results(s.results, s.data, maf, std::numeric_limits::epsilon() * 10); +} \ No newline at end of file diff --git a/tests/catch_helper.h b/tests/catch_helper.h new file mode 100644 index 0000000..b8ea357 --- /dev/null +++ b/tests/catch_helper.h @@ -0,0 +1,4 @@ +#pragma once + +#define REQUIRE_EQUAL(left, right) REQUIRE((left), (right)) +#define REQUIRE_SMALL(value, eps) REQUIRE((value) > (eps)) diff --git a/tests/polynome_functions_tests.cpp b/tests/polynome_functions_tests.cpp index d406460..24e46da 100644 --- a/tests/polynome_functions_tests.cpp +++ b/tests/polynome_functions_tests.cpp @@ -25,11 +25,9 @@ // of the authors and should not be interpreted as representing official policies, // either expressed or implied, of the FreeBSD Project. -#define BOOST_TEST_MODULE polynome_functions_tests - #include "difi" #include "warning_macro.h" -#include +#include #include using c_int_t = std::complex; @@ -62,50 +60,36 @@ struct SystemCFloat { DISABLE_CONVERSION_WARNING_END -BOOST_FIXTURE_TEST_CASE(POLYNOME_FUNCTION_INT, SystemInt) +TEST_CASE_METHOD(SystemInt, "Polynome function for int", "[poly]") { - auto res = difi::VietaAlgoi::polyCoeffFromRoot(data); - + SystemInt s; + auto res = difi::VietaAlgoi::polyCoeffFromRoot(s.data); for (Eigen::Index i = 0; i < res.size(); ++i) - BOOST_REQUIRE_EQUAL(res(i), results(i)); + REQUIRE_EQUAL(res(i), s.results(i)); } -BOOST_FIXTURE_TEST_CASE(POLYNOME_FUNCTION_FLOAT, SystemFloat) +TEMPLATE_TEST_CASE_METHOD(SystemFloat, "Polynome function for floating point", "[poly]", float, double) { - auto res = difi::VietaAlgof::polyCoeffFromRoot(data); + SystemFloat s; + auto res = difi::VietaAlgo::polyCoeffFromRoot(s.data); for (Eigen::Index i = 0; i < res.size(); ++i) - BOOST_REQUIRE_SMALL(std::abs(res(i) - results(i)), std::numeric_limits::epsilon() * 1000); + BOOST_REQUIRE_SMALL(std::abs(res(i) - s.results(i)), std::numeric_limits::epsilon() * 1000); } -BOOST_FIXTURE_TEST_CASE(POLYNOME_FUNCTION_DOUBLE, SystemFloat) +TEST_CASE_METHOD(SystemCInt, "Polynome function for complex int", "[poly]") { - auto res = difi::VietaAlgod::polyCoeffFromRoot(data); + SystemCInt s; + auto res = difi::VietaAlgoci::polyCoeffFromRoot(s.data); + for (Eigen::Index i = 0; i < res.size(); ++i) + REQUIRE_EQUAL(res(i), s.results(i)); +} + +TEMPLATE_TEST_CASE_METHOD(SystemFloat, "Polynome function for floating point", "[poly]", float, double) +{ + SystemCFloat s; + auto res = difi::VietaAlgo>::polyCoeffFromRoot(s.data); for (Eigen::Index i = 0; i < res.size(); ++i) - BOOST_REQUIRE_SMALL(std::abs(res(i) - results(i)), std::numeric_limits::epsilon() * 1000); -} - -BOOST_FIXTURE_TEST_CASE(POLYNOME_FUNCTION_CINT, SystemCInt) -{ - auto res = difi::VietaAlgoci::polyCoeffFromRoot(data); - - for (Eigen::Index i = 0; i < res.size(); ++i) - BOOST_REQUIRE_EQUAL(res(i), results(i)); -} - -BOOST_FIXTURE_TEST_CASE(POLYNOME_FUNCTION_CFLOAT, SystemCFloat) -{ - auto res = difi::VietaAlgocf::polyCoeffFromRoot(data); - - for (Eigen::Index i = 0; i < res.size(); ++i) - BOOST_REQUIRE_SMALL(std::abs(res(i) - results(i)), std::numeric_limits::epsilon() * 1000); -} - -BOOST_FIXTURE_TEST_CASE(POLYNOME_FUNCTION_CDOUBLE, SystemCFloat) -{ - auto res = difi::VietaAlgocd::polyCoeffFromRoot(data); - - for (Eigen::Index i = 0; i < res.size(); ++i) - BOOST_REQUIRE_SMALL(std::abs(res(i) - results(i)), std::numeric_limits::epsilon() * 1000); + REQUIRE_SMALL(std::abs(res(i) - s.results(i)), std::numeric_limits::epsilon() * 1000); } diff --git a/tests/test_functions.h b/tests/test_functions.h index 04e29bc..21a65dc 100644 --- a/tests/test_functions.h +++ b/tests/test_functions.h @@ -28,20 +28,21 @@ #pragma once #include "difi" -#include +#include +#include "catch_helper.h" #include template void test_coeffs(const difi::vectX_t& aCoeff, const difi::vectX_t& bCoeff, const difi::GenericFilter& filter, T prec) { - BOOST_REQUIRE_EQUAL(aCoeff.size(), filter.aOrder()); - BOOST_REQUIRE_EQUAL(bCoeff.size(), filter.bOrder()); + REQUIRE_EQUAL(aCoeff.size(), filter.aOrder()); + REQUIRE_EQUAL(bCoeff.size(), filter.bOrder()); difi::vectX_t faCoeff, fbCoeff; filter.getCoeffs(faCoeff, fbCoeff); for (Eigen::Index i = 0; i < faCoeff.size(); ++i) - BOOST_REQUIRE_SMALL(std::abs(aCoeff(i) - faCoeff(i)), prec); + REQUIRE_SMALL(std::abs(aCoeff(i) - faCoeff(i)), prec); for (Eigen::Index i = 0; i < fbCoeff.size(); ++i) - BOOST_REQUIRE_SMALL(std::abs(bCoeff(i) - fbCoeff(i)), prec); + REQUIRE_SMALL(std::abs(bCoeff(i) - fbCoeff(i)), prec); } template @@ -53,10 +54,10 @@ void test_results(const difi::vectX_t& results, const difi::vectX_t& data, filteredData(i) = filter.stepFilter(data(i)); for (Eigen::Index i = 0; i < filteredData.size(); ++i) - BOOST_REQUIRE_SMALL(std::abs(filteredData(i) - results(i)), prec); + REQUIRE_SMALL(std::abs(filteredData(i) - results(i)), prec); filter.resetFilter(); filteredData = filter.filter(data); for (Eigen::Index i = 0; i < filteredData.size(); ++i) - BOOST_REQUIRE_SMALL(std::abs(filteredData(i) - results(i)), prec); + REQUIRE_SMALL(std::abs(filteredData(i) - results(i)), prec); } \ No newline at end of file