Line data Source code
1 : /**
2 : * @file test_SoftThresholding.cpp
3 : *
4 : * @brief Tests for the SoftThresholding class
5 : *
6 : * @author Andi Braimllari
7 : */
8 :
9 : #include "Error.h"
10 : #include "SoftThresholding.h"
11 : #include "VolumeDescriptor.h"
12 :
13 : #include "doctest/doctest.h"
14 : #include <testHelpers.h>
15 :
16 : using namespace elsa;
17 : using namespace doctest;
18 :
19 : TEST_SUITE_BEGIN("proximity_operators");
20 :
21 : TEST_CASE_TEMPLATE("SoftThresholding: Testing construction", data_t, float, double)
22 4 : {
23 4 : GIVEN("a DataDescriptor")
24 4 : {
25 4 : IndexVector_t numCoeff(3);
26 4 : numCoeff << 45, 11, 7;
27 4 : VolumeDescriptor volDescr(numCoeff);
28 :
29 4 : WHEN("instantiating a SoftThresholding operator")
30 4 : {
31 2 : SoftThresholding<data_t> sThrOp(volDescr);
32 :
33 2 : THEN("the DataDescriptors are equal")
34 2 : {
35 2 : REQUIRE_EQ(sThrOp.getRangeDescriptor(), volDescr);
36 2 : }
37 2 : }
38 :
39 4 : WHEN("cloning a SoftThresholding operator")
40 4 : {
41 2 : SoftThresholding<data_t> sThrOp(volDescr);
42 2 : auto sThrOpClone = sThrOp.clone();
43 :
44 2 : THEN("cloned SoftThresholding operator equals original SoftThresholding operator")
45 2 : {
46 2 : REQUIRE_NE(sThrOpClone.get(), &sThrOp);
47 2 : REQUIRE_EQ(*sThrOpClone, sThrOp);
48 2 : }
49 2 : }
50 4 : }
51 4 : }
52 :
53 : TEST_CASE_TEMPLATE("SoftThresholding: Testing in 1D", data_t, float, double)
54 2 : {
55 2 : GIVEN("a DataDescriptor")
56 2 : {
57 2 : IndexVector_t numCoeff(1);
58 2 : numCoeff << 8;
59 2 : VolumeDescriptor volDescr(numCoeff);
60 :
61 2 : WHEN("Using SoftThresholding operator in 1D")
62 2 : {
63 2 : SoftThresholding<data_t> sThrOp(volDescr);
64 :
65 2 : THEN("Values under threshold=4 are 0 and values above are sign(v) * (abs(v) - t)")
66 2 : {
67 2 : Vector_t<data_t> data(volDescr.getNumberOfCoefficients());
68 2 : data << -2, 3, 4, -7, 7, 8, 8, 3;
69 2 : DataContainer<data_t> dataCont(volDescr, data);
70 :
71 2 : Vector_t<data_t> expectedRes(sThrOp.getRangeDescriptor().getNumberOfCoefficients());
72 2 : expectedRes << 0, 0, 0, -3, 3, 4, 4, 0;
73 2 : DataContainer<data_t> dCRes(sThrOp.getRangeDescriptor(), expectedRes);
74 :
75 2 : REQUIRE_UNARY(
76 2 : isApprox(dCRes, sThrOp.apply(dataCont, geometry::Threshold<data_t>{4})));
77 2 : }
78 2 : }
79 2 : }
80 2 : }
81 :
82 : TEST_CASE_TEMPLATE("SoftThresholding: Testing in 3D", data_t, float, double)
83 2 : {
84 2 : GIVEN("a DataDescriptor")
85 2 : {
86 2 : IndexVector_t numCoeff(3);
87 2 : numCoeff << 3, 2, 3;
88 2 : VolumeDescriptor volDescr(numCoeff);
89 :
90 2 : WHEN("Using SoftThresholding operator in 3D")
91 2 : {
92 2 : SoftThresholding<data_t> sThrOp(volDescr);
93 :
94 2 : THEN("Values under threshold=5 are 0 and values above are sign(v) * (abs(v) - t)")
95 2 : {
96 2 : Vector_t<data_t> data(volDescr.getNumberOfCoefficients());
97 2 : data << 2, 1, 6, 6, 1, 4, 2, -9, 7, 7, 7, 3, 1, 2, 8, 9, -4, 5;
98 2 : DataContainer<data_t> dataCont(volDescr, data);
99 :
100 2 : Vector_t<data_t> expectedRes(sThrOp.getRangeDescriptor().getNumberOfCoefficients());
101 2 : expectedRes << 0, 0, 1, 1, 0, 0, 0, -4, 2, 2, 2, 0, 0, 0, 3, 4, 0, 0;
102 2 : DataContainer<data_t> dCRes(sThrOp.getRangeDescriptor(), expectedRes);
103 :
104 2 : REQUIRE_UNARY(
105 2 : isApprox(dCRes, sThrOp.apply(dataCont, geometry::Threshold<data_t>{5})));
106 2 : }
107 2 : }
108 2 : }
109 2 : }
110 :
111 : TEST_CASE_TEMPLATE("SoftThresholding: Testing general behaviour", data_t, float, double)
112 8 : {
113 8 : GIVEN("a DataDescriptor")
114 8 : {
115 8 : IndexVector_t numCoeff(1);
116 8 : numCoeff << 8;
117 8 : VolumeDescriptor volDescr(numCoeff);
118 :
119 8 : WHEN("Using SoftThresholding operator")
120 8 : {
121 8 : SoftThresholding<data_t> sThrOp(volDescr);
122 :
123 8 : THEN("The zero vector is returned when the zero vector is given")
124 8 : {
125 2 : Vector_t<data_t> data(volDescr.getNumberOfCoefficients());
126 2 : data << 0, 0, 0, 0, 0, 0, 0, 0;
127 2 : DataContainer<data_t> dataCont(volDescr, data);
128 :
129 2 : Vector_t<data_t> expectedRes(sThrOp.getRangeDescriptor().getNumberOfCoefficients());
130 2 : expectedRes << 0, 0, 0, 0, 0, 0, 0, 0;
131 2 : DataContainer<data_t> dCRes(sThrOp.getRangeDescriptor(), expectedRes);
132 :
133 2 : REQUIRE_UNARY(
134 2 : isApprox(dCRes, sThrOp.apply(dataCont, geometry::Threshold<data_t>{4})));
135 2 : }
136 :
137 8 : THEN("SoftThresholding operator throws exception for t = 0")
138 8 : {
139 2 : Vector_t<data_t> data(volDescr.getNumberOfCoefficients());
140 2 : data << 0, 0, 0, 0, 0, 0, 0, 0;
141 2 : DataContainer<data_t> dC(volDescr, data);
142 :
143 : // actually the geometry::Threshold throws this
144 2 : REQUIRE_THROWS_AS(sThrOp.apply(dC, geometry::Threshold<data_t>{0}),
145 2 : InvalidArgumentError);
146 2 : }
147 :
148 8 : THEN("SoftThresholding operator throws exception for t < 0")
149 8 : {
150 2 : Vector_t<data_t> data(volDescr.getNumberOfCoefficients());
151 2 : data << 0, 0, 0, 0, 0, 0, 0, 0;
152 2 : DataContainer<data_t> dataCont(volDescr, data);
153 :
154 : // actually the geometry::Threshold throws this
155 2 : REQUIRE_THROWS_AS(sThrOp.apply(dataCont, geometry::Threshold<data_t>{-1}),
156 2 : InvalidArgumentError);
157 2 : }
158 :
159 8 : THEN("SoftThresholding operator throws exception for differently sized v and prox")
160 8 : {
161 2 : Vector_t<data_t> data(volDescr.getNumberOfCoefficients());
162 2 : data << 0, 0, 0, 0, 0, 0, 0, 0;
163 2 : DataContainer<data_t> dC(volDescr, data);
164 :
165 2 : IndexVector_t numCoeff1(1);
166 2 : numCoeff1 << 9;
167 2 : VolumeDescriptor volDescr1(numCoeff1);
168 2 : Vector_t<data_t> data1(volDescr1.getNumberOfCoefficients());
169 2 : data1 << 0, 0, 0, 0, 0, 0, 0, 0, 0;
170 2 : DataContainer<data_t> dC1(volDescr1, data1);
171 :
172 2 : REQUIRE_THROWS_AS(sThrOp.apply(dC, geometry::Threshold<data_t>{1}, dC1),
173 2 : LogicError);
174 2 : }
175 8 : }
176 8 : }
177 8 : }
178 :
179 : TEST_SUITE_END();
|