annotate tests/TestDCT.cpp @ 191:857ca50ca25f

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