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