Mercurial > hg > qm-dsp
diff tests/TestDCT.cpp @ 415:4ae4229a074a
Add DCT
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Wed, 07 Oct 2015 09:55:35 +0100 |
parents | |
children | 2de6184b2ce0 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/TestDCT.cpp Wed Oct 07 09:55:35 2015 +0100 @@ -0,0 +1,196 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +#include "dsp/transforms/DCT.h" + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MAIN + +#include <boost/test/unit_test.hpp> + +#include <stdexcept> + +using namespace std; + +BOOST_AUTO_TEST_SUITE(TestDCT) + +BOOST_AUTO_TEST_CASE(forwardArrayBounds) +{ + // initialise bins to something recognisable, so we can tell if + // they haven't been written; and allocate the inputs on the heap + // so that, if running under valgrind, we get warnings about + // overruns + double *in = new double[4]; + in[0] = 1; + in[1] = 1; + in[2] = -1; + in[3] = -1; + double out[] = { 999, 999, 999, 999, 999, 999 }; + DCT(4).forward(in, out+1); + // And check we haven't overrun the arrays + BOOST_CHECK_EQUAL(out[0], 999.0); + BOOST_CHECK_EQUAL(out[5], 999.0); + delete[] in; +} + +BOOST_AUTO_TEST_CASE(u_forwardArrayBounds) +{ + // initialise bins to something recognisable, so we can tell if + // they haven't been written; and allocate the inputs on the heap + // so that, if running under valgrind, we get warnings about + // overruns + double *in = new double[4]; + in[0] = 1; + in[1] = 1; + in[2] = -1; + in[3] = -1; + double out[] = { 999, 999, 999, 999, 999, 999 }; + DCT(4).forwardUnitary(in, out+1); + // And check we haven't overrun the arrays + BOOST_CHECK_EQUAL(out[0], 999.0); + BOOST_CHECK_EQUAL(out[5], 999.0); + delete[] in; +} + +BOOST_AUTO_TEST_CASE(inverseArrayBounds) +{ + // initialise bins to something recognisable, so we can tell if + // they haven't been written; and allocate the inputs on the heap + // so that, if running under valgrind, we get warnings about + // overruns + double *in = new double[4]; + in[0] = 1; + in[1] = 1; + in[2] = -1; + in[3] = -1; + double out[] = { 999, 999, 999, 999, 999, 999 }; + DCT(4).inverse(in, out+1); + // And check we haven't overrun the arrays + BOOST_CHECK_EQUAL(out[0], 999.0); + BOOST_CHECK_EQUAL(out[5], 999.0); + delete[] in; + +} + +BOOST_AUTO_TEST_CASE(u_inverseArrayBounds) +{ + // initialise bins to something recognisable, so we can tell if + // they haven't been written; and allocate the inputs on the heap + // so that, if running under valgrind, we get warnings about + // overruns + double *in = new double[4]; + in[0] = 1; + in[1] = 1; + in[2] = -1; + in[3] = -1; + double out[] = { 999, 999, 999, 999, 999, 999 }; + DCT(4).inverseUnitary(in, out+1); + // And check we haven't overrun the arrays + BOOST_CHECK_EQUAL(out[0], 999.0); + BOOST_CHECK_EQUAL(out[5], 999.0); + delete[] in; +} + +BOOST_AUTO_TEST_CASE(nonU4) +{ + int n = 4; + vector<double> in { 1, 2, 3, 5 }; + vector<double> out(n); + vector<double> inv(n); + vector<double> expected { 22.0, -8.1564, 1.4142, -1.2137 }; + + DCT d(n); + + // our expected values are very approximate + double thresh = 1e-4; + + d.forward(in.data(), out.data()); + + for (int i = 0; i < n; ++i) { + BOOST_CHECK_SMALL(expected[i] - out[i], thresh); + } + + d.inverse(out.data(), inv.data()); + + for (int i = 0; i < n; ++i) { + BOOST_CHECK_SMALL(in[i] - inv[i], thresh); + } + + // do it again, just in case some internal state was modified in inverse + + d.forward(in.data(), out.data()); + + for (int i = 0; i < n; ++i) { + BOOST_CHECK_SMALL(expected[i] - out[i], thresh); + } +} + +BOOST_AUTO_TEST_CASE(u4) +{ + int n = 4; + vector<double> in { 1, 2, 3, 5 }; + vector<double> out(n); + vector<double> inv(n); + vector<double> expected { 5.5, -2.8837, 0.5, -0.4291 }; + + DCT d(n); + + // our expected values are very approximate + double thresh = 1e-4; + + d.forwardUnitary(in.data(), out.data()); + + for (int i = 0; i < n; ++i) { + BOOST_CHECK_SMALL(expected[i] - out[i], thresh); + } + + d.inverseUnitary(out.data(), inv.data()); + + for (int i = 0; i < n; ++i) { + BOOST_CHECK_SMALL(in[i] - inv[i], thresh); + } + + // do it again, just in case some internal state was modified in inverse + + d.forwardUnitary(in.data(), out.data()); + + for (int i = 0; i < n; ++i) { + BOOST_CHECK_SMALL(expected[i] - out[i], thresh); + } +} + +BOOST_AUTO_TEST_CASE(u5) +{ + int n = 5; + vector<double> in { 1, 2, 3, 5, 6 }; + vector<double> out(n); + vector<double> inv(n); + vector<double> expected { 7.6026, -4.1227, 0.3162, -0.0542, -0.3162 }; + + DCT d(n); + + // our expected values are very approximate + double thresh = 1e-4; + + d.forwardUnitary(in.data(), out.data()); + + for (int i = 0; i < n; ++i) { + BOOST_CHECK_SMALL(expected[i] - out[i], thresh); + } + + d.inverseUnitary(out.data(), inv.data()); + + for (int i = 0; i < n; ++i) { + BOOST_CHECK_SMALL(in[i] - inv[i], thresh); + } + + // do it again, just in case some internal state was modified in inverse + + d.forwardUnitary(in.data(), out.data()); + + for (int i = 0; i < n; ++i) { + BOOST_CHECK_SMALL(expected[i] - out[i], thresh); + } +} + +BOOST_AUTO_TEST_SUITE_END() +