indexed_test.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // Copyright 2018 Hans Dembinski
  2. //
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt
  5. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #include <algorithm>
  7. #include <boost/core/lightweight_test.hpp>
  8. #include <boost/histogram/axis/integer.hpp>
  9. #include <boost/histogram/axis/ostream.hpp>
  10. #include <boost/histogram/axis/variable.hpp>
  11. #include <boost/histogram/histogram.hpp>
  12. #include <boost/histogram/indexed.hpp>
  13. #include <boost/histogram/literals.hpp>
  14. #include <boost/histogram/ostream.hpp>
  15. #include <boost/mp11/algorithm.hpp>
  16. #include <boost/mp11/list.hpp>
  17. #include <iterator>
  18. #include <ostream>
  19. #include <type_traits>
  20. #include <vector>
  21. #include "throw_exception.hpp"
  22. #include "utility_histogram.hpp"
  23. using namespace boost::histogram;
  24. using namespace boost::histogram::literals;
  25. using namespace boost::mp11;
  26. template <class IsDynamic, class Coverage>
  27. void run_1d_tests(mp_list<IsDynamic, Coverage>) {
  28. auto h = make(IsDynamic(), axis::integer<>(0, 3));
  29. h(-1, weight(1));
  30. h(0, weight(2));
  31. h(1, weight(3));
  32. h(2, weight(4));
  33. h(3, weight(5));
  34. auto ind = indexed(h, Coverage());
  35. auto it = ind.begin();
  36. BOOST_TEST_EQ(it->indices().size(), 1);
  37. BOOST_TEST_EQ(it->indices()[0], Coverage() == coverage::all ? -1 : 0);
  38. if (Coverage() == coverage::all) {
  39. BOOST_TEST_EQ(it->index(0), -1);
  40. BOOST_TEST_EQ(**it, 1);
  41. BOOST_TEST_EQ(it->bin(0), h.axis().bin(-1));
  42. ++it;
  43. }
  44. BOOST_TEST_EQ(it->index(0), 0);
  45. BOOST_TEST_EQ(**it, 2);
  46. BOOST_TEST_EQ(it->bin(0), h.axis().bin(0));
  47. ++it;
  48. BOOST_TEST_EQ(it->index(0), 1);
  49. BOOST_TEST_EQ(**it, 3);
  50. BOOST_TEST_EQ(it->bin(0), h.axis().bin(1));
  51. ++it;
  52. // check post-increment
  53. auto prev = it++;
  54. BOOST_TEST_EQ(prev->index(0), 2);
  55. BOOST_TEST_EQ(**prev, 4);
  56. BOOST_TEST_EQ(prev->bin(0), h.axis().bin(2));
  57. if (Coverage() == coverage::all) {
  58. BOOST_TEST_EQ(it->index(0), 3);
  59. BOOST_TEST_EQ(**it, 5);
  60. BOOST_TEST_EQ(it->bin(0), h.axis().bin(3));
  61. ++it;
  62. }
  63. BOOST_TEST(it == ind.end());
  64. for (auto&& x : indexed(h, Coverage())) *x = 0;
  65. for (auto&& x : indexed(static_cast<const decltype(h)&>(h), Coverage()))
  66. BOOST_TEST_EQ(*x, 0);
  67. }
  68. template <class IsDynamic, class Coverage>
  69. void run_3d_tests(mp_list<IsDynamic, Coverage>) {
  70. auto h = make_s(IsDynamic(), std::vector<int>(), axis::integer<>(0, 2),
  71. axis::integer<int, axis::null_type, axis::option::none_t>(0, 3),
  72. axis::integer<int, axis::null_type, axis::option::overflow_t>(0, 4));
  73. for (int i = -1; i < 3; ++i)
  74. for (int j = -1; j < 4; ++j)
  75. for (int k = -1; k < 5; ++k) h(i, j, k, weight(i * 100 + j * 10 + k));
  76. auto ind = indexed(h, Coverage());
  77. auto it = ind.begin();
  78. BOOST_TEST_EQ(it->indices().size(), 3);
  79. const int d = Coverage() == coverage::all;
  80. // imitate iteration order of indexed loop
  81. for (int k = 0; k < 4 + d; ++k)
  82. for (int j = 0; j < 3; ++j)
  83. for (int i = -d; i < 2 + d; ++i) {
  84. BOOST_TEST_EQ(it->index(0), i);
  85. BOOST_TEST_EQ(it->index(1), j);
  86. BOOST_TEST_EQ(it->index(2), k);
  87. BOOST_TEST_EQ(it->bin(0_c), h.axis(0_c).bin(i));
  88. BOOST_TEST_EQ(it->bin(1_c), h.axis(1_c).bin(j));
  89. BOOST_TEST_EQ(it->bin(2_c), h.axis(2_c).bin(k));
  90. BOOST_TEST_EQ(**it, i * 100 + j * 10 + k);
  91. ++it;
  92. }
  93. BOOST_TEST(it == ind.end());
  94. }
  95. template <class IsDynamic, class Coverage>
  96. void run_density_tests(mp_list<IsDynamic, Coverage>) {
  97. auto ax = axis::variable<>({0.0, 0.1, 0.3, 0.6});
  98. auto ay = axis::integer<int>(0, 2);
  99. auto az = ax;
  100. auto h = make_s(IsDynamic(), std::vector<int>(), ax, ay, az);
  101. // fill uniformly
  102. for (auto&& x : h) x = 1;
  103. for (auto&& x : indexed(h, Coverage())) {
  104. BOOST_TEST_EQ(x.density(), *x / (x.bin(0).width() * x.bin(2).width()));
  105. }
  106. }
  107. template <class IsDynamic, class Coverage>
  108. void run_stdlib_tests(mp_list<IsDynamic, Coverage>) {
  109. auto ax = axis::regular<>(3, 0, 1);
  110. auto ay = axis::integer<>(0, 2);
  111. auto h = make_s(IsDynamic(), std::array<int, 20>(), ax, ay);
  112. struct generator {
  113. int i = 0;
  114. int operator()() { return ++i; }
  115. };
  116. auto ind = indexed(h, Coverage());
  117. std::generate(ind.begin(), ind.end(), generator{});
  118. {
  119. int i = 0;
  120. for (auto&& x : ind) BOOST_TEST_EQ(*x, ++i);
  121. }
  122. {
  123. auto it = std::min_element(ind.begin(), ind.end());
  124. BOOST_TEST(it == ind.begin());
  125. BOOST_TEST(it != ind.end());
  126. }
  127. {
  128. auto it = std::max_element(ind.begin(), ind.end());
  129. // get last before end()
  130. auto it2 = ind.begin();
  131. auto it3 = it2;
  132. while (it2 != ind.end()) it3 = it2++;
  133. BOOST_TEST(it == it3);
  134. BOOST_TEST(it != ind.begin());
  135. }
  136. }
  137. int main() {
  138. mp_for_each<mp_product<mp_list, mp_list<mp_false, mp_true>,
  139. mp_list<std::integral_constant<coverage, coverage::inner>,
  140. std::integral_constant<coverage, coverage::all>>>>(
  141. [](auto&& x) {
  142. run_1d_tests(x);
  143. run_3d_tests(x);
  144. run_density_tests(x);
  145. run_stdlib_tests(x);
  146. });
  147. return boost::report_errors();
  148. }