cannam@506
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
cannam@506
|
2
|
cannam@506
|
3 #include "dsp/signalconditioning/FiltFilt.h"
|
cannam@506
|
4
|
cannam@506
|
5 #define BOOST_TEST_DYN_LINK
|
cannam@506
|
6 #define BOOST_TEST_MAIN
|
cannam@506
|
7
|
cannam@506
|
8 #include <boost/test/unit_test.hpp>
|
cannam@506
|
9
|
cannam@506
|
10 #include <stdexcept>
|
cannam@506
|
11
|
cannam@506
|
12 using namespace std;
|
cannam@506
|
13
|
cannam@506
|
14 BOOST_AUTO_TEST_SUITE(TestFiltFilt)
|
cannam@506
|
15
|
cannam@506
|
16 // Our FiltFilt is, apparently intentionally (?) a bit different from
|
cannam@506
|
17 // the equivalents in MATLAB and Octave (which themselves also differ)
|
cannam@506
|
18 // in how it handles transients at either end. While the three should
|
cannam@506
|
19 // all be "roughly" the same, all produce slightly different values.
|
cannam@506
|
20 // So the "expected" values here are, unfortunately, simply produced
|
cannam@506
|
21 // by the function itself, in a process involving tracing the values
|
cannam@506
|
22 // passed in to each of the filter stages within it and compared their
|
cannam@506
|
23 // outputs against MATLAB.
|
cannam@506
|
24
|
cannam@506
|
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 };
|
cannam@506
|
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 };
|
cannam@506
|
27
|
cannam@506
|
28 BOOST_AUTO_TEST_CASE(long_zeroes)
|
cannam@506
|
29 {
|
cannam@506
|
30 vector<double> a(iir_a);
|
cannam@506
|
31 vector<double> b(iir_b);
|
cannam@506
|
32
|
cannam@506
|
33 vector<double> zeroes(1000, 0.0);
|
cannam@506
|
34 vector<double> expected(zeroes);
|
cannam@506
|
35
|
cannam@506
|
36 FiltFilt f({ a, b });
|
cannam@506
|
37
|
cannam@506
|
38 int n = expected.size();
|
cannam@506
|
39 vector<double> out(n, 0.0);
|
cannam@506
|
40
|
cannam@506
|
41 f.process(zeroes.data(), out.data(), n);
|
cannam@506
|
42
|
cannam@506
|
43 double thresh = 1e-12;
|
cannam@506
|
44
|
cannam@506
|
45 for (int i = 0; i < n; ++i) {
|
cannam@506
|
46 BOOST_CHECK_SMALL(out[i] - expected[i], thresh);
|
cannam@506
|
47 }
|
cannam@506
|
48 }
|
cannam@506
|
49
|
cannam@506
|
50 BOOST_AUTO_TEST_CASE(empty)
|
cannam@506
|
51 {
|
cannam@506
|
52 vector<double> a(iir_a);
|
cannam@506
|
53 vector<double> b(iir_b);
|
cannam@506
|
54 vector<double> in;
|
cannam@506
|
55 vector<double> out;
|
cannam@506
|
56 vector<double> expected;
|
cannam@506
|
57
|
cannam@506
|
58 FiltFilt f({ a, b });
|
cannam@506
|
59
|
cannam@506
|
60 f.process(in.data(), out.data(), 0);
|
cannam@506
|
61 }
|
cannam@506
|
62
|
cannam@506
|
63 BOOST_AUTO_TEST_CASE(single_value)
|
cannam@506
|
64 {
|
cannam@506
|
65 vector<double> a(iir_a);
|
cannam@506
|
66 vector<double> b(iir_b);
|
cannam@506
|
67 vector<double> in({ 1.0 });
|
cannam@506
|
68 vector<double> out({ 0.0 });
|
cannam@507
|
69 vector<double> expected({ 0.000607783187363 });
|
cannam@506
|
70
|
cannam@506
|
71 FiltFilt f({ a, b });
|
cannam@506
|
72
|
cannam@506
|
73 f.process(in.data(), out.data(), 1);
|
cannam@506
|
74
|
cannam@506
|
75 double thresh = 1e-12;
|
cannam@506
|
76
|
cannam@506
|
77 BOOST_CHECK_SMALL(out[0] - expected[0], thresh);
|
cannam@506
|
78 }
|
cannam@506
|
79
|
cannam@506
|
80 BOOST_AUTO_TEST_CASE(shortish)
|
cannam@506
|
81 {
|
cannam@506
|
82 vector<double> a(iir_a);
|
cannam@506
|
83 vector<double> b(iir_b);
|
cannam@506
|
84
|
cannam@506
|
85 vector<double> in { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
|
cannam@507
|
86 vector<double> expected { 0.0183210564167, -0.0251812631055, 0.0182718199887, -0.00232894428926, -0.0131783133711, 0.0204387725824, -0.016092298975, 0.00402175146108, 0.00913732971217, -0.0158214509991, 0.0138601876508, -0.00455783828038, -0.00563875593951, 0.0121184171941, -0.011073916445, 0.00491681731861 };
|
cannam@506
|
87
|
cannam@506
|
88 FiltFilt f({ a, b });
|
cannam@506
|
89
|
cannam@506
|
90 int n = expected.size();
|
cannam@506
|
91 vector<double> out(n, 0.0);
|
cannam@506
|
92
|
cannam@506
|
93 f.process(in.data(), out.data(), n);
|
cannam@506
|
94
|
cannam@506
|
95 double thresh = 1e-12;
|
cannam@506
|
96
|
cannam@506
|
97 for (int i = 0; i < n; ++i) {
|
cannam@506
|
98 BOOST_CHECK_SMALL(out[i] - expected[i], thresh);
|
cannam@506
|
99 }
|
cannam@506
|
100 }
|
cannam@506
|
101
|
cannam@506
|
102 BOOST_AUTO_TEST_SUITE_END()
|