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 : TEST_CASE_TEMPLATE("FiniteDifference: Testing construction", data_t, float, double)
20 4 : {
21 4 : GIVEN("a descriptor")
22 4 : {
23 4 : IndexVector_t numCoeff(2);
24 4 : numCoeff << 143, 48;
25 4 : VolumeDescriptor dd(numCoeff);
26 :
27 4 : IndexVector_t rangeCoeffs(3);
28 4 : rangeCoeffs << 143, 48, 2;
29 4 : VolumeDescriptor ddRange(rangeCoeffs);
30 :
31 4 : WHEN("instantiating a FiniteDifferences operator")
32 4 : {
33 2 : FiniteDifferences<data_t> fdOp(dd);
34 :
35 2 : THEN("the descriptors are as expected")
36 2 : {
37 2 : REQUIRE_EQ(fdOp.getDomainDescriptor(), dd);
38 2 : REQUIRE_EQ(fdOp.getRangeDescriptor(), ddRange);
39 2 : }
40 2 : }
41 :
42 4 : WHEN("cloning a FiniteDifference operator")
43 4 : {
44 2 : FiniteDifferences<data_t> fdOp(dd);
45 2 : auto fdOpClone = fdOp.clone();
46 :
47 2 : THEN("everything matches")
48 2 : {
49 2 : REQUIRE_NE(fdOpClone.get(), &fdOp);
50 2 : REQUIRE_EQ(*fdOpClone, fdOp);
51 2 : }
52 2 : }
53 4 : }
54 4 : }
55 :
56 : TEST_CASE_TEMPLATE("FiniteDifference: Testing in 1D", data_t, float, double)
57 6 : {
58 6 : GIVEN("some data")
59 6 : {
60 6 : IndexVector_t numCoeff(1);
61 6 : numCoeff << 5;
62 6 : VolumeDescriptor dd(numCoeff);
63 6 : Vector_t<data_t> data(dd.getNumberOfCoefficients());
64 6 : data << 30, 3, 2, -1, 7;
65 :
66 6 : DataContainer<data_t> dc(dd, data);
67 :
68 6 : WHEN("using forward differences (default mode)")
69 6 : {
70 2 : FiniteDifferences<data_t> fdOp(dd);
71 :
72 2 : THEN("the results are correct")
73 2 : {
74 2 : Vector_t<data_t> resApply(fdOp.getRangeDescriptor().getNumberOfCoefficients());
75 2 : resApply << -27, -1, -3, 8, -7;
76 2 : DataContainer<data_t> dcResApply(fdOp.getRangeDescriptor(), resApply);
77 :
78 2 : REQUIRE_EQ(dcResApply, fdOp.apply(dc));
79 :
80 2 : 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 2 : resApplyAdjoint);
85 :
86 2 : REQUIRE_EQ(dcResApplyAdjoint, fdOp.applyAdjoint(dcResApply));
87 2 : }
88 2 : }
89 :
90 6 : WHEN("using backward differences")
91 6 : {
92 2 : FiniteDifferences<data_t> fdOp(dd, FiniteDifferences<data_t>::DiffType::BACKWARD);
93 :
94 2 : THEN("the results are correct")
95 2 : {
96 2 : Vector_t<data_t> resApply(fdOp.getRangeDescriptor().getNumberOfCoefficients());
97 2 : resApply << 30, -27, -1, -3, 8;
98 2 : DataContainer<data_t> dcResApply(fdOp.getRangeDescriptor(), resApply);
99 :
100 2 : REQUIRE_EQ(dcResApply, fdOp.apply(dc));
101 :
102 2 : 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 2 : resApplyAdjoint);
107 :
108 2 : REQUIRE_EQ(dcResApplyAdjoint, fdOp.applyAdjoint(dcResApply));
109 2 : }
110 2 : }
111 :
112 6 : WHEN("using central differences")
113 6 : {
114 2 : FiniteDifferences<data_t> fdOp(dd, FiniteDifferences<data_t>::DiffType::CENTRAL);
115 :
116 2 : THEN("the results are correct")
117 2 : {
118 2 : Vector_t<data_t> resApply(fdOp.getRangeDescriptor().getNumberOfCoefficients());
119 2 : resApply << 1.5, -14.0, -2.0, 2.5, 0.5;
120 2 : DataContainer<data_t> dcResApply(fdOp.getRangeDescriptor(), resApply);
121 :
122 2 : REQUIRE_EQ(dcResApply, fdOp.apply(dc));
123 :
124 2 : 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 2 : resApplyAdjoint);
129 :
130 2 : REQUIRE_EQ(dcResApplyAdjoint, fdOp.applyAdjoint(dcResApply));
131 2 : }
132 2 : }
133 6 : }
134 6 : }
135 :
136 : TEST_CASE_TEMPLATE("FiniteDifference: Testing in 2D", data_t, float, double)
137 6 : {
138 6 : GIVEN("some data")
139 6 : {
140 6 : IndexVector_t numCoeff(2);
141 6 : numCoeff << 4, 4;
142 6 : VolumeDescriptor dd(numCoeff);
143 6 : 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 6 : DataContainer<data_t> dc(dd, data);
146 :
147 6 : WHEN("using forward differences (default)")
148 6 : {
149 2 : FiniteDifferences<data_t> fdOp(dd);
150 :
151 2 : THEN("the results are correct")
152 2 : {
153 2 : Vector_t<data_t> res(fdOp.getRangeDescriptor().getNumberOfCoefficients());
154 2 : res << -11, 4, -5, -4, 9, -4, 7, -14, 7, -4, 9, -15, -5, 4, -11, -1, -14, 6, -2, 10,
155 2 : 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 2 : }
160 2 : }
161 :
162 6 : WHEN("using backward differences")
163 6 : {
164 2 : FiniteDifferences<data_t> fdOp(dd, FiniteDifferences<data_t>::DiffType::BACKWARD);
165 :
166 2 : THEN("the results are correct")
167 2 : {
168 2 : Vector_t<data_t> res(fdOp.getRangeDescriptor().getNumberOfCoefficients());
169 2 : res << 16, -11, 4, -5, 2, 9, -4, 7, 3, 7, -4, 9, 13, -5, 4, -11, 16, 5, 9, 4, -14,
170 2 : 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 2 : }
175 2 : }
176 :
177 6 : WHEN("using central differences")
178 6 : {
179 2 : FiniteDifferences<data_t> fdOp(dd, FiniteDifferences<data_t>::DiffType::CENTRAL);
180 :
181 2 : THEN("the results are correct")
182 2 : {
183 2 : Vector_t<data_t> res(fdOp.getRangeDescriptor().getNumberOfCoefficients());
184 2 : 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 2 : -3.0, -7.5;
189 2 : DataContainer<data_t> dcRes(fdOp.getRangeDescriptor(), res);
190 :
191 2 : REQUIRE_EQ(dcRes, fdOp.apply(dc));
192 2 : }
193 2 : }
194 6 : }
195 6 : }
196 :
197 : TEST_CASE_TEMPLATE("FiniteDifference: Testing in 2D with not all dimensions active", data_t, float,
198 : double)
199 6 : {
200 6 : GIVEN("some data")
201 6 : {
202 6 : IndexVector_t numCoeff(2);
203 6 : numCoeff << 4, 4;
204 6 : VolumeDescriptor dd(numCoeff);
205 6 : 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 6 : DataContainer<data_t> dc(dd, data);
208 :
209 6 : WHEN("using forward differences (default)")
210 6 : {
211 2 : BooleanVector_t activeDims(2);
212 2 : activeDims << true, false;
213 2 : FiniteDifferences<data_t> fdOp1(dd, activeDims);
214 :
215 2 : activeDims << false, true;
216 2 : FiniteDifferences<data_t> fdOp2(dd, activeDims);
217 :
218 2 : THEN("the results are correct")
219 2 : {
220 2 : 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 2 : DataContainer<data_t> dcRes1(fdOp1.getRangeDescriptor(), res1);
223 :
224 2 : REQUIRE_EQ(dcRes1, fdOp1.apply(dc));
225 :
226 2 : 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 2 : }
232 2 : }
233 :
234 6 : WHEN("using backward differences")
235 6 : {
236 2 : BooleanVector_t activeDims(2);
237 2 : activeDims << true, false;
238 2 : FiniteDifferences<data_t> fdOp1(dd, activeDims,
239 2 : FiniteDifferences<data_t>::DiffType::BACKWARD);
240 :
241 2 : activeDims << false, true;
242 2 : FiniteDifferences<data_t> fdOp2(dd, activeDims,
243 2 : FiniteDifferences<data_t>::DiffType::BACKWARD);
244 :
245 2 : THEN("the results are correct")
246 2 : {
247 2 : 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 2 : DataContainer<data_t> dcRes1(fdOp1.getRangeDescriptor(), res1);
250 :
251 2 : REQUIRE_EQ(dcRes1, fdOp1.apply(dc));
252 :
253 2 : 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 2 : }
259 2 : }
260 :
261 6 : WHEN("using central differences")
262 6 : {
263 2 : BooleanVector_t activeDims(2);
264 2 : activeDims << true, false;
265 2 : FiniteDifferences<data_t> fdOp1(dd, activeDims,
266 2 : FiniteDifferences<data_t>::DiffType::CENTRAL);
267 :
268 2 : activeDims << false, true;
269 2 : FiniteDifferences<data_t> fdOp2(dd, activeDims,
270 2 : FiniteDifferences<data_t>::DiffType::CENTRAL);
271 :
272 2 : THEN("the results are correct")
273 2 : {
274 2 : Vector_t<data_t> res1(fdOp1.getRangeDescriptor().getNumberOfCoefficients());
275 2 : 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 2 : -3.5, -6.0;
277 2 : DataContainer<data_t> dcRes1(fdOp1.getRangeDescriptor(), res1);
278 :
279 2 : REQUIRE_EQ(dcRes1, fdOp1.apply(dc));
280 :
281 2 : Vector_t<data_t> res2(fdOp2.getRangeDescriptor().getNumberOfCoefficients());
282 2 : 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 2 : -3.0, -7.5;
284 2 : DataContainer<data_t> dcRes2(fdOp2.getRangeDescriptor(), res2);
285 :
286 2 : REQUIRE_EQ(dcRes2, fdOp2.apply(dc));
287 2 : }
288 2 : }
289 6 : }
290 6 : }
291 : TEST_SUITE_END();
|