Mercurial > hg > qm-dsp
comparison tests/TestFiltFilt.cpp @ 506:285f18c0992a
Tests and fixes for FiltFilt: Fix overrun; reset filter between forwards and backwards processes
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Wed, 05 Jun 2019 15:50:38 +0100 |
parents | |
children | d7b9691817a3 |
comparison
equal
deleted
inserted
replaced
505:930b5b0f707d | 506:285f18c0992a |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 #include "dsp/signalconditioning/FiltFilt.h" | |
4 | |
5 #define BOOST_TEST_DYN_LINK | |
6 #define BOOST_TEST_MAIN | |
7 | |
8 #include <boost/test/unit_test.hpp> | |
9 | |
10 #include <stdexcept> | |
11 | |
12 using namespace std; | |
13 | |
14 BOOST_AUTO_TEST_SUITE(TestFiltFilt) | |
15 | |
16 // Our FiltFilt is, apparently intentionally (?) a bit different from | |
17 // the equivalents in MATLAB and Octave (which themselves also differ) | |
18 // in how it handles transients at either end. While the three should | |
19 // all be "roughly" the same, all produce slightly different values. | |
20 // So the "expected" values here are, unfortunately, simply produced | |
21 // by the function itself, in a process involving tracing the values | |
22 // passed in to each of the filter stages within it and compared their | |
23 // outputs against MATLAB. | |
24 | |
25 static vector<double> iir_a { 1,5.75501989315662,16.326056867468,28.779190797823,34.2874379215653,28.137815126537,15.6064643257793,5.37874515231553,0.913800050254382,0.0,0.0 }; | |
26 static vector<double> iir_b { 0.0031954608137085,0.0180937089815597,0.0508407778575426,0.0895040074158415,0.107385387168148,0.0895040074158415,0.0508407778575426,0.0180937089815597,0.0031954608137085,0.0,0.0 }; | |
27 | |
28 BOOST_AUTO_TEST_CASE(long_zeroes) | |
29 { | |
30 vector<double> a(iir_a); | |
31 vector<double> b(iir_b); | |
32 | |
33 vector<double> zeroes(1000, 0.0); | |
34 vector<double> expected(zeroes); | |
35 | |
36 FiltFilt f({ a, b }); | |
37 | |
38 int n = expected.size(); | |
39 vector<double> out(n, 0.0); | |
40 | |
41 f.process(zeroes.data(), out.data(), n); | |
42 | |
43 double thresh = 1e-12; | |
44 | |
45 for (int i = 0; i < n; ++i) { | |
46 BOOST_CHECK_SMALL(out[i] - expected[i], thresh); | |
47 } | |
48 } | |
49 | |
50 BOOST_AUTO_TEST_CASE(empty) | |
51 { | |
52 vector<double> a(iir_a); | |
53 vector<double> b(iir_b); | |
54 vector<double> in; | |
55 vector<double> out; | |
56 vector<double> expected; | |
57 | |
58 FiltFilt f({ a, b }); | |
59 | |
60 f.process(in.data(), out.data(), 0); | |
61 } | |
62 | |
63 BOOST_AUTO_TEST_CASE(single_value) | |
64 { | |
65 vector<double> a(iir_a); | |
66 vector<double> b(iir_b); | |
67 vector<double> in({ 1.0 }); | |
68 vector<double> out({ 0.0 }); | |
69 vector<double> expected({ -0.000236642942007 }); | |
70 | |
71 FiltFilt f({ a, b }); | |
72 | |
73 f.process(in.data(), out.data(), 1); | |
74 | |
75 double thresh = 1e-12; | |
76 | |
77 BOOST_CHECK_SMALL(out[0] - expected[0], thresh); | |
78 } | |
79 | |
80 BOOST_AUTO_TEST_CASE(shortish) | |
81 { | |
82 vector<double> a(iir_a); | |
83 vector<double> b(iir_b); | |
84 | |
85 vector<double> in { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; | |
86 vector<double> expected { 0.0180395628158, -0.0317213769922, 0.0276928584707, -0.00944844359572, -0.0119394068579, 0.0252763627734, -0.0239770024451, 0.010560830803, 0.00726290602379, -0.0191915890394, 0.0202451156989, -0.0103434265023, -0.00341952789985, 0.0142823904341, -0.0160627659442, 0.00984876782803 }; | |
87 | |
88 FiltFilt f({ a, b }); | |
89 | |
90 int n = expected.size(); | |
91 vector<double> out(n, 0.0); | |
92 | |
93 f.process(in.data(), out.data(), n); | |
94 | |
95 double thresh = 1e-12; | |
96 | |
97 for (int i = 0; i < n; ++i) { | |
98 BOOST_CHECK_SMALL(out[i] - expected[i], thresh); | |
99 } | |
100 } | |
101 | |
102 BOOST_AUTO_TEST_SUITE_END() |