Imported Upstream version 1.71.0
[platform/upstream/boost.git] / libs / histogram / examples / guide_custom_accumulators.cpp
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 //[ guide_custom_accumulators
8
9 #include <array>
10 #include <boost/format.hpp>
11 #include <boost/histogram.hpp>
12 #include <boost/histogram/accumulators/mean.hpp>
13 #include <iostream>
14
15 int main() {
16   using namespace boost::histogram;
17   const auto axis = axis::regular<>(3, 0.0, 1.0);
18
19   // Create a 1D-profile, which computes the mean of samples in each bin. The
20   // factory function `make_profile` is provided by the library as a shorthand.
21   auto h1 = make_histogram_with(dense_storage<accumulators::mean<>>(), axis);
22
23   // Argument of `sample` is passed to accumulator.
24   h1(0.0, sample(2)); // sample 2 goes to first bin
25   h1(0.1, sample(2)); // sample 2 goes to first bin
26   h1(0.4, sample(3)); // sample 3 goes to second bin
27   h1(0.5, sample(4)); // sample 4 goes to second bin
28
29   std::ostringstream os1;
30   for (auto&& x : indexed(h1)) {
31     // Accumulators usually have methods to access their state. Use the arrow
32     // operator to access them. Here, `count()` gives the number of samples,
33     // `value()` the mean, and `variance()` the variance estimate of the mean.
34     os1 << boost::format("%i count %i mean %.1f variance %.1f\n") % x.index() %
35                x->count() % x->value() % x->variance();
36   }
37   std::cout << os1.str() << std::flush;
38   assert(os1.str() == "0 count 2 mean 2.0 variance 0.0\n"
39                       "1 count 2 mean 3.5 variance 0.5\n"
40                       "2 count 0 mean 0.0 variance 0.0\n");
41
42   // Let's make a custom accumulator, which tracks the maximum of the samples. It must
43   // have a call operator that accepts the argument of the `sample` function. The return
44   // value of the call operator is ignored.
45   struct max {
46     void operator()(double x) {
47       if (x > value) value = x;
48     }
49     double value = 0; // value is initialized to zero
50   };
51
52   // Create a histogram that uses the custom accumulator.
53   auto h2 = make_histogram_with(dense_storage<max>(), axis);
54   h2(0.0, sample(2));   // sample 2 goes to first bin
55   h2(0.1, sample(2.5)); // sample 2.5 goes to first bin
56   h2(0.4, sample(3));   // sample 3 goes to second bin
57   h2(0.5, sample(4));   // sample 4 goes to second bin
58
59   std::ostringstream os2;
60   for (auto&& x : indexed(h2)) {
61     os2 << boost::format("%i value %.1f\n") % x.index() % x->value;
62   }
63   std::cout << os2.str() << std::flush;
64   assert(os2.str() == "0 value 2.5\n"
65                       "1 value 4.0\n"
66                       "2 value 0.0\n");
67 }
68
69 //]