All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TensorIndices_test.cc
Go to the documentation of this file.
1 /**
2  * @file TensorIndices_test.cc
3  * @brief Test for TensorIndices class
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date June 28, 2016
6  * @see TensorIndices.h
7  *
8  * This test instantiates some TensorIndices and verifies the reaction to some
9  * hard-coded settings and queries.
10  *
11  * The test is run with no arguments.
12  *
13  * Tests are run:
14  *
15  * * `VectorTest`: one-dimension tensor test
16  * * `MatrixTest`: two-dimension tensor test
17  * * `TensorRank3Test`: test rank 3 tensor
18  *
19  * See the documentation of the three functions for more information.
20  *
21  */
22 
23 // LArSoft libraries
25 
26 // Boost libraries
27 #define BOOST_TEST_MODULE ( PointIsolationAlg_test )
28 #include "boost/test/unit_test.hpp"
29 
30 // C/C++ standard libraries
31 #include <stdexcept> // std::out_of_range
32 
33 
34 //------------------------------------------------------------------------------
35 //--- Test code
36 //---
37 /**
38  * @brief Test for a rank 1 tensor (vector)
39  */
40 void VectorTest() {
41 
42  // indices for a vector of size 4
44 
45  //
46  // reflection
47  //
48  BOOST_TEST(indices.dim<0>() == 4U);
49 
50  BOOST_TEST(indices.size<0>() == 4U);
51 
52  BOOST_TEST(indices.size() == 4U);
53 
54  //
55  // indexing
56  //
57  // BUG the double brace syntax is required to work around clang bug 21629
58  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
59  std::array<char, 1> ii {{ 1 }}; // char is for test; it should be size_t
60 /* TODO
61  BOOST_TEST(indices[0] == 0U);
62  BOOST_TEST(indices[1] == 1U);
63  BOOST_TEST(indices[2] == 2U);
64  BOOST_TEST(indices[3] == 3U);
65  BOOST_TEST(indices[4] == 4U); // no bound check
66 */
67  BOOST_TEST(indices(0) == 0U);
68  BOOST_TEST(indices(1) == 1U);
69  BOOST_TEST(indices(ii.begin()) == 1U);
70  BOOST_TEST(indices(2) == 2U);
71  BOOST_TEST(indices(3) == 3U);
72  BOOST_CHECK_NO_THROW(indices(4)); // no bound check
73 
74  BOOST_TEST(indices.at(0) == 0U);
75  BOOST_TEST(indices.at(1) == 1U);
76  BOOST_TEST(indices.at(ii.begin()) == 1U);
77  BOOST_TEST(indices.at(2) == 2U);
78  BOOST_TEST(indices.at(3) == 3U);
79  BOOST_CHECK_THROW(indices.at(4), std::out_of_range);
80 
81  BOOST_TEST(indices.has(0));
82  BOOST_TEST(indices.has(1));
83  BOOST_TEST(indices.has(ii.begin()));
84  BOOST_TEST(indices.has(2));
85  BOOST_TEST(indices.has(3));
86  BOOST_TEST(!indices.has(4));
87 
88  BOOST_TEST( indices.hasIndex<0>(0));
89  BOOST_TEST( indices.hasIndex<0>(1));
90  BOOST_TEST( indices.hasIndex<0>(2));
91  BOOST_TEST( indices.hasIndex<0>(3));
92  BOOST_TEST(!indices.hasIndex<0>(4));
93  BOOST_TEST(!indices.hasIndex<0>(5));
94 
95  BOOST_TEST(indices.hasLinIndex(0U));
96  BOOST_TEST(indices.hasLinIndex(indices.size() - 1));
97  BOOST_TEST(!indices.hasLinIndex(indices.size()));
98 
99  BOOST_TEST(indices.size() == 4U);
100 
101  // check that the function also works
102  // BUG the double brace syntax is required to work around clang bug 21629
103  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
104  std::array<int, 1> ia {{ 4 }};
105  util::TensorIndices<1> indicesAgain(ia.begin());
108 
109  // check the comparison operators
110  BOOST_TEST((indicesAgain == indices));
111  BOOST_TEST(!(indicesAgain != indices));
112  BOOST_TEST((indicesOther != indices));
113  BOOST_TEST(!(indicesOther == indices));
114  BOOST_TEST((indicesRank != indices));
115  BOOST_TEST(!(indicesRank == indices));
116 
117 
118 } // VectorTest()
119 
120 
121 /**
122  * @brief Test for a rank 2 tensor (matrix)
123  */
124 void MatrixTest() {
125 
126  // indices for a matrix 4 x 3
127  util::TensorIndices<2> const indices{4, 3};
128 
129  //
130  // reflection
131  //
132  BOOST_TEST(indices.dim<0>() == 4U);
133  BOOST_TEST(indices.dim<1>() == 3U);
134 
135  BOOST_TEST(indices.size<0>() == 4U * 3U);
136  BOOST_TEST(indices.size<1>() == 3U);
137 
138  BOOST_TEST(indices.size() == 4U * 3U);
139 
140  BOOST_TEST(indices.minorTensor().rank() == 1U);
141  BOOST_TEST(indices.minorTensor().size() == 3U);
142 
143  //
144  // indexing
145  //
146  // BUG the double brace syntax is required to work around clang bug 21629
147  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
148  std::array<char, 2> ii {{ 1, 2 }}; // char is for test; it should be size_t
149 /* TODO
150  BOOST_TEST(indices[0] == 0U);
151  BOOST_TEST(indices[1] == 1U);
152  BOOST_TEST(indices[2] == 2U);
153  BOOST_TEST(indices[3] == 3U);
154  BOOST_TEST(indices[4] == 4U); // no bound check
155 */
156  BOOST_TEST(indices(0, 0) == 0U);
157  BOOST_TEST(indices(1, 2) == 5U);
158  BOOST_TEST(indices(ii.begin()) == 5U);
159  BOOST_CHECK_NO_THROW(indices(1, 3));
160  BOOST_CHECK_NO_THROW(indices(4, 2));
161  BOOST_CHECK_NO_THROW(indices(7, 6));
162 
163  BOOST_TEST(indices.at(0, 0) == 0U);
164  BOOST_TEST(indices.at(1, 2) == 5U);
165  BOOST_TEST(indices.at(ii.begin()) == 5U);
166  BOOST_CHECK_THROW(indices.at(1, 3), std::out_of_range);
167  BOOST_CHECK_THROW(indices.at(4, 2), std::out_of_range);
168  BOOST_CHECK_THROW(indices.at(7, 6), std::out_of_range);
169 
170  BOOST_TEST(indices.has(0, 0));
171  BOOST_TEST(indices.has(ii.begin()));
172  BOOST_TEST(indices.has(2, 2));
173  BOOST_TEST(!indices.has(1, 3));
174  BOOST_TEST(!indices.has(4, 2));
175  BOOST_TEST(!indices.has(7, 6));
176 
177  BOOST_TEST( indices.hasIndex<0>(0));
178  BOOST_TEST( indices.hasIndex<0>(3));
179  BOOST_TEST(!indices.hasIndex<0>(4));
180  BOOST_TEST( indices.hasIndex<1>(0));
181  BOOST_TEST( indices.hasIndex<1>(2));
182  BOOST_TEST(!indices.hasIndex<1>(3));
183 
184  BOOST_TEST(indices.hasLinIndex(0U));
185  BOOST_TEST(indices.hasLinIndex(indices.size() - 1));
186  BOOST_TEST(!indices.hasLinIndex(indices.size()));
187 
188  //
189  // comparisons
190  //
191  // check that the function and other constructors also works
192  // BUG the double brace syntax is required to work around clang bug 21629
193  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
194  std::array<int, 2> ia {{ 4, 3 }};
195  util::TensorIndices<2> indicesAgain(ia.begin());
196  util::TensorIndices<2> indicesOther = util::makeTensorIndices(4, 4);
197  util::TensorIndices<3> indicesRank = util::makeTensorIndices(5, 4, 3);
198 
199  // check the comparison operators
200  BOOST_TEST((indicesAgain == indices));
201  BOOST_TEST(!(indicesAgain != indices));
202  BOOST_TEST((indicesOther != indices));
203  BOOST_TEST(!(indicesOther == indices));
204  BOOST_TEST((indicesRank != indices));
205  BOOST_TEST(!(indicesRank == indices));
206 
207 } // MatrixTest()
208 
209 
210 /**
211  * @brief Test for a rank 3 tensor
212  */
214 
215  // indices for a matrix 2 x 3 x 4
216  util::TensorIndices<3> const indices{ 2, 3, 4 };
217 
218  //
219  // reflection
220  //
221  BOOST_TEST(indices.dim<0>() == 2U);
222  BOOST_TEST(indices.dim<1>() == 3U);
223  BOOST_TEST(indices.dim<2>() == 4U);
224 
225  BOOST_TEST(indices.size<0>() == 2U * 3U * 4U);
226  BOOST_TEST(indices.size<1>() == 3U * 4U);
227  BOOST_TEST(indices.size<2>() == 4U);
228 
229  BOOST_TEST(indices.size() == 2U * 3U * 4U);
230 
231  BOOST_TEST(indices.minorTensor().rank() == 2U);
232  BOOST_TEST(indices.minorTensor().size() == 3U * 4U);
233 
234  //
235  // indexing
236  //
237  // BUG the double brace syntax is required to work around clang bug 21629
238  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
239  std::array<char, 3> ii {{ 1, 2, 3 }}; // char is for test; it should be size_t
240 /* TODO
241  BOOST_TEST(indices[0] == 0U);
242  BOOST_TEST(indices[1] == 1U);
243  BOOST_TEST(indices[2] == 2U);
244  BOOST_TEST(indices[3] == 3U);
245  BOOST_TEST(indices[4] == 4U); // no bound check
246 */
247  BOOST_TEST(indices(0, 0, 0) == 0U);
248  BOOST_TEST(indices(1, 2, 3) == 23U);
249  BOOST_TEST(indices(ii.begin()) == 23U);
250  BOOST_CHECK_NO_THROW(indices(1, 3, 1));
251  BOOST_CHECK_NO_THROW(indices(4, 2, 1));
252  BOOST_CHECK_NO_THROW(indices(1, 2, 6));
253  BOOST_CHECK_NO_THROW(indices(7, 6, 6));
254 
255  BOOST_TEST(indices.at(0, 0, 0) == 0U);
256  BOOST_TEST(indices.at(1, 2, 3) == 23U);
257  BOOST_TEST(indices.at(ii.begin()) == 23U);
258  BOOST_CHECK_THROW(indices.at(1, 3, 1), std::out_of_range);
259  BOOST_CHECK_THROW(indices.at(4, 2, 1), std::out_of_range);
260  BOOST_CHECK_THROW(indices.at(1, 2, 6), std::out_of_range);
261  BOOST_CHECK_THROW(indices.at(7, 6, 6), std::out_of_range);
262 
263  BOOST_TEST(indices.has(0, 0, 0));
264  BOOST_TEST(indices.has(1, 2, 3));
265  BOOST_TEST(indices.has(ii.begin()));
266  BOOST_TEST(!indices.has(1, 3, 1));
267  BOOST_TEST(!indices.has(4, 2, 1));
268  BOOST_TEST(!indices.has(1, 2, 6));
269  BOOST_TEST(!indices.has(7, 6, 6));
270 
271  BOOST_TEST( indices.hasIndex<0>(0));
272  BOOST_TEST( indices.hasIndex<0>(1));
273  BOOST_TEST(!indices.hasIndex<0>(2));
274  BOOST_TEST( indices.hasIndex<1>(0));
275  BOOST_TEST( indices.hasIndex<1>(2));
276  BOOST_TEST(!indices.hasIndex<1>(3));
277  BOOST_TEST( indices.hasIndex<2>(0));
278  BOOST_TEST( indices.hasIndex<2>(3));
279  BOOST_TEST(!indices.hasIndex<2>(4));
280 
281  BOOST_TEST(indices.hasLinIndex(0U));
282  BOOST_TEST(indices.hasLinIndex(indices.size() - 1));
283  BOOST_TEST(!indices.hasLinIndex(indices.size()));
284 
285  //
286  // comparisons
287  //
288  // check that the function also works
289  // BUG the double brace syntax is required to work around clang bug 21629
290  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
291  std::array<int, 3> ia {{ 2, 3, 4 }};
292  util::TensorIndices<3> indicesAgain(ia.begin());
293  util::TensorIndices<3> indicesOther = util::makeTensorIndices(2, 3, 5);
295 
296  // check the comparison operators
297  BOOST_TEST((indicesAgain == indices));
298  BOOST_TEST(!(indicesAgain != indices));
299  BOOST_TEST((indicesOther != indices));
300  BOOST_TEST(!(indicesOther == indices));
301  BOOST_TEST((indicesRank != indices));
302  BOOST_TEST(!(indicesRank == indices));
303 
304 } // TensorRank3Test()
305 
306 
307 //------------------------------------------------------------------------------
308 //--- tests
309 //
310 BOOST_AUTO_TEST_CASE(VectorTestCase) {
311  VectorTest();
312 } // VectorTestCase
313 
314 BOOST_AUTO_TEST_CASE(MatrixTestCase) {
315  MatrixTest();
316 } // MatrixTestCase
317 
318 BOOST_AUTO_TEST_CASE(TensorRank3TestCase) {
319  TensorRank3Test();
320 } // TensorRank3TestCase
BOOST_AUTO_TEST_CASE(AllTests)
void TensorRank3Test()
Test for a rank 3 tensor.
TensorIndices class to flatten multi-dimension indices into linear.
Converts a tensor element specification into a linear index.
Definition: TensorIndices.h:46
constexpr std::array< std::size_t, geo::vect::dimension< Vector >)> indices()
Returns a sequence of indices valid for a vector of the specified type.
void MatrixTest(Array const &mat)
void VectorTest()
auto makeTensorIndices(DIMS...dims)
Instantiates a TensorIndices class with the specified dimensions.