1 // Copyright (c) 2018-2019 Cem Bassoy
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // The author gratefully acknowledge the support of
8 // Fraunhofer and Google in producing this work
9 // which started as a Google Summer of Code project.
10 //
11
12
13 #include <boost/numeric/ublas/tensor.hpp>
14
15 #include <boost/test/unit_test.hpp>
16
17 BOOST_AUTO_TEST_SUITE ( test_multi_index_utility )
18
19
BOOST_AUTO_TEST_CASE(test_multi_index_has_index)20 BOOST_AUTO_TEST_CASE ( test_multi_index_has_index )
21 {
22 using namespace boost::numeric::ublas;
23 using namespace boost::numeric::ublas::index;
24
25 {
26 constexpr auto tuple = std::tuple<>{};
27 constexpr auto has_a = has_index<decltype(_a),decltype(tuple)>::value;
28 constexpr auto has_b = has_index<decltype(_b),decltype(tuple)>::value;
29 BOOST_CHECK( !has_a );
30 BOOST_CHECK( !has_b );
31 }
32
33
34 {
35 constexpr auto tuple = std::make_tuple(_a);
36 constexpr auto has_a = has_index<decltype(_a),decltype(tuple)>::value;
37 constexpr auto has_b = has_index<decltype(_b),decltype(tuple)>::value;
38 BOOST_CHECK( has_a );
39 BOOST_CHECK( !has_b );
40 }
41
42 {
43 constexpr auto tuple = std::make_tuple(_a,_b,_,_c,_d);
44 constexpr auto has_a = has_index<decltype(_a),decltype(tuple)>::value;
45 constexpr auto has_b = has_index<decltype(_b),decltype(tuple)>::value;
46 constexpr auto has_c = has_index<decltype(_c),decltype(tuple)>::value;
47 constexpr auto has_d = has_index<decltype(_d),decltype(tuple)>::value;
48 constexpr auto has_e = has_index<decltype(_e),decltype(tuple)>::value;
49 constexpr auto has__ = has_index<decltype( _),decltype(tuple)>::value;
50 BOOST_CHECK( has_a );
51 BOOST_CHECK( has_b );
52 BOOST_CHECK( has_c );
53 BOOST_CHECK( has_d );
54 BOOST_CHECK( !has_e );
55 BOOST_CHECK( has__ );
56 }
57 }
58
59
60
BOOST_AUTO_TEST_CASE(test_multi_index_valid)61 BOOST_AUTO_TEST_CASE ( test_multi_index_valid )
62 {
63 using namespace boost::numeric::ublas;
64 using namespace boost::numeric::ublas::index;
65
66 {
67 constexpr auto tuple = std::tuple<>{};
68 constexpr auto valid = valid_multi_index<decltype(tuple)>::value;
69 BOOST_CHECK( valid );
70 }
71
72
73 {
74 constexpr auto tuple = std::make_tuple(_a);
75 constexpr auto valid = valid_multi_index<decltype(tuple)>::value;
76 BOOST_CHECK( valid );
77 }
78
79 {
80 constexpr auto tuple = std::make_tuple(_a,_,_b);
81 constexpr auto valid = valid_multi_index<decltype(tuple)>::value;
82 BOOST_CHECK( valid );
83 }
84
85 {
86 constexpr auto tuple = std::make_tuple(_a,_,_b,_b);
87 constexpr auto valid = valid_multi_index<decltype(tuple)>::value;
88 BOOST_CHECK( !valid );
89 }
90
91 {
92 constexpr auto tuple = std::make_tuple(_c,_a,_,_b,_b);
93 constexpr auto valid = valid_multi_index<decltype(tuple)>::value;
94 BOOST_CHECK( !valid );
95 }
96
97 {
98 constexpr auto tuple = std::make_tuple(_c,_a,_,_b);
99 constexpr auto valid = valid_multi_index<decltype(tuple)>::value;
100 BOOST_CHECK( valid );
101 }
102
103 {
104 constexpr auto tuple = std::make_tuple(_,_c,_a,_,_b);
105 constexpr auto valid = valid_multi_index<decltype(tuple)>::value;
106 BOOST_CHECK( valid );
107 }
108
109 {
110 constexpr auto tuple = std::make_tuple(_,_c,_a,_,_b,_);
111 constexpr auto valid = valid_multi_index<decltype(tuple)>::value;
112 BOOST_CHECK( valid );
113 }
114 }
115
116
117
118
119
BOOST_AUTO_TEST_CASE(test_multi_index_number_equal_indices)120 BOOST_AUTO_TEST_CASE ( test_multi_index_number_equal_indices )
121 {
122 using namespace boost::numeric::ublas;
123 using namespace boost::numeric::ublas::index;
124
125 {
126 constexpr auto lhs = std::tuple<>{};
127 constexpr auto rhs = std::tuple<>{};
128 constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value;
129 BOOST_CHECK_EQUAL( num, 0 );
130 }
131
132 {
133 constexpr auto lhs = std::make_tuple(_a);
134 constexpr auto rhs = std::tuple<>{};
135 constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value;
136 BOOST_CHECK_EQUAL( num, 0 );
137 }
138
139 {
140 constexpr auto lhs = std::tuple<>{};
141 constexpr auto rhs = std::make_tuple(_a);
142 constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value;
143 BOOST_CHECK_EQUAL( num, 0 );
144 }
145
146 {
147 constexpr auto lhs = std::make_tuple(_b);
148 constexpr auto rhs = std::make_tuple(_a);
149 constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value;
150 BOOST_CHECK_EQUAL( num, 0 );
151 }
152
153
154
155 {
156 constexpr auto lhs = std::make_tuple(_a);
157 constexpr auto rhs = std::make_tuple(_a);
158 constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value;
159 BOOST_CHECK_EQUAL( num, 1 );
160 }
161
162 {
163 constexpr auto lhs = std::make_tuple(_a,_b);
164 constexpr auto rhs = std::make_tuple(_a);
165 constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value;
166 BOOST_CHECK_EQUAL( num, 1 );
167 }
168
169 {
170 constexpr auto lhs = std::make_tuple(_b);
171 constexpr auto rhs = std::make_tuple(_a,_b);
172 constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value;
173 BOOST_CHECK_EQUAL( num, 1 );
174 }
175
176 {
177 constexpr auto lhs = std::make_tuple(_a);
178 constexpr auto rhs = std::make_tuple(_a);
179 constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value;
180 BOOST_CHECK_EQUAL( num, 1 );
181 }
182
183
184
185 {
186 constexpr auto lhs = std::make_tuple(_a,_b);
187 constexpr auto rhs = std::make_tuple(_a,_b);
188 constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value;
189 BOOST_CHECK_EQUAL( num, 2 );
190 }
191
192 {
193 constexpr auto lhs = std::make_tuple(_b,_a);
194 constexpr auto rhs = std::make_tuple(_a,_b);
195 constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value;
196 BOOST_CHECK_EQUAL( num, 2 );
197 }
198
199 {
200 constexpr auto lhs = std::make_tuple(_b,_a,_c);
201 constexpr auto rhs = std::make_tuple(_a,_b);
202 constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value;
203 BOOST_CHECK_EQUAL( num, 2 );
204 }
205
206 {
207 constexpr auto lhs = std::make_tuple(_b,_a,_c);
208 constexpr auto rhs = std::make_tuple(_a,_b,_d);
209 constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value;
210 BOOST_CHECK_EQUAL( num, 2 );
211 }
212
213 {
214 constexpr auto lhs = std::make_tuple(_b,_a,_d);
215 constexpr auto rhs = std::make_tuple(_a,_b,_d);
216 constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value;
217 BOOST_CHECK_EQUAL( num, 3 );
218 }
219
220 {
221 constexpr auto lhs = std::make_tuple(_b,_a,_d);
222 constexpr auto rhs = std::make_tuple(_a,_b,_d,_);
223 constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value;
224 BOOST_CHECK_EQUAL( num, 3 );
225 }
226
227 {
228 constexpr auto lhs = std::make_tuple(_b,_a,_d,_);
229 constexpr auto rhs = std::make_tuple(_a,_b,_d,_);
230 constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value;
231 BOOST_CHECK_EQUAL( num, 3 );
232 }
233
234 {
235 constexpr auto lhs = std::make_tuple(_b,_a,_d,_);
236 constexpr auto rhs = std::make_tuple( _,_b,_d,_);
237 constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value;
238 BOOST_CHECK_EQUAL( num, 2 );
239 }
240
241 {
242 constexpr auto lhs = std::make_tuple(_,_a,_d,_);
243 constexpr auto rhs = std::make_tuple(_,_b,_d,_);
244 constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value;
245 BOOST_CHECK_EQUAL( num, 1 );
246 }
247
248 {
249 constexpr auto lhs = std::make_tuple(_,_a,_d,_);
250 constexpr auto rhs = std::make_tuple(_,_b,_d,_,_);
251 constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value;
252 BOOST_CHECK_EQUAL( num, 1 );
253 }
254 }
255
256
257
258
259
260
261
BOOST_AUTO_TEST_CASE(test_multi_index_index_position)262 BOOST_AUTO_TEST_CASE ( test_multi_index_index_position )
263 {
264 using namespace boost::numeric::ublas;
265 using namespace boost::numeric::ublas::index;
266
267 {
268 constexpr auto tuple = std::tuple<>{};
269 constexpr auto ind = index_position<decltype(_),decltype(tuple)>::value;
270 BOOST_CHECK_EQUAL(ind,0);
271 }
272
273 {
274 constexpr auto tuple = std::make_tuple(_);
275 constexpr auto ind = index_position<decltype(_),decltype(tuple)>::value;
276 BOOST_CHECK_EQUAL(ind,0);
277 }
278
279 {
280 constexpr auto tuple = std::make_tuple(_);
281 constexpr auto ind = index_position<decltype(_a),decltype(tuple)>::value;
282 BOOST_CHECK_EQUAL(ind,1);
283 }
284
285 {
286 constexpr auto tuple = std::make_tuple(_,_a);
287 constexpr auto ind = index_position<decltype(_),decltype(tuple)>::value;
288 BOOST_CHECK_EQUAL(ind,0);
289 }
290
291 {
292 constexpr auto tuple = std::make_tuple(_,_a);
293 constexpr auto ind = index_position<decltype(_a),decltype(tuple)>::value;
294 BOOST_CHECK_EQUAL(ind,1);
295 }
296
297 {
298 constexpr auto tuple = std::make_tuple(_,_a);
299 constexpr auto ind = index_position<decltype(_b),decltype(tuple)>::value;
300 BOOST_CHECK_EQUAL(ind,2);
301 }
302
303
304
305
306 {
307 constexpr auto tuple = std::make_tuple(_c,_,_a);
308 constexpr auto ind = index_position<decltype(_c),decltype(tuple)>::value;
309 BOOST_CHECK_EQUAL(ind,0);
310 }
311
312 {
313 constexpr auto tuple = std::make_tuple(_c,_,_a,_);
314 constexpr auto ind = index_position<decltype(_),decltype(tuple)>::value;
315 BOOST_CHECK_EQUAL(ind,1);
316 }
317
318 {
319 constexpr auto tuple = std::make_tuple(_c,_,_a);
320 constexpr auto ind = index_position<decltype(_a),decltype(tuple)>::value;
321 BOOST_CHECK_EQUAL(ind,2);
322 }
323
324 {
325 constexpr auto tuple = std::make_tuple(_c,_,_a);
326 constexpr auto ind = index_position<decltype(_d),decltype(tuple)>::value;
327 BOOST_CHECK_EQUAL(ind,3);
328 }
329
330 }
331
332
333
334
335
336
337
338
BOOST_AUTO_TEST_CASE(test_multi_index_index_position_pairs)339 BOOST_AUTO_TEST_CASE ( test_multi_index_index_position_pairs )
340 {
341 using namespace boost::numeric::ublas;
342 using namespace boost::numeric::ublas::index;
343
344 {
345 constexpr auto lhs = std::tuple<>{};
346 constexpr auto rhs = std::tuple<>{};
347 auto array = index_position_pairs(lhs, rhs);
348 BOOST_CHECK_EQUAL(array.size(), 0ul );
349 }
350
351 {
352 constexpr auto lhs = std::make_tuple(_a);
353 constexpr auto rhs = std::tuple<>{};
354 auto array = index_position_pairs(lhs, rhs);
355 BOOST_CHECK_EQUAL(array.size(), 0ul );
356 }
357
358 {
359 constexpr auto lhs = std::tuple<>{};
360 constexpr auto rhs = std::make_tuple(_a);
361 auto array = index_position_pairs(lhs, rhs);
362 BOOST_CHECK_EQUAL(array.size(), 0ul );
363 }
364
365 {
366 constexpr auto lhs = std::make_tuple(_b);
367 constexpr auto rhs = std::make_tuple(_a);
368 auto array = index_position_pairs(lhs, rhs);
369 BOOST_CHECK_EQUAL(array.size(), 0ul );
370 }
371
372
373
374 {
375 constexpr auto lhs = std::make_tuple(_a);
376 constexpr auto rhs = std::make_tuple(_a);
377 auto array = index_position_pairs(lhs, rhs);
378 BOOST_ASSERT(array.size() == 1ul );
379 BOOST_CHECK_EQUAL(array[0].first , 0 );
380 BOOST_CHECK_EQUAL(array[0].second, 0 );
381 }
382
383 {
384 constexpr auto lhs = std::make_tuple(_a,_b);
385 constexpr auto rhs = std::make_tuple(_a);
386 auto array = index_position_pairs(lhs, rhs);
387 BOOST_ASSERT(array.size() == 1ul );
388 BOOST_CHECK_EQUAL(array[0].first , 0 );
389 BOOST_CHECK_EQUAL(array[0].second, 0 );
390 }
391
392 {
393 constexpr auto lhs = std::make_tuple(_b);
394 constexpr auto rhs = std::make_tuple(_a,_b);
395 auto array = index_position_pairs(lhs, rhs);
396 BOOST_ASSERT(array.size() == 1ul );
397 BOOST_CHECK_EQUAL(array[0].first , 0 );
398 BOOST_CHECK_EQUAL(array[0].second, 1 );
399 }
400
401 {
402 constexpr auto lhs = std::make_tuple(_a);
403 constexpr auto rhs = std::make_tuple(_a);
404 auto array = index_position_pairs(lhs, rhs);
405 BOOST_ASSERT(array.size() == 1ul );
406 BOOST_CHECK_EQUAL(array[0].first , 0 );
407 BOOST_CHECK_EQUAL(array[0].second, 0 );
408 }
409
410
411
412 {
413 constexpr auto lhs = std::make_tuple(_a,_b);
414 constexpr auto rhs = std::make_tuple(_a,_b);
415 auto array = index_position_pairs(lhs, rhs);
416 BOOST_ASSERT(array.size() == 2ul );
417 BOOST_CHECK_EQUAL(array[0].first , 0 );
418 BOOST_CHECK_EQUAL(array[0].second, 0 );
419 BOOST_CHECK_EQUAL(array[1].first , 1 );
420 BOOST_CHECK_EQUAL(array[1].second, 1 );
421 }
422
423 {
424 constexpr auto lhs = std::make_tuple(_b,_a);
425 constexpr auto rhs = std::make_tuple(_a,_b);
426 auto array = index_position_pairs(lhs, rhs);
427 BOOST_ASSERT(array.size() == 2ul );
428 BOOST_CHECK_EQUAL(array[0].first , 0 );
429 BOOST_CHECK_EQUAL(array[0].second, 1 );
430 BOOST_CHECK_EQUAL(array[1].first , 1 );
431 BOOST_CHECK_EQUAL(array[1].second, 0 );
432 }
433
434 {
435 constexpr auto lhs = std::make_tuple(_b,_a,_c);
436 constexpr auto rhs = std::make_tuple(_a,_b);
437 auto array = index_position_pairs(lhs, rhs);
438 BOOST_ASSERT(array.size() == 2ul );
439 BOOST_CHECK_EQUAL(array[0].first , 0 );
440 BOOST_CHECK_EQUAL(array[0].second, 1 );
441 BOOST_CHECK_EQUAL(array[1].first , 1 );
442 BOOST_CHECK_EQUAL(array[1].second, 0 );
443 }
444
445 {
446 constexpr auto lhs = std::make_tuple(_b,_a,_c);
447 constexpr auto rhs = std::make_tuple(_a,_b,_d);
448 auto array = index_position_pairs(lhs, rhs);
449 BOOST_ASSERT(array.size() == 2ul );
450 BOOST_CHECK_EQUAL(array[0].first , 0 );
451 BOOST_CHECK_EQUAL(array[0].second, 1 );
452 BOOST_CHECK_EQUAL(array[1].first , 1 );
453 BOOST_CHECK_EQUAL(array[1].second, 0 );
454 }
455
456 {
457 constexpr auto lhs = std::make_tuple(_b,_a,_d);
458 constexpr auto rhs = std::make_tuple(_a,_b,_d);
459 auto array = index_position_pairs(lhs, rhs);
460 BOOST_ASSERT(array.size() == 3ul );
461 BOOST_CHECK_EQUAL(array[0].first , 0 );
462 BOOST_CHECK_EQUAL(array[0].second, 1 );
463 BOOST_CHECK_EQUAL(array[1].first , 1 );
464 BOOST_CHECK_EQUAL(array[1].second, 0 );
465 BOOST_CHECK_EQUAL(array[2].first , 2 );
466 BOOST_CHECK_EQUAL(array[2].second, 2 );
467 }
468
469 {
470 constexpr auto lhs = std::make_tuple(_b,_a,_d);
471 constexpr auto rhs = std::make_tuple(_a,_b,_d,_);
472 auto array = index_position_pairs(lhs, rhs);
473 BOOST_ASSERT(array.size() == 3ul );
474 BOOST_CHECK_EQUAL(array[0].first , 0 );
475 BOOST_CHECK_EQUAL(array[0].second, 1 );
476 BOOST_CHECK_EQUAL(array[1].first , 1 );
477 BOOST_CHECK_EQUAL(array[1].second, 0 );
478 BOOST_CHECK_EQUAL(array[2].first , 2 );
479 BOOST_CHECK_EQUAL(array[2].second, 2 );
480 }
481
482 {
483 constexpr auto lhs = std::make_tuple(_b,_a,_d,_);
484 constexpr auto rhs = std::make_tuple(_a,_b,_d,_);
485 auto array = index_position_pairs(lhs, rhs);
486 BOOST_ASSERT(array.size() == 3ul );
487 BOOST_CHECK_EQUAL(array[0].first , 0 );
488 BOOST_CHECK_EQUAL(array[0].second, 1 );
489 BOOST_CHECK_EQUAL(array[1].first , 1 );
490 BOOST_CHECK_EQUAL(array[1].second, 0 );
491 BOOST_CHECK_EQUAL(array[2].first , 2 );
492 BOOST_CHECK_EQUAL(array[2].second, 2 );
493 }
494
495 {
496 constexpr auto lhs = std::make_tuple(_b,_a,_d,_);
497 constexpr auto rhs = std::make_tuple( _,_b,_d,_);
498 auto array = index_position_pairs(lhs, rhs);
499 BOOST_ASSERT(array.size() == 2ul );
500 BOOST_CHECK_EQUAL(array[0].first , 0 );
501 BOOST_CHECK_EQUAL(array[0].second, 1 );
502 BOOST_CHECK_EQUAL(array[1].first , 2 );
503 BOOST_CHECK_EQUAL(array[1].second, 2 );
504 }
505
506 {
507 constexpr auto lhs = std::make_tuple(_,_a,_d,_);
508 constexpr auto rhs = std::make_tuple(_,_b,_d,_);
509 auto array = index_position_pairs(lhs, rhs);
510 BOOST_ASSERT(array.size() == 1ul );
511 BOOST_CHECK_EQUAL(array[0].first , 2 );
512 BOOST_CHECK_EQUAL(array[0].second, 2 );
513 }
514
515 {
516 constexpr auto lhs = std::make_tuple(_,_a,_d,_);
517 constexpr auto rhs = std::make_tuple(_,_b,_d,_,_);
518 auto array = index_position_pairs(lhs, rhs);
519 BOOST_ASSERT(array.size() == 1ul );
520 BOOST_CHECK_EQUAL(array[0].first , 2 );
521 BOOST_CHECK_EQUAL(array[0].second, 2 );
522 }
523 }
524
525
526
BOOST_AUTO_TEST_CASE(test_multi_index_array_to_vector)527 BOOST_AUTO_TEST_CASE ( test_multi_index_array_to_vector )
528 {
529 using namespace boost::numeric::ublas;
530 using namespace boost::numeric::ublas::index;
531
532 auto check = [](auto const& lhs, auto const& rhs)
533 {
534 auto array = index_position_pairs(lhs, rhs);
535
536 auto vector_pair = array_to_vector( array );
537
538 BOOST_CHECK_EQUAL(vector_pair.first .size(), array.size() );
539 BOOST_CHECK_EQUAL(vector_pair.second.size(), array.size() );
540
541 for(auto i = 0ul; i < array.size(); ++i)
542 {
543 BOOST_CHECK_EQUAL(vector_pair.first [i], array[i].first +1 );
544 BOOST_CHECK_EQUAL(vector_pair.second[i], array[i].second+1 );
545 }
546
547 };
548
549 check(std::tuple<>{} , std::tuple<>{});
550 check(std::make_tuple(_a) , std::tuple<>{});
551 check(std::tuple<>{} , std::make_tuple(_a));
552 check(std::make_tuple(_a) , std::make_tuple(_b));
553 check(std::make_tuple(_a) , std::make_tuple(_a));
554 check(std::make_tuple(_a,_b), std::make_tuple(_a));
555 check(std::make_tuple(_a) , std::make_tuple(_a,_b));
556 check(std::make_tuple(_a,_b), std::make_tuple(_a,_b));
557 check(std::make_tuple(_b,_a), std::make_tuple(_a,_b));
558 check(std::make_tuple(_b,_a,_c), std::make_tuple(_a,_b,_d));
559 }
560
561
562
563 BOOST_AUTO_TEST_SUITE_END()
564
565