Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / histogram / test / histogram_ostream_test.cpp
1 // Copyright 2019 Przemyslaw Bartosik
2 // Copyright 2019 Hans Dembinski
3 //
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt
6 // or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8 #include <boost/core/lightweight_test.hpp>
9 #include <boost/histogram/accumulators/mean.hpp>
10 #include <boost/histogram/accumulators/ostream.hpp>
11 #include <boost/histogram/axis/category.hpp>
12 #include <boost/histogram/axis/integer.hpp>
13 #include <boost/histogram/axis/option.hpp>
14 #include <boost/histogram/axis/regular.hpp>
15 #include <boost/histogram/make_histogram.hpp>
16 #include <boost/histogram/ostream.hpp>
17 #include <limits>
18 #include <sstream>
19 #include <string>
20 #include "throw_exception.hpp"
21 #include "utility_histogram.hpp"
22
23 using namespace boost::histogram;
24
25 template <class Histogram>
26 auto str(const Histogram& h, const unsigned width = 0) {
27   std::ostringstream os;
28   // BEGIN and END make nicer error messages
29   os << "BEGIN\n" << std::setw(width) << h << "END";
30   return os.str();
31 }
32
33 template <class Tag>
34 void run_tests() {
35   using R = axis::regular<>;
36   using R2 =
37       axis::regular<double, boost::use_default, axis::null_type, axis::option::none_t>;
38   using R3 = axis::regular<double, axis::transform::log>;
39   using C = axis::category<std::string>;
40   using I = axis::integer<>;
41
42   // regular
43   {
44     auto h = make(Tag(), R(3, -0.5, 1.0));
45     h.at(0) = 1;
46     h.at(1) = 10;
47     h.at(2) = 5;
48
49     const auto expected =
50         "BEGIN\n"
51         "histogram(regular(3, -0.5, 1, options=underflow | overflow))\n"
52         "                +------------------------------------------------------------+\n"
53         "[-inf, -0.5) 0  |                                                            |\n"
54         "[-0.5,    0) 1  |======                                                      |\n"
55         "[   0,  0.5) 10 |=========================================================== |\n"
56         "[ 0.5,    1) 5  |==============================                              |\n"
57         "[   1,  inf) 0  |                                                            |\n"
58         "                +------------------------------------------------------------+\n"
59         "END";
60
61     BOOST_TEST_CSTR_EQ(expected, str(h).c_str());
62   }
63
64   // regular, narrow
65   {
66     auto h = make(Tag(), R2(3, -0.5, 1.0));
67     h.at(0) = 1;
68     h.at(1) = 10;
69     h.at(2) = 2;
70
71     const auto expected = "BEGIN\n"
72                           "histogram(regular(3, -0.5, 1, options=none))\n"
73                           "               +-----------------------+\n"
74                           "[-0.5,   0) 1  |==                     |\n"
75                           "[   0, 0.5) 10 |====================== |\n"
76                           "[ 0.5,   1) 2  |====                   |\n"
77                           "               +-----------------------+\n"
78                           "END";
79
80     BOOST_TEST_CSTR_EQ(expected, str(h, 40).c_str());
81
82     // too narrow
83     BOOST_TEST_CSTR_EQ("BEGIN\n"
84                        "histogram(regular(3, -0.5, 1, options=none))END",
85                        str(h, 10).c_str());
86   }
87
88   // regular2
89   {
90     auto h = make(Tag(), R2(3, -0.5, 1.0));
91     h.at(0) = 1;
92     h.at(1) = -5;
93     h.at(2) = 2;
94
95     const auto expected =
96         "BEGIN\n"
97         "histogram(regular(3, -0.5, 1, options=none))\n"
98         "               +-------------------------------------------------------------+\n"
99         "[-0.5,   0) 1  |                                           =========         |\n"
100         "[   0, 0.5) -5 |===========================================                  |\n"
101         "[ 0.5,   1) 2  |                                           ================= |\n"
102         "               +-------------------------------------------------------------+\n"
103         "END";
104
105     BOOST_TEST_CSTR_EQ(expected, str(h).c_str());
106   }
107
108   // regular with log
109   {
110     auto h = make(Tag(), R3(6, 1e-3, 1e3, "foo"));
111
112     const auto expected =
113         "BEGIN\n"
114         "histogram(regular_log(6, 0.001, 1000, metadata=\"foo\", options=underflow | "
115         "overflow))\n"
116         "                 +-----------------------------------------------------------+\n"
117         "[    0, 0.001) 0 |                                                           |\n"
118         "[0.001,  0.01) 0 |                                                           |\n"
119         "[ 0.01,   0.1) 0 |                                                           |\n"
120         "[  0.1,     1) 0 |                                                           |\n"
121         "[    1,    10) 0 |                                                           |\n"
122         "[   10,   100) 0 |                                                           |\n"
123         "[  100,  1000) 0 |                                                           |\n"
124         "[ 1000,   inf) 0 |                                                           |\n"
125         "                 +-----------------------------------------------------------+\n"
126         "END";
127
128     BOOST_TEST_CSTR_EQ(expected, str(h).c_str());
129   }
130
131   // integer
132   {
133     auto h = make(Tag(), I(0, 1));
134     h.at(0) = -10;
135     h.at(1) = 5;
136
137     const auto expected =
138         "BEGIN\n"
139         "histogram(integer(0, 1, options=underflow | overflow))\n"
140         "       +---------------------------------------------------------------------+\n"
141         "-1 0   |                                                                     |\n"
142         " 0 -10 |=============================================                        |\n"
143         " 1 5   |                                             ======================= |\n"
144         "       +---------------------------------------------------------------------+\n"
145         "END";
146
147     BOOST_TEST_CSTR_EQ(expected, str(h).c_str());
148   }
149
150   // catorgy<string>
151   {
152     auto h = make(Tag(), C({"a", "bb", "ccc", "dddd"}));
153     h.at(0) = 1.23;
154     h.at(1) = 1;
155     h.at(2) = 1.2345789e-3;
156     h.at(3) = 1.2345789e-12;
157     h.at(4) = std::numeric_limits<double>::quiet_NaN();
158
159     const auto expected =
160         "BEGIN\n"
161         "histogram(category(\"a\", \"bb\", \"ccc\", \"dddd\", options=overflow))\n"
162         "                +------------------------------------------------------------+\n"
163         "    a 1.23      |=========================================================== |\n"
164         "   bb 1         |================================================            |\n"
165         "  ccc 0.001235  |                                                            |\n"
166         " dddd 1.235e-12 |                                                            |\n"
167         "other nan       |                                                            |\n"
168         "                +------------------------------------------------------------+\n"
169         "END";
170
171     BOOST_TEST_CSTR_EQ(expected, str(h).c_str());
172   }
173
174   // histogram with axis that has no value method
175   {
176     struct minimal_axis {
177       int index(int x) const { return x % 2; }
178       int size() const { return 2; }
179     };
180
181     auto h = make(Tag(), minimal_axis{});
182     h.at(0) = 3;
183     h.at(1) = 4;
184
185     const auto expected =
186         "BEGIN\n"
187         "histogram(<unstreamable>)\n"
188         "    +------------------------------------------------------------------------+\n"
189         "0 3 |=====================================================                   |\n"
190         "1 4 |======================================================================= |\n"
191         "    +------------------------------------------------------------------------+\n"
192         "END";
193
194     BOOST_TEST_CSTR_EQ(expected, str(h).c_str());
195   }
196
197   // fallback for 2D
198   {
199     auto h = make(Tag(), R(1, -1, 1), R(2, -4, 7));
200     h.at(-1, 0) = 1000;
201     h.at(-1, -1) = 123;
202     h.at(1, 0) = 1.23456789;
203     h.at(-1, 2) = std::numeric_limits<double>::quiet_NaN();
204
205     const auto expected =
206         "BEGIN\n"
207         "histogram(\n"
208         "  regular(1, -1, 1, options=underflow | overflow)\n"
209         "  regular(2, -4, 7, options=underflow | overflow)\n"
210         "  (-1 -1): 123   ( 0 -1): 0     ( 1 -1): 0     (-1  0): 1000 \n"
211         "  ( 0  0): 0     ( 1  0): 1.235 (-1  1): 0     ( 0  1): 0    \n"
212         "  ( 1  1): 0     (-1  2): nan   ( 0  2): 0     ( 1  2): 0    \n"
213         ")END";
214
215     BOOST_TEST_CSTR_EQ(expected, str(h).c_str());
216   }
217
218   // fallback for profile
219   {
220     auto h = make_s(Tag(), profile_storage(), R(1, -1, 1));
221     h.at(0) = accumulators::mean<>(10, 100, 1000);
222
223     const auto expected = "BEGIN\n"
224                           "histogram(\n"
225                           "  regular(1, -1, 1, options=underflow | overflow)\n"
226                           "  (-1): mean(0, 0, -0)      ( 0): mean(10, 100, 1000)\n"
227                           "  ( 1): mean(0, 0, -0)     \n"
228                           ")END";
229
230     BOOST_TEST_CSTR_EQ(expected, str(h).c_str());
231   }
232 }
233
234 int main() {
235   run_tests<static_tag>();
236   run_tests<dynamic_tag>();
237
238   {
239     // cannot make empty static histogram
240     auto h = histogram<std::vector<axis::regular<>>>();
241
242     const auto expected = "BEGIN\n"
243                           "histogram()END";
244
245     BOOST_TEST_CSTR_EQ(expected, str(h).c_str());
246   }
247
248   return boost::report_errors();
249 }