annotate tests/TestMedianFilter.cpp @ 395:a0829908bb74

Fix overrun in reading inverse complex-to-real FFT input (contrary to docs)
author Chris Cannam <c.cannam@qmul.ac.uk>
date Fri, 09 May 2014 14:35:46 +0100
parents e7010b8eb0c6
children 5ec47007b873
rev   line source
c@391 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
c@391 2
c@391 3 #include "maths/MedianFilter.h"
c@391 4
c@391 5 #include <cmath>
c@391 6
c@391 7 #define BOOST_TEST_DYN_LINK
c@391 8 #define BOOST_TEST_MAIN
c@391 9
c@391 10 #include <boost/test/unit_test.hpp>
c@391 11
c@391 12 BOOST_AUTO_TEST_SUITE(TestMedianFilter)
c@391 13
c@391 14 BOOST_AUTO_TEST_CASE(odd)
c@391 15 {
c@391 16 // A median filter of size N always retains a pool of N elements,
c@391 17 // which start out all-zero. So the output median will remain zero
c@391 18 // until N/2 elements have been pushed.
c@391 19 MedianFilter<double> f(3);
c@391 20 f.push(1); // 0 0 1
c@391 21 BOOST_CHECK_EQUAL(f.get(), 0);
c@391 22 BOOST_CHECK_EQUAL(f.get(), 0);
c@391 23 f.push(-3); // 0 1 -3
c@391 24 BOOST_CHECK_EQUAL(f.get(), 0);
c@391 25 f.push(5); // 1 -3 5
c@391 26 BOOST_CHECK_EQUAL(f.get(), 1);
c@391 27 f.push(7); // -3 5 7
c@391 28 BOOST_CHECK_EQUAL(f.get(), 5);
c@391 29 BOOST_CHECK_EQUAL(f.get(), 5);
c@391 30 f.push(3); // 5 7 3
c@391 31 BOOST_CHECK_EQUAL(f.get(), 5);
c@391 32 f.push(3); // 7 3 3
c@391 33 BOOST_CHECK_EQUAL(f.get(), 3);
c@391 34 }
c@391 35
c@391 36 BOOST_AUTO_TEST_CASE(even)
c@391 37 {
c@391 38 // Our median does not halve the difference (should it??), it just
c@391 39 // returns the next element from the input set
c@391 40 MedianFilter<double> f(4);
c@391 41 f.push(1); // 0 0 0 1
c@391 42 BOOST_CHECK_EQUAL(f.get(), 0);
c@391 43 BOOST_CHECK_EQUAL(f.get(), 0);
c@391 44 f.push(-3); // 0 0 1 -3
c@391 45 BOOST_CHECK_EQUAL(f.get(), 0);
c@391 46 f.push(5); // 0 1 -3 5
c@391 47 BOOST_CHECK_EQUAL(f.get(), 1);
c@391 48 f.push(7); // 1 -3 5 7
c@391 49 BOOST_CHECK_EQUAL(f.get(), 5);
c@391 50 BOOST_CHECK_EQUAL(f.get(), 5);
c@391 51 f.push(3); // -3 5 7 3
c@391 52 BOOST_CHECK_EQUAL(f.get(), 5);
c@391 53 f.push(3); // 5 7 3 3
c@391 54 BOOST_CHECK_EQUAL(f.get(), 5);
c@391 55 }
c@391 56
c@391 57 BOOST_AUTO_TEST_CASE(odd75)
c@391 58 {
c@391 59 MedianFilter<double> f(5, 75.f);
c@391 60 f.push(1); // 0 0 0 0 1
c@391 61 BOOST_CHECK_EQUAL(f.get(), 0);
c@391 62 BOOST_CHECK_EQUAL(f.get(), 0);
c@391 63 f.push(-3); // 0 0 0 1 -3
c@391 64 BOOST_CHECK_EQUAL(f.get(), 0);
c@391 65 f.push(5); // 0 0 1 -3 5
c@391 66 BOOST_CHECK_EQUAL(f.get(), 1);
c@391 67 f.push(7); // 0 1 -3 5 7
c@391 68 BOOST_CHECK_EQUAL(f.get(), 5);
c@391 69 BOOST_CHECK_EQUAL(f.get(), 5);
c@391 70 f.push(3); // 0 -3 5 7 3
c@391 71 BOOST_CHECK_EQUAL(f.get(), 5);
c@391 72 f.push(3); // 0 5 7 3 3
c@391 73 BOOST_CHECK_EQUAL(f.get(), 5);
c@391 74 }
c@391 75
c@391 76 BOOST_AUTO_TEST_CASE(even75)
c@391 77 {
c@391 78 MedianFilter<double> f(4, 75.f);
c@391 79 f.push(1); // 0 0 0 1
c@391 80 BOOST_CHECK_EQUAL(f.get(), 1);
c@391 81 BOOST_CHECK_EQUAL(f.get(), 1);
c@391 82 f.push(-3); // 0 0 1 -3
c@391 83 BOOST_CHECK_EQUAL(f.get(), 1);
c@391 84 f.push(5); // 0 1 -3 5
c@391 85 BOOST_CHECK_EQUAL(f.get(), 5);
c@391 86 f.push(7); // 1 -3 5 7
c@391 87 BOOST_CHECK_EQUAL(f.get(), 7);
c@391 88 BOOST_CHECK_EQUAL(f.get(), 7);
c@391 89 f.push(3); // -3 5 7 3
c@391 90 BOOST_CHECK_EQUAL(f.get(), 7);
c@391 91 f.push(3); // 5 7 3 3
c@391 92 BOOST_CHECK_EQUAL(f.get(), 7);
c@391 93 }
c@391 94
c@392 95 BOOST_AUTO_TEST_CASE(oddStandalone)
c@392 96 {
c@392 97 // The standalone (static filter() method) function is intended to
c@392 98 // match e.g. MATLAB median filter, filtering a row at once
c@392 99 // assuming the values beyond its edges are zeroes. This basically
c@392 100 // just means it needs to compensate for the latency in the raw
c@392 101 // filter:
c@392 102 //
c@392 103 // Raw filter
c@392 104 // 1 3 5 7 -> 0 1 3 5 (N=3)
c@392 105 // (because at each step only the values up to that step are
c@392 106 // available)
c@392 107 //
c@392 108 // Standalone function:
c@392 109 // 1 3 5 7 -> 1 3 5 5 (N=3)
c@392 110
c@392 111 std::vector<double> in;
c@392 112 in.push_back(1);
c@392 113 in.push_back(3);
c@392 114 in.push_back(5);
c@392 115 in.push_back(7);
c@392 116
c@392 117 std::vector<double> out = MedianFilter<double>::filter(3, in);
c@392 118 BOOST_CHECK_EQUAL(out[0], 1);
c@392 119 BOOST_CHECK_EQUAL(out[1], 3);
c@392 120 BOOST_CHECK_EQUAL(out[2], 5);
c@392 121 BOOST_CHECK_EQUAL(out[3], 5);
c@392 122 }
c@392 123
c@392 124 BOOST_AUTO_TEST_CASE(evenStandalone)
c@392 125 {
c@392 126 // See above. But note that the even length does not match the
c@392 127 // MATLAB because it doesn't halve the middle, as MATLAB does
c@392 128
c@392 129 std::vector<double> in;
c@392 130 in.push_back(1);
c@392 131 in.push_back(3);
c@392 132 in.push_back(5);
c@392 133 in.push_back(7);
c@392 134
c@392 135 std::vector<double> out = MedianFilter<double>::filter(4, in);
c@392 136 BOOST_CHECK_EQUAL(out[0], 3);
c@392 137 BOOST_CHECK_EQUAL(out[1], 5);
c@392 138 BOOST_CHECK_EQUAL(out[2], 5);
c@392 139 BOOST_CHECK_EQUAL(out[3], 5);
c@392 140 }
c@392 141
c@392 142 BOOST_AUTO_TEST_CASE(standaloneEmpty)
c@392 143 {
c@392 144 std::vector<double> in;
c@392 145 std::vector<double> out1 = MedianFilter<double>::filter(3, in);
c@392 146 BOOST_CHECK_EQUAL(out1.size(), 0);
c@392 147 std::vector<double> out2 = MedianFilter<double>::filter(4, in);
c@392 148 BOOST_CHECK_EQUAL(out2.size(), 0);
c@392 149 }
c@392 150
c@392 151 BOOST_AUTO_TEST_CASE(types)
c@392 152 {
c@392 153 MedianFilter<double> dfilt(3);
c@392 154 dfilt.push(1.2);
c@392 155 BOOST_CHECK_EQUAL(dfilt.get(), 0.0);
c@392 156 dfilt.push(2.4);
c@392 157 BOOST_CHECK_EQUAL(dfilt.get(), 1.2);
c@392 158 dfilt.push(1e-6);
c@392 159 BOOST_CHECK_EQUAL(dfilt.get(), 1.2);
c@392 160 dfilt.push(1e6);
c@392 161 BOOST_CHECK_EQUAL(dfilt.get(), 2.4);
c@392 162
c@392 163 MedianFilter<int> ifilt(3);
c@392 164 ifilt.push(1);
c@392 165 BOOST_CHECK_EQUAL(ifilt.get(), 0);
c@392 166 ifilt.push(2);
c@392 167 BOOST_CHECK_EQUAL(ifilt.get(), 1);
c@392 168 ifilt.push(0);
c@392 169 BOOST_CHECK_EQUAL(ifilt.get(), 1);
c@392 170 ifilt.push(1000);
c@392 171 BOOST_CHECK_EQUAL(ifilt.get(), 2);
c@392 172 }
c@392 173
c@391 174 BOOST_AUTO_TEST_SUITE_END()
c@391 175
c@391 176