Line data Source code
1 : /**
2 : * @file test_FiniteDifferences.cpp
3 : *
4 : * @brief Tests for FiniteDifferences class
5 : *
6 : * @author Matthias Wieczorek - main code
7 : * @author Tobias Lasser - rewrite
8 : */
9 :
10 : #include "doctest/doctest.h"
11 : #include "FiniteDifferences.h"
12 : #include "VolumeDescriptor.h"
13 :
14 : using namespace elsa;
15 : using namespace doctest;
16 :
17 : TEST_SUITE_BEGIN("core");
18 :
19 28 : TEST_CASE_TEMPLATE("FiniteDifference: Testing construction", data_t, float, double)
20 : {
21 8 : GIVEN("a descriptor")
22 : {
23 8 : IndexVector_t numCoeff(2);
24 4 : numCoeff << 143, 48;
25 8 : VolumeDescriptor dd(numCoeff);
26 :
27 8 : IndexVector_t rangeCoeffs(3);
28 4 : rangeCoeffs << 143, 48, 2;
29 8 : VolumeDescriptor ddRange(rangeCoeffs);
30 :
31 6 : WHEN("instantiating a FiniteDifferences operator")
32 : {
33 4 : FiniteDifferences<data_t> fdOp(dd);
34 :
35 4 : THEN("the descriptors are as expected")
36 : {
37 2 : REQUIRE_EQ(fdOp.getDomainDescriptor(), dd);
38 2 : REQUIRE_EQ(fdOp.getRangeDescriptor(), ddRange);
39 : }
40 : }
41 :
42 6 : WHEN("cloning a FiniteDifference operator")
43 : {
44 4 : FiniteDifferences<data_t> fdOp(dd);
45 4 : auto fdOpClone = fdOp.clone();
46 :
47 4 : THEN("everything matches")
48 : {
49 2 : REQUIRE_NE(fdOpClone.get(), &fdOp);
50 2 : REQUIRE_EQ(*fdOpClone, fdOp);
51 : }
52 : }
53 : }
54 4 : }
55 :
56 30 : TEST_CASE_TEMPLATE("FiniteDifference: Testing in 1D", data_t, float, double)
57 : {
58 12 : GIVEN("some data")
59 : {
60 12 : IndexVector_t numCoeff(1);
61 6 : numCoeff << 5;
62 12 : VolumeDescriptor dd(numCoeff);
63 12 : Vector_t<data_t> data(dd.getNumberOfCoefficients());
64 6 : data << 30, 3, 2, -1, 7;
65 :
66 12 : DataContainer<data_t> dc(dd, data);
67 :
68 8 : WHEN("using forward differences (default mode)")
69 : {
70 4 : FiniteDifferences<data_t> fdOp(dd);
71 :
72 4 : THEN("the results are correct")
73 : {
74 4 : Vector_t<data_t> resApply(fdOp.getRangeDescriptor().getNumberOfCoefficients());
75 2 : resApply << -27, -1, -3, 8, -7;
76 4 : DataContainer<data_t> dcResApply(fdOp.getRangeDescriptor(), resApply);
77 :
78 2 : REQUIRE_EQ(dcResApply, fdOp.apply(dc));
79 :
80 4 : Vector_t<data_t> resApplyAdjoint(
81 2 : fdOp.getDomainDescriptor().getNumberOfCoefficients());
82 2 : resApplyAdjoint << 27, -26, 2, -11, 15;
83 2 : DataContainer<data_t> dcResApplyAdjoint(fdOp.getDomainDescriptor(),
84 : resApplyAdjoint);
85 :
86 2 : REQUIRE_EQ(dcResApplyAdjoint, fdOp.applyAdjoint(dcResApply));
87 : }
88 : }
89 :
90 8 : WHEN("using backward differences")
91 : {
92 4 : FiniteDifferences<data_t> fdOp(dd, FiniteDifferences<data_t>::DiffType::BACKWARD);
93 :
94 4 : THEN("the results are correct")
95 : {
96 4 : Vector_t<data_t> resApply(fdOp.getRangeDescriptor().getNumberOfCoefficients());
97 2 : resApply << 30, -27, -1, -3, 8;
98 4 : DataContainer<data_t> dcResApply(fdOp.getRangeDescriptor(), resApply);
99 :
100 2 : REQUIRE_EQ(dcResApply, fdOp.apply(dc));
101 :
102 4 : Vector_t<data_t> resApplyAdjoint(
103 2 : fdOp.getDomainDescriptor().getNumberOfCoefficients());
104 2 : resApplyAdjoint << 57, -26, 2, -11, 8;
105 2 : DataContainer<data_t> dcResApplyAdjoint(fdOp.getDomainDescriptor(),
106 : resApplyAdjoint);
107 :
108 2 : REQUIRE_EQ(dcResApplyAdjoint, fdOp.applyAdjoint(dcResApply));
109 : }
110 : }
111 :
112 8 : WHEN("using central differences")
113 : {
114 4 : FiniteDifferences<data_t> fdOp(dd, FiniteDifferences<data_t>::DiffType::CENTRAL);
115 :
116 4 : THEN("the results are correct")
117 : {
118 4 : Vector_t<data_t> resApply(fdOp.getRangeDescriptor().getNumberOfCoefficients());
119 2 : resApply << 1.5, -14.0, -2.0, 2.5, 0.5;
120 4 : DataContainer<data_t> dcResApply(fdOp.getRangeDescriptor(), resApply);
121 :
122 2 : REQUIRE_EQ(dcResApply, fdOp.apply(dc));
123 :
124 4 : Vector_t<data_t> resApplyAdjoint(
125 2 : fdOp.getDomainDescriptor().getNumberOfCoefficients());
126 2 : resApplyAdjoint << 7.0, 1.75, -8.25, -1.25, 1.25;
127 2 : DataContainer<data_t> dcResApplyAdjoint(fdOp.getDomainDescriptor(),
128 : resApplyAdjoint);
129 :
130 2 : REQUIRE_EQ(dcResApplyAdjoint, fdOp.applyAdjoint(dcResApply));
131 : }
132 : }
133 : }
134 6 : }
135 :
136 30 : TEST_CASE_TEMPLATE("FiniteDifference: Testing in 2D", data_t, float, double)
137 : {
138 12 : GIVEN("some data")
139 : {
140 12 : IndexVector_t numCoeff(2);
141 6 : numCoeff << 4, 4;
142 12 : VolumeDescriptor dd(numCoeff);
143 12 : Vector_t<data_t> data(dd.getNumberOfCoefficients());
144 6 : data << 16, 5, 9, 4, 2, 11, 7, 14, 3, 10, 6, 15, 13, 8, 12, 1;
145 12 : DataContainer<data_t> dc(dd, data);
146 :
147 8 : WHEN("using forward differences (default)")
148 : {
149 4 : FiniteDifferences<data_t> fdOp(dd);
150 :
151 4 : THEN("the results are correct")
152 : {
153 4 : Vector_t<data_t> res(fdOp.getRangeDescriptor().getNumberOfCoefficients());
154 4 : res << -11, 4, -5, -4, 9, -4, 7, -14, 7, -4, 9, -15, -5, 4, -11, -1, -14, 6, -2, 10,
155 4 : 1, -1, -1, 1, 10, -2, 6, -14, -13, -8, -12, -1;
156 2 : DataContainer<data_t> dcRes(fdOp.getRangeDescriptor(), res);
157 :
158 2 : REQUIRE_EQ(dcRes, fdOp.apply(dc));
159 : }
160 : }
161 :
162 8 : WHEN("using backward differences")
163 : {
164 4 : FiniteDifferences<data_t> fdOp(dd, FiniteDifferences<data_t>::DiffType::BACKWARD);
165 :
166 4 : THEN("the results are correct")
167 : {
168 4 : Vector_t<data_t> res(fdOp.getRangeDescriptor().getNumberOfCoefficients());
169 4 : res << 16, -11, 4, -5, 2, 9, -4, 7, 3, 7, -4, 9, 13, -5, 4, -11, 16, 5, 9, 4, -14,
170 4 : 6, -2, 10, 1, -1, -1, 1, 10, -2, 6, -14;
171 2 : DataContainer<data_t> dcRes(fdOp.getRangeDescriptor(), res);
172 :
173 2 : REQUIRE_EQ(dcRes, fdOp.apply(dc));
174 : }
175 : }
176 :
177 8 : WHEN("using central differences")
178 : {
179 4 : FiniteDifferences<data_t> fdOp(dd, FiniteDifferences<data_t>::DiffType::CENTRAL);
180 :
181 4 : THEN("the results are correct")
182 : {
183 4 : Vector_t<data_t> res(fdOp.getRangeDescriptor().getNumberOfCoefficients());
184 4 : res << 2.5, -3.5, -0.5, -4.5, 5.5, 2.5, 1.5, -3.5, 5.0, 1.5, 2.5, -3.0, 4.0, -0.5,
185 2 : -3.5, -6.0,
186 : //
187 2 : 1.0, 5.5, 3.5, 7.0, -6.5, 2.5, -1.5, 5.5, 5.5, -1.5, 2.5, -6.5, -1.5, -5.0,
188 4 : -3.0, -7.5;
189 2 : DataContainer<data_t> dcRes(fdOp.getRangeDescriptor(), res);
190 :
191 2 : REQUIRE_EQ(dcRes, fdOp.apply(dc));
192 : }
193 : }
194 : }
195 6 : }
196 :
197 30 : TEST_CASE_TEMPLATE("FiniteDifference: Testing in 2D with not all dimensions active", data_t, float,
198 : double)
199 : {
200 12 : GIVEN("some data")
201 : {
202 12 : IndexVector_t numCoeff(2);
203 6 : numCoeff << 4, 4;
204 12 : VolumeDescriptor dd(numCoeff);
205 12 : Vector_t<data_t> data(dd.getNumberOfCoefficients());
206 6 : data << 16, 5, 9, 4, 2, 11, 7, 14, 3, 10, 6, 15, 13, 8, 12, 1;
207 12 : DataContainer<data_t> dc(dd, data);
208 :
209 8 : WHEN("using forward differences (default)")
210 : {
211 4 : BooleanVector_t activeDims(2);
212 2 : activeDims << true, false;
213 4 : FiniteDifferences<data_t> fdOp1(dd, activeDims);
214 :
215 2 : activeDims << false, true;
216 4 : FiniteDifferences<data_t> fdOp2(dd, activeDims);
217 :
218 4 : THEN("the results are correct")
219 : {
220 4 : Vector_t<data_t> res1(fdOp1.getRangeDescriptor().getNumberOfCoefficients());
221 2 : res1 << -11, 4, -5, -4, 9, -4, 7, -14, 7, -4, 9, -15, -5, 4, -11, -1;
222 4 : DataContainer<data_t> dcRes1(fdOp1.getRangeDescriptor(), res1);
223 :
224 2 : REQUIRE_EQ(dcRes1, fdOp1.apply(dc));
225 :
226 4 : Vector_t<data_t> res2(fdOp2.getRangeDescriptor().getNumberOfCoefficients());
227 2 : res2 << -14, 6, -2, 10, 1, -1, -1, 1, 10, -2, 6, -14, -13, -8, -12, -1;
228 2 : DataContainer<data_t> dcRes2(fdOp2.getRangeDescriptor(), res2);
229 :
230 2 : REQUIRE_EQ(dcRes2, fdOp2.apply(dc));
231 : }
232 : }
233 :
234 8 : WHEN("using backward differences")
235 : {
236 4 : BooleanVector_t activeDims(2);
237 2 : activeDims << true, false;
238 4 : FiniteDifferences<data_t> fdOp1(dd, activeDims,
239 : FiniteDifferences<data_t>::DiffType::BACKWARD);
240 :
241 2 : activeDims << false, true;
242 4 : FiniteDifferences<data_t> fdOp2(dd, activeDims,
243 : FiniteDifferences<data_t>::DiffType::BACKWARD);
244 :
245 4 : THEN("the results are correct")
246 : {
247 4 : Vector_t<data_t> res1(fdOp1.getRangeDescriptor().getNumberOfCoefficients());
248 2 : res1 << 16, -11, 4, -5, 2, 9, -4, 7, 3, 7, -4, 9, 13, -5, 4, -11;
249 4 : DataContainer<data_t> dcRes1(fdOp1.getRangeDescriptor(), res1);
250 :
251 2 : REQUIRE_EQ(dcRes1, fdOp1.apply(dc));
252 :
253 4 : Vector_t<data_t> res2(fdOp2.getRangeDescriptor().getNumberOfCoefficients());
254 2 : res2 << 16, 5, 9, 4, -14, 6, -2, 10, 1, -1, -1, 1, 10, -2, 6, -14;
255 2 : DataContainer<data_t> dcRes2(fdOp2.getRangeDescriptor(), res2);
256 :
257 2 : REQUIRE_EQ(dcRes2, fdOp2.apply(dc));
258 : }
259 : }
260 :
261 8 : WHEN("using central differences")
262 : {
263 4 : BooleanVector_t activeDims(2);
264 2 : activeDims << true, false;
265 4 : FiniteDifferences<data_t> fdOp1(dd, activeDims,
266 : FiniteDifferences<data_t>::DiffType::CENTRAL);
267 :
268 2 : activeDims << false, true;
269 4 : FiniteDifferences<data_t> fdOp2(dd, activeDims,
270 : FiniteDifferences<data_t>::DiffType::CENTRAL);
271 :
272 4 : THEN("the results are correct")
273 : {
274 4 : Vector_t<data_t> res1(fdOp1.getRangeDescriptor().getNumberOfCoefficients());
275 4 : res1 << 2.5, -3.5, -0.5, -4.5, 5.5, 2.5, 1.5, -3.5, 5.0, 1.5, 2.5, -3.0, 4.0, -0.5,
276 4 : -3.5, -6.0;
277 4 : DataContainer<data_t> dcRes1(fdOp1.getRangeDescriptor(), res1);
278 :
279 2 : REQUIRE_EQ(dcRes1, fdOp1.apply(dc));
280 :
281 4 : Vector_t<data_t> res2(fdOp2.getRangeDescriptor().getNumberOfCoefficients());
282 4 : res2 << 1.0, 5.5, 3.5, 7.0, -6.5, 2.5, -1.5, 5.5, 5.5, -1.5, 2.5, -6.5, -1.5, -5.0,
283 4 : -3.0, -7.5;
284 2 : DataContainer<data_t> dcRes2(fdOp2.getRangeDescriptor(), res2);
285 :
286 2 : REQUIRE_EQ(dcRes2, fdOp2.apply(dc));
287 : }
288 : }
289 : }
290 6 : }
291 : TEST_SUITE_END();
|