comparison tests/TestDCT.cpp @ 191:857ca50ca25f

Add DCT
author Chris Cannam
date Wed, 07 Oct 2015 09:55:35 +0100
parents
children 2de6184b2ce0
comparison
equal deleted inserted replaced
189:e4a57215ddee 191:857ca50ca25f
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 #include "dsp/transforms/DCT.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(TestDCT)
15
16 BOOST_AUTO_TEST_CASE(forwardArrayBounds)
17 {
18 // initialise bins to something recognisable, so we can tell if
19 // they haven't been written; and allocate the inputs on the heap
20 // so that, if running under valgrind, we get warnings about
21 // overruns
22 double *in = new double[4];
23 in[0] = 1;
24 in[1] = 1;
25 in[2] = -1;
26 in[3] = -1;
27 double out[] = { 999, 999, 999, 999, 999, 999 };
28 DCT(4).forward(in, out+1);
29 // And check we haven't overrun the arrays
30 BOOST_CHECK_EQUAL(out[0], 999.0);
31 BOOST_CHECK_EQUAL(out[5], 999.0);
32 delete[] in;
33 }
34
35 BOOST_AUTO_TEST_CASE(u_forwardArrayBounds)
36 {
37 // initialise bins to something recognisable, so we can tell if
38 // they haven't been written; and allocate the inputs on the heap
39 // so that, if running under valgrind, we get warnings about
40 // overruns
41 double *in = new double[4];
42 in[0] = 1;
43 in[1] = 1;
44 in[2] = -1;
45 in[3] = -1;
46 double out[] = { 999, 999, 999, 999, 999, 999 };
47 DCT(4).forwardUnitary(in, out+1);
48 // And check we haven't overrun the arrays
49 BOOST_CHECK_EQUAL(out[0], 999.0);
50 BOOST_CHECK_EQUAL(out[5], 999.0);
51 delete[] in;
52 }
53
54 BOOST_AUTO_TEST_CASE(inverseArrayBounds)
55 {
56 // initialise bins to something recognisable, so we can tell if
57 // they haven't been written; and allocate the inputs on the heap
58 // so that, if running under valgrind, we get warnings about
59 // overruns
60 double *in = new double[4];
61 in[0] = 1;
62 in[1] = 1;
63 in[2] = -1;
64 in[3] = -1;
65 double out[] = { 999, 999, 999, 999, 999, 999 };
66 DCT(4).inverse(in, out+1);
67 // And check we haven't overrun the arrays
68 BOOST_CHECK_EQUAL(out[0], 999.0);
69 BOOST_CHECK_EQUAL(out[5], 999.0);
70 delete[] in;
71
72 }
73
74 BOOST_AUTO_TEST_CASE(u_inverseArrayBounds)
75 {
76 // initialise bins to something recognisable, so we can tell if
77 // they haven't been written; and allocate the inputs on the heap
78 // so that, if running under valgrind, we get warnings about
79 // overruns
80 double *in = new double[4];
81 in[0] = 1;
82 in[1] = 1;
83 in[2] = -1;
84 in[3] = -1;
85 double out[] = { 999, 999, 999, 999, 999, 999 };
86 DCT(4).inverseUnitary(in, out+1);
87 // And check we haven't overrun the arrays
88 BOOST_CHECK_EQUAL(out[0], 999.0);
89 BOOST_CHECK_EQUAL(out[5], 999.0);
90 delete[] in;
91 }
92
93 BOOST_AUTO_TEST_CASE(nonU4)
94 {
95 int n = 4;
96 vector<double> in { 1, 2, 3, 5 };
97 vector<double> out(n);
98 vector<double> inv(n);
99 vector<double> expected { 22.0, -8.1564, 1.4142, -1.2137 };
100
101 DCT d(n);
102
103 // our expected values are very approximate
104 double thresh = 1e-4;
105
106 d.forward(in.data(), out.data());
107
108 for (int i = 0; i < n; ++i) {
109 BOOST_CHECK_SMALL(expected[i] - out[i], thresh);
110 }
111
112 d.inverse(out.data(), inv.data());
113
114 for (int i = 0; i < n; ++i) {
115 BOOST_CHECK_SMALL(in[i] - inv[i], thresh);
116 }
117
118 // do it again, just in case some internal state was modified in inverse
119
120 d.forward(in.data(), out.data());
121
122 for (int i = 0; i < n; ++i) {
123 BOOST_CHECK_SMALL(expected[i] - out[i], thresh);
124 }
125 }
126
127 BOOST_AUTO_TEST_CASE(u4)
128 {
129 int n = 4;
130 vector<double> in { 1, 2, 3, 5 };
131 vector<double> out(n);
132 vector<double> inv(n);
133 vector<double> expected { 5.5, -2.8837, 0.5, -0.4291 };
134
135 DCT d(n);
136
137 // our expected values are very approximate
138 double thresh = 1e-4;
139
140 d.forwardUnitary(in.data(), out.data());
141
142 for (int i = 0; i < n; ++i) {
143 BOOST_CHECK_SMALL(expected[i] - out[i], thresh);
144 }
145
146 d.inverseUnitary(out.data(), inv.data());
147
148 for (int i = 0; i < n; ++i) {
149 BOOST_CHECK_SMALL(in[i] - inv[i], thresh);
150 }
151
152 // do it again, just in case some internal state was modified in inverse
153
154 d.forwardUnitary(in.data(), out.data());
155
156 for (int i = 0; i < n; ++i) {
157 BOOST_CHECK_SMALL(expected[i] - out[i], thresh);
158 }
159 }
160
161 BOOST_AUTO_TEST_CASE(u5)
162 {
163 int n = 5;
164 vector<double> in { 1, 2, 3, 5, 6 };
165 vector<double> out(n);
166 vector<double> inv(n);
167 vector<double> expected { 7.6026, -4.1227, 0.3162, -0.0542, -0.3162 };
168
169 DCT d(n);
170
171 // our expected values are very approximate
172 double thresh = 1e-4;
173
174 d.forwardUnitary(in.data(), out.data());
175
176 for (int i = 0; i < n; ++i) {
177 BOOST_CHECK_SMALL(expected[i] - out[i], thresh);
178 }
179
180 d.inverseUnitary(out.data(), inv.data());
181
182 for (int i = 0; i < n; ++i) {
183 BOOST_CHECK_SMALL(in[i] - inv[i], thresh);
184 }
185
186 // do it again, just in case some internal state was modified in inverse
187
188 d.forwardUnitary(in.data(), out.data());
189
190 for (int i = 0; i < n; ++i) {
191 BOOST_CHECK_SMALL(expected[i] - out[i], thresh);
192 }
193 }
194
195 BOOST_AUTO_TEST_SUITE_END()
196