histogram_growing_test.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. // Copyright 2015-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 <boost/core/lightweight_test.hpp>
  7. #include <boost/histogram/algorithm/sum.hpp>
  8. #include <boost/histogram/axis.hpp>
  9. #include <boost/histogram/axis/ostream.hpp>
  10. #include <boost/histogram/histogram.hpp>
  11. #include <boost/histogram/ostream.hpp>
  12. #include <string>
  13. #include <utility>
  14. #include "std_ostream.hpp"
  15. #include "throw_exception.hpp"
  16. #include "utility_histogram.hpp"
  17. using namespace boost::histogram;
  18. using def = use_default;
  19. using regular = axis::regular<double, def, def, axis::option::growth_t>;
  20. using integer = axis::integer<double, def,
  21. decltype(axis::option::underflow | axis::option::overflow |
  22. axis::option::growth)>;
  23. using category = axis::category<std::string, def, axis::option::growth_t>;
  24. class custom_2d_axis {
  25. public:
  26. auto index(std::tuple<double, double> xy) const {
  27. const auto x = std::get<0>(xy);
  28. const auto y = std::get<1>(xy);
  29. const auto r = std::sqrt(x * x + y * y);
  30. return (std::min)(static_cast<axis::index_type>(r), size());
  31. }
  32. auto update(std::tuple<double, double> xy) {
  33. const auto x = std::get<0>(xy);
  34. const auto y = std::get<1>(xy);
  35. const auto r = std::sqrt(x * x + y * y);
  36. const auto n = static_cast<int>(r);
  37. const auto old = size_;
  38. if (n >= size_) size_ = n + 1;
  39. return std::make_pair(n, old - size_);
  40. }
  41. axis::index_type size() const { return size_; }
  42. private:
  43. axis::index_type size_ = 0;
  44. };
  45. template <typename Tag>
  46. void run_tests() {
  47. {
  48. auto h = make(Tag(), regular(2, 0, 1));
  49. const auto& a = h.axis();
  50. BOOST_TEST_EQ(a.size(), 2);
  51. BOOST_TEST_EQ(h.size(), 2);
  52. // [0.0, 0.5, 1.0]
  53. h(0.1);
  54. h(0.9);
  55. BOOST_TEST_EQ(a.size(), 2);
  56. BOOST_TEST_EQ(h.size(), 2);
  57. h(-std::numeric_limits<double>::infinity());
  58. h(std::numeric_limits<double>::quiet_NaN());
  59. h(std::numeric_limits<double>::infinity());
  60. BOOST_TEST_EQ(a.size(), 2);
  61. BOOST_TEST_EQ(h.size(), 2);
  62. h(-0.3);
  63. // [-0.5, 0.0, 0.5, 1.0]
  64. BOOST_TEST_EQ(a.size(), 3);
  65. BOOST_TEST_EQ(h.size(), 3);
  66. BOOST_TEST_EQ(h[0], 1);
  67. BOOST_TEST_EQ(h[1], 1);
  68. BOOST_TEST_EQ(h[2], 1);
  69. h(1.9);
  70. // [-0.5, 0.0, 0.5, 1.0, 1.5, 2.0]
  71. BOOST_TEST_EQ(a.size(), 5);
  72. BOOST_TEST_EQ(h.size(), 5);
  73. BOOST_TEST_EQ(h[0], 1);
  74. BOOST_TEST_EQ(h[1], 1);
  75. BOOST_TEST_EQ(h[2], 1);
  76. BOOST_TEST_EQ(h[3], 0);
  77. BOOST_TEST_EQ(h[4], 1);
  78. }
  79. {
  80. auto h = make_s(Tag(), std::vector<int>(), integer());
  81. const auto& a = h.axis();
  82. h(-std::numeric_limits<double>::infinity());
  83. h(std::numeric_limits<double>::quiet_NaN());
  84. h(std::numeric_limits<double>::infinity());
  85. BOOST_TEST_EQ(a.size(), 0);
  86. BOOST_TEST_EQ(h.size(), 2);
  87. BOOST_TEST_EQ(h[-1], 1);
  88. BOOST_TEST_EQ(h[0], 2);
  89. h(0);
  90. BOOST_TEST_EQ(a.size(), 1);
  91. BOOST_TEST_EQ(h.size(), 3);
  92. BOOST_TEST_EQ(h[-1], 1);
  93. BOOST_TEST_EQ(h[0], 1);
  94. BOOST_TEST_EQ(h[1], 2);
  95. h(2);
  96. BOOST_TEST_EQ(a.size(), 3);
  97. BOOST_TEST_EQ(h.size(), 5);
  98. BOOST_TEST_EQ(h[-1], 1);
  99. BOOST_TEST_EQ(h[0], 1);
  100. BOOST_TEST_EQ(h[1], 0);
  101. BOOST_TEST_EQ(h[2], 1);
  102. BOOST_TEST_EQ(h[3], 2);
  103. h(-2);
  104. BOOST_TEST_EQ(a.size(), 5);
  105. BOOST_TEST_EQ(h.size(), 7);
  106. // BOOST_TEST_EQ(h[-1], 1)
  107. BOOST_TEST_EQ(h[0], 1);
  108. BOOST_TEST_EQ(h[1], 0);
  109. BOOST_TEST_EQ(h[2], 1);
  110. BOOST_TEST_EQ(h[3], 0);
  111. BOOST_TEST_EQ(h[4], 1);
  112. BOOST_TEST_EQ(h[5], 2);
  113. }
  114. {
  115. auto h = make_s(Tag(), std::vector<int>(), integer(), category());
  116. const auto& a = h.axis(0);
  117. const auto& b = h.axis(1);
  118. BOOST_TEST_EQ(a.size(), 0);
  119. BOOST_TEST_EQ(b.size(), 0);
  120. BOOST_TEST_EQ(h.size(), 0);
  121. h(0, "x");
  122. h(-std::numeric_limits<double>::infinity(), "x");
  123. h(std::numeric_limits<double>::infinity(), "x");
  124. h(std::numeric_limits<double>::quiet_NaN(), "x");
  125. BOOST_TEST_EQ(a.size(), 1);
  126. BOOST_TEST_EQ(b.size(), 1);
  127. BOOST_TEST_EQ(h.size(), 3);
  128. h(2, "x");
  129. BOOST_TEST_EQ(a.size(), 3);
  130. BOOST_TEST_EQ(b.size(), 1);
  131. BOOST_TEST_EQ(h.size(), 5);
  132. h(1, "y");
  133. BOOST_TEST_EQ(a.size(), 3);
  134. BOOST_TEST_EQ(b.size(), 2);
  135. BOOST_TEST_EQ(h.size(), 10);
  136. BOOST_TEST_EQ(h.at(-1, 0), 1);
  137. BOOST_TEST_EQ(h.at(-1, 1), 0);
  138. BOOST_TEST_EQ(h.at(3, 0), 2);
  139. BOOST_TEST_EQ(h.at(3, 1), 0);
  140. BOOST_TEST_EQ(h.at(a.index(0), b.index("x")), 1);
  141. BOOST_TEST_EQ(h.at(a.index(1), b.index("x")), 0);
  142. BOOST_TEST_EQ(h.at(a.index(2), b.index("x")), 1);
  143. BOOST_TEST_EQ(h.at(a.index(0), b.index("y")), 0);
  144. BOOST_TEST_EQ(h.at(a.index(1), b.index("y")), 1);
  145. BOOST_TEST_EQ(h.at(a.index(2), b.index("y")), 0);
  146. BOOST_TEST_THROWS(h(0, "x", 42), std::invalid_argument);
  147. }
  148. {
  149. auto h = make_s(Tag{}, std::vector<int>{}, custom_2d_axis{});
  150. BOOST_TEST_EQ(h.size(), 0);
  151. h(0, 0);
  152. BOOST_TEST_EQ(h.size(), 1);
  153. h(1, 0);
  154. h(0, 1);
  155. BOOST_TEST_EQ(h.size(), 2);
  156. h(10, 0);
  157. BOOST_TEST_EQ(h.size(), 11);
  158. BOOST_TEST_EQ(h[0], 1);
  159. BOOST_TEST_EQ(h[1], 2);
  160. BOOST_TEST_EQ(h[10], 1);
  161. BOOST_TEST_THROWS(h(0), std::invalid_argument);
  162. }
  163. // mix of a growing and a non-growing axis
  164. {
  165. using reg_nogrow = axis::regular<>;
  166. auto h = make(Tag(), reg_nogrow{2, 0.0, 1.0}, regular{2, 0.0, 1.0});
  167. BOOST_TEST_EQ(h.size(), 4 * 2);
  168. h(0.0, 0.0);
  169. BOOST_TEST_EQ(h.size(), 4 * 2);
  170. BOOST_TEST_EQ(h.at(0, 0), 1);
  171. h(-1.0, -0.1);
  172. BOOST_TEST_EQ(h.size(), 4 * 3);
  173. BOOST_TEST_EQ(h.at(-1, 0), 1);
  174. h(2.0, 1.1);
  175. BOOST_TEST_EQ(h.size(), 4 * 4);
  176. // axis 0: [0.0, 0.5, 1.0] + under/overflow
  177. // axis 1: [-0.5, 0.0, 0.5, 1.0, 1.5]
  178. BOOST_TEST_EQ(h.at(-1, 0), 1);
  179. BOOST_TEST_EQ(h.at(0, 1), 1);
  180. BOOST_TEST_EQ(h.at(2, 3), 1);
  181. BOOST_TEST_EQ(algorithm::sum(h), 3);
  182. }
  183. }
  184. int main() {
  185. run_tests<static_tag>();
  186. run_tests<dynamic_tag>();
  187. return boost::report_errors();
  188. }