c@415: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ c@415: c@415: #include "dsp/transforms/DCT.h" c@415: c@415: #define BOOST_TEST_DYN_LINK c@415: #define BOOST_TEST_MAIN c@415: c@415: #include c@415: c@415: #include c@415: c@415: using namespace std; c@415: c@415: BOOST_AUTO_TEST_SUITE(TestDCT) c@415: c@415: BOOST_AUTO_TEST_CASE(forwardArrayBounds) c@415: { c@415: // initialise bins to something recognisable, so we can tell if c@415: // they haven't been written; and allocate the inputs on the heap c@415: // so that, if running under valgrind, we get warnings about c@415: // overruns c@415: double *in = new double[4]; c@415: in[0] = 1; c@415: in[1] = 1; c@415: in[2] = -1; c@415: in[3] = -1; c@415: double out[] = { 999, 999, 999, 999, 999, 999 }; c@415: DCT(4).forward(in, out+1); c@415: // And check we haven't overrun the arrays c@415: BOOST_CHECK_EQUAL(out[0], 999.0); c@415: BOOST_CHECK_EQUAL(out[5], 999.0); c@415: delete[] in; c@415: } c@415: c@415: BOOST_AUTO_TEST_CASE(u_forwardArrayBounds) c@415: { c@415: // initialise bins to something recognisable, so we can tell if c@415: // they haven't been written; and allocate the inputs on the heap c@415: // so that, if running under valgrind, we get warnings about c@415: // overruns c@415: double *in = new double[4]; c@415: in[0] = 1; c@415: in[1] = 1; c@415: in[2] = -1; c@415: in[3] = -1; c@415: double out[] = { 999, 999, 999, 999, 999, 999 }; c@415: DCT(4).forwardUnitary(in, out+1); c@415: // And check we haven't overrun the arrays c@415: BOOST_CHECK_EQUAL(out[0], 999.0); c@415: BOOST_CHECK_EQUAL(out[5], 999.0); c@415: delete[] in; c@415: } c@415: c@415: BOOST_AUTO_TEST_CASE(inverseArrayBounds) c@415: { c@415: // initialise bins to something recognisable, so we can tell if c@415: // they haven't been written; and allocate the inputs on the heap c@415: // so that, if running under valgrind, we get warnings about c@415: // overruns c@415: double *in = new double[4]; c@415: in[0] = 1; c@415: in[1] = 1; c@415: in[2] = -1; c@415: in[3] = -1; c@415: double out[] = { 999, 999, 999, 999, 999, 999 }; c@415: DCT(4).inverse(in, out+1); c@415: // And check we haven't overrun the arrays c@415: BOOST_CHECK_EQUAL(out[0], 999.0); c@415: BOOST_CHECK_EQUAL(out[5], 999.0); c@415: delete[] in; c@415: c@415: } c@415: c@415: BOOST_AUTO_TEST_CASE(u_inverseArrayBounds) c@415: { c@415: // initialise bins to something recognisable, so we can tell if c@415: // they haven't been written; and allocate the inputs on the heap c@415: // so that, if running under valgrind, we get warnings about c@415: // overruns c@415: double *in = new double[4]; c@415: in[0] = 1; c@415: in[1] = 1; c@415: in[2] = -1; c@415: in[3] = -1; c@415: double out[] = { 999, 999, 999, 999, 999, 999 }; c@415: DCT(4).inverseUnitary(in, out+1); c@415: // And check we haven't overrun the arrays c@415: BOOST_CHECK_EQUAL(out[0], 999.0); c@415: BOOST_CHECK_EQUAL(out[5], 999.0); c@415: delete[] in; c@415: } c@415: c@415: BOOST_AUTO_TEST_CASE(nonU4) c@415: { c@415: int n = 4; c@415: vector in { 1, 2, 3, 5 }; c@415: vector out(n); c@415: vector inv(n); c@415: vector expected { 22.0, -8.1564, 1.4142, -1.2137 }; c@415: c@415: DCT d(n); c@415: c@415: // our expected values are very approximate c@415: double thresh = 1e-4; c@415: c@415: d.forward(in.data(), out.data()); c@415: c@415: for (int i = 0; i < n; ++i) { c@415: BOOST_CHECK_SMALL(expected[i] - out[i], thresh); c@415: } c@415: c@415: d.inverse(out.data(), inv.data()); c@415: c@415: for (int i = 0; i < n; ++i) { c@415: BOOST_CHECK_SMALL(in[i] - inv[i], thresh); c@415: } c@415: c@415: // do it again, just in case some internal state was modified in inverse c@415: c@415: d.forward(in.data(), out.data()); c@415: c@415: for (int i = 0; i < n; ++i) { c@415: BOOST_CHECK_SMALL(expected[i] - out[i], thresh); c@415: } c@415: } c@415: c@415: BOOST_AUTO_TEST_CASE(u4) c@415: { c@415: int n = 4; c@415: vector in { 1, 2, 3, 5 }; c@415: vector out(n); c@415: vector inv(n); c@415: vector expected { 5.5, -2.8837, 0.5, -0.4291 }; c@415: c@415: DCT d(n); c@415: c@415: // our expected values are very approximate c@415: double thresh = 1e-4; c@415: c@415: d.forwardUnitary(in.data(), out.data()); c@415: c@415: for (int i = 0; i < n; ++i) { c@415: BOOST_CHECK_SMALL(expected[i] - out[i], thresh); c@415: } c@415: c@415: d.inverseUnitary(out.data(), inv.data()); c@415: c@415: for (int i = 0; i < n; ++i) { c@415: BOOST_CHECK_SMALL(in[i] - inv[i], thresh); c@415: } c@415: c@415: // do it again, just in case some internal state was modified in inverse c@415: c@415: d.forwardUnitary(in.data(), out.data()); c@415: c@415: for (int i = 0; i < n; ++i) { c@415: BOOST_CHECK_SMALL(expected[i] - out[i], thresh); c@415: } c@415: } c@415: c@415: BOOST_AUTO_TEST_CASE(u5) c@415: { c@415: int n = 5; c@415: vector in { 1, 2, 3, 5, 6 }; c@415: vector out(n); c@415: vector inv(n); c@415: vector expected { 7.6026, -4.1227, 0.3162, -0.0542, -0.3162 }; c@415: c@415: DCT d(n); c@415: c@415: // our expected values are very approximate c@415: double thresh = 1e-4; c@415: c@415: d.forwardUnitary(in.data(), out.data()); c@415: c@415: for (int i = 0; i < n; ++i) { c@415: BOOST_CHECK_SMALL(expected[i] - out[i], thresh); c@415: } c@415: c@415: d.inverseUnitary(out.data(), inv.data()); c@415: c@415: for (int i = 0; i < n; ++i) { c@415: BOOST_CHECK_SMALL(in[i] - inv[i], thresh); c@415: } c@415: c@415: // do it again, just in case some internal state was modified in inverse c@415: c@415: d.forwardUnitary(in.data(), out.data()); c@415: c@415: for (int i = 0; i < n; ++i) { c@415: BOOST_CHECK_SMALL(expected[i] - out[i], thresh); c@415: } c@415: } c@415: c@415: BOOST_AUTO_TEST_SUITE_END() c@415: