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