Mercurial > hg > svcore
comparison base/test/TestMovingMedian.h @ 1577:50fe6d6a5ef0
Merge from branch spectrogramparam
author | Chris Cannam |
---|---|
date | Wed, 14 Nov 2018 14:21:53 +0000 |
parents | cfcfec216c21 |
children |
comparison
equal
deleted
inserted
replaced
1570:410819150cd3 | 1577:50fe6d6a5ef0 |
---|---|
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 std::cerr << "ERROR: output array size " << output.size() | |
37 << " differs from expected size " << expected.size() | |
38 << std::endl; | |
39 } | |
40 for (int i = 0; i < int(output.size()); ++i) { | |
41 if (output[i] != expected[i]) { | |
42 std::cerr << "ERROR: Value at index " << i | |
43 << " in output array differs from expected" | |
44 << std::endl; | |
45 std::cerr << "Output: "; | |
46 for (auto v: output) std::cerr << v << " "; | |
47 std::cerr << "\nExpected: "; | |
48 for (auto v: expected) std::cerr << v << " "; | |
49 std::cerr << std::endl; | |
50 break; | |
51 } | |
52 } | |
53 QCOMPARE(output, expected); | |
54 } | |
55 | |
56 template <typename T> | |
57 void testFixed(int n, | |
58 const vector<T> &input, | |
59 const vector<T> &expected, | |
60 double percentile = 50.0) { | |
61 vector<T> output; | |
62 MovingMedian<T> mm(n, percentile); | |
63 for (auto v: input) { | |
64 mm.push(v); | |
65 mm.checkIntegrity(); | |
66 output.push_back(mm.get()); | |
67 } | |
68 mm.checkIntegrity(); | |
69 checkExpected<T>(output, expected); | |
70 } | |
71 | |
72 private slots: | |
73 | |
74 void empty() { | |
75 MovingMedian<double> mm(3); | |
76 QCOMPARE(mm.get(), 0.0); | |
77 } | |
78 | |
79 void zeros() { | |
80 vector<double> input { 0.0, 0.0, 0.0, 0.0, 0.0 }; | |
81 vector<double> expected { 0.0, 0.0, 0.0, 0.0, 0.0 }; | |
82 testFixed<double>(3, input, expected); | |
83 } | |
84 | |
85 void ascending() { | |
86 vector<double> input { 1.0, 2.0, 3.0, 4.0, 5.0 }; | |
87 vector<double> expected { 0.0, 1.0, 2.0, 3.0, 4.0 }; | |
88 testFixed<double>(3, input, expected); | |
89 } | |
90 | |
91 void ascendingInt() { | |
92 vector<int> input { 1, 2, 3, 4, 5 }; | |
93 vector<int> expected { 0, 1, 2, 3, 4 }; | |
94 testFixed<int>(3, input, expected); | |
95 } | |
96 | |
97 void descending() { | |
98 vector<double> input { 5.0, 4.0, 3.0, 2.0, 1.0 }; | |
99 vector<double> expected { 0.0, 4.0, 4.0, 3.0, 2.0 }; | |
100 testFixed<double>(3, input, expected); | |
101 } | |
102 | |
103 void descendingInt() { | |
104 vector<int> input { 5, 4, 3, 2, 1 }; | |
105 vector<int> expected { 0, 4, 4, 3, 2 }; | |
106 testFixed<int>(3, input, expected); | |
107 } | |
108 | |
109 void duplicates() { | |
110 vector<double> input { 2.0, 2.0, 3.0, 4.0, 3.0 }; | |
111 vector<double> expected { 0.0, 2.0, 2.0, 3.0, 3.0 }; | |
112 testFixed<double>(3, input, expected); | |
113 } | |
114 | |
115 void percentile10() { | |
116 vector<double> input { 1.0, 2.0, 3.0, 4.0, 5.0 }; | |
117 vector<double> expected { 0.0, 0.0, 1.0, 2.0, 3.0 }; | |
118 testFixed<double>(3, input, expected, 10); | |
119 } | |
120 | |
121 void percentile90() { | |
122 vector<double> input { 1.0, 2.0, 3.0, 4.0, 5.0 }; | |
123 vector<double> expected { 1.0, 2.0, 3.0, 4.0, 5.0 }; | |
124 testFixed<double>(3, input, expected, 90); | |
125 } | |
126 | |
127 void even() { | |
128 vector<double> input { 5.0, 4.0, 3.0, 2.0, 1.0 }; | |
129 vector<double> expected { 0.0, 4.0, 4.0, 4.0, 3.0 }; | |
130 testFixed<double>(4, input, expected); | |
131 } | |
132 | |
133 void growing() { | |
134 vector<double> input { 2.0, 4.0, 3.0, 2.5, 2.5, 3.0, 1.0, 2.0, 1.0, 0.0 }; | |
135 vector<double> expected { 2.0, 4.0, 4.0, 3.0, 2.5, 2.5, 2.5, 2.5, 2.0, 1.0 }; | |
136 vector<double> output; | |
137 MovingMedian<double> mm(1); | |
138 for (int i = 0; i < int(input.size()); ++i) { | |
139 // sizes 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 | |
140 int sz = i/2 + 1; | |
141 mm.resize(sz); | |
142 QCOMPARE(mm.size(), sz); | |
143 mm.push(input[i]); | |
144 mm.checkIntegrity(); | |
145 output.push_back(mm.get()); | |
146 } | |
147 mm.checkIntegrity(); | |
148 checkExpected<double>(output, expected); | |
149 } | |
150 | |
151 void shrinking() { | |
152 vector<double> input { 2.0, 4.0, 3.0, 2.5, 2.5, 3.0, 1.0, 2.0, 1.0, 0.0 }; | |
153 vector<double> expected { 0.0, 0.0, 3.0, 3.0, 2.5, 2.5, 3.0, 2.0, 1.0, 0.0 }; | |
154 vector<double> output; | |
155 MovingMedian<double> mm(99); | |
156 for (int i = 0; i < int(input.size()); ++i) { | |
157 // sizes 5, 5, 4, 4, 3, 3, 2, 2, 1, 1 | |
158 int sz = 5 - i/2; | |
159 mm.resize(sz); | |
160 QCOMPARE(mm.size(), sz); | |
161 mm.push(input[i]); | |
162 mm.checkIntegrity(); | |
163 output.push_back(mm.get()); | |
164 } | |
165 mm.checkIntegrity(); | |
166 checkExpected<double>(output, expected); | |
167 } | |
168 }; | |
169 | |
170 #endif |