Mercurial > hg > svcore
comparison base/test/TestMovingMedian.h @ 1573:f04038819c26 spectrogramparam
Introduce & make use of faster MovingMedian class (now with resize capability)
author | Chris Cannam |
---|---|
date | Thu, 08 Nov 2018 15:02:30 +0000 |
parents | |
children | cfcfec216c21 |
comparison
equal
deleted
inserted
replaced
1572:c36ffc195988 | 1573:f04038819c26 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 /* | |
4 Sonic Visualiser | |
5 An audio file viewer and annotation editor. | |
6 Centre for Digital Music, Queen Mary, University of London. | |
7 | |
8 This program is free software; you can redistribute it and/or | |
9 modify it under the terms of the GNU General Public License as | |
10 published by the Free Software Foundation; either version 2 of the | |
11 License, or (at your option) any later version. See the file | |
12 COPYING included with this distribution for more information. | |
13 */ | |
14 | |
15 #ifndef TEST_MOVING_MEDIAN_H | |
16 #define TEST_MOVING_MEDIAN_H | |
17 | |
18 #include "../MovingMedian.h" | |
19 | |
20 #include <QObject> | |
21 #include <QtTest> | |
22 #include <QDir> | |
23 | |
24 #include <iostream> | |
25 | |
26 using namespace std; | |
27 | |
28 class TestMovingMedian : public QObject | |
29 { | |
30 Q_OBJECT | |
31 | |
32 template <typename T> | |
33 void checkExpected(const vector<T> &output, | |
34 const vector<T> &expected) { | |
35 if (output.size() != expected.size()) { | |
36 cerr << "ERROR: output array size " << output.size() | |
37 << " differs from expected size " << expected.size() << endl; | |
38 } | |
39 for (int i = 0; i < int(output.size()); ++i) { | |
40 if (output[i] != expected[i]) { | |
41 cerr << "ERROR: Value at index " << i | |
42 << " in output array differs from expected" << endl; | |
43 cerr << "Output: "; | |
44 for (auto v: output) cerr << v << " "; | |
45 cerr << "\nExpected: "; | |
46 for (auto v: expected) cerr << v << " "; | |
47 cerr << endl; | |
48 break; | |
49 } | |
50 } | |
51 QCOMPARE(output, expected); | |
52 } | |
53 | |
54 template <typename T> | |
55 void testFixed(int n, | |
56 const vector<T> &input, | |
57 const vector<T> &expected, | |
58 double percentile = 50.0) { | |
59 vector<T> output; | |
60 MovingMedian<T> mm(n, percentile); | |
61 for (auto v: input) { | |
62 mm.push(v); | |
63 mm.checkIntegrity(); | |
64 output.push_back(mm.get()); | |
65 } | |
66 mm.checkIntegrity(); | |
67 checkExpected<T>(output, expected); | |
68 } | |
69 | |
70 private slots: | |
71 | |
72 void empty() { | |
73 MovingMedian<double> mm(3); | |
74 QCOMPARE(mm.get(), 0.0); | |
75 } | |
76 | |
77 void zeros() { | |
78 vector<double> input { 0.0, 0.0, 0.0, 0.0, 0.0 }; | |
79 vector<double> expected { 0.0, 0.0, 0.0, 0.0, 0.0 }; | |
80 testFixed<double>(3, input, expected); | |
81 } | |
82 | |
83 void ascending() { | |
84 vector<double> input { 1.0, 2.0, 3.0, 4.0, 5.0 }; | |
85 vector<double> expected { 0.0, 1.0, 2.0, 3.0, 4.0 }; | |
86 testFixed<double>(3, input, expected); | |
87 } | |
88 | |
89 void ascendingInt() { | |
90 vector<int> input { 1, 2, 3, 4, 5 }; | |
91 vector<int> expected { 0, 1, 2, 3, 4 }; | |
92 testFixed<int>(3, input, expected); | |
93 } | |
94 | |
95 void descending() { | |
96 vector<double> input { 5.0, 4.0, 3.0, 2.0, 1.0 }; | |
97 vector<double> expected { 0.0, 4.0, 4.0, 3.0, 2.0 }; | |
98 testFixed<double>(3, input, expected); | |
99 } | |
100 | |
101 void descendingInt() { | |
102 vector<int> input { 5, 4, 3, 2, 1 }; | |
103 vector<int> expected { 0, 4, 4, 3, 2 }; | |
104 testFixed<int>(3, input, expected); | |
105 } | |
106 | |
107 void duplicates() { | |
108 vector<double> input { 2.0, 2.0, 3.0, 4.0, 3.0 }; | |
109 vector<double> expected { 0.0, 2.0, 2.0, 3.0, 3.0 }; | |
110 testFixed<double>(3, input, expected); | |
111 } | |
112 | |
113 void percentile10() { | |
114 vector<double> input { 1.0, 2.0, 3.0, 4.0, 5.0 }; | |
115 vector<double> expected { 0.0, 0.0, 1.0, 2.0, 3.0 }; | |
116 testFixed<double>(3, input, expected, 10); | |
117 } | |
118 | |
119 void percentile90() { | |
120 vector<double> input { 1.0, 2.0, 3.0, 4.0, 5.0 }; | |
121 vector<double> expected { 1.0, 2.0, 3.0, 4.0, 5.0 }; | |
122 testFixed<double>(3, input, expected, 90); | |
123 } | |
124 | |
125 void even() { | |
126 vector<double> input { 5.0, 4.0, 3.0, 2.0, 1.0 }; | |
127 vector<double> expected { 0.0, 4.0, 4.0, 4.0, 3.0 }; | |
128 testFixed<double>(4, input, expected); | |
129 } | |
130 | |
131 void growing() { | |
132 vector<double> input { 2.0, 4.0, 3.0, 2.5, 2.5, 3.0, 1.0, 2.0, 1.0, 0.0 }; | |
133 vector<double> expected { 2.0, 4.0, 4.0, 3.0, 2.5, 2.5, 2.5, 2.5, 2.0, 1.0 }; | |
134 vector<double> output; | |
135 MovingMedian<double> mm(1); | |
136 for (int i = 0; i < int(input.size()); ++i) { | |
137 // sizes 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 | |
138 int sz = i/2 + 1; | |
139 mm.resize(sz); | |
140 QCOMPARE(mm.size(), sz); | |
141 mm.push(input[i]); | |
142 mm.checkIntegrity(); | |
143 output.push_back(mm.get()); | |
144 } | |
145 mm.checkIntegrity(); | |
146 checkExpected<double>(output, expected); | |
147 } | |
148 | |
149 void shrinking() { | |
150 vector<double> input { 2.0, 4.0, 3.0, 2.5, 2.5, 3.0, 1.0, 2.0, 1.0, 0.0 }; | |
151 vector<double> expected { 0.0, 0.0, 3.0, 3.0, 2.5, 2.5, 3.0, 2.0, 1.0, 0.0 }; | |
152 vector<double> output; | |
153 MovingMedian<double> mm(99); | |
154 for (int i = 0; i < int(input.size()); ++i) { | |
155 // sizes 5, 5, 4, 4, 3, 3, 2, 2, 1, 1 | |
156 int sz = 5 - i/2; | |
157 mm.resize(sz); | |
158 QCOMPARE(mm.size(), sz); | |
159 mm.push(input[i]); | |
160 mm.checkIntegrity(); | |
161 output.push_back(mm.get()); | |
162 } | |
163 mm.checkIntegrity(); | |
164 checkExpected<double>(output, expected); | |
165 } | |
166 }; | |
167 | |
168 #endif |