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