Mercurial > hg > qm-dsp
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 | 
