1 // Copyright 2015-2018 Hans Dembinski
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)
7 #include <boost/core/lightweight_test.hpp>
8 #include <boost/histogram/accumulators/mean.hpp>
9 #include <boost/histogram/accumulators/ostream.hpp>
10 #include <boost/histogram/accumulators/sum.hpp>
11 #include <boost/histogram/accumulators/thread_safe.hpp>
12 #include <boost/histogram/accumulators/weighted_mean.hpp>
13 #include <boost/histogram/accumulators/weighted_sum.hpp>
14 #include "throw_exception.hpp"
16 #include "is_close.hpp"
18 using namespace boost::histogram;
19 using namespace std::literals;
22 auto str(const T& t) {
23 std::ostringstream os;
30 using w_t = accumulators::weighted_sum<double>;
32 BOOST_TEST_EQ(str(w), "weighted_sum(0, 0)"s);
34 BOOST_TEST_EQ(w, w_t(0));
35 BOOST_TEST_NE(w, w_t(1));
37 BOOST_TEST_EQ(w.value(), 1);
38 BOOST_TEST_EQ(w.variance(), 1);
43 BOOST_TEST_EQ(w.value(), 3);
44 BOOST_TEST_EQ(w.variance(), 5);
45 BOOST_TEST_EQ(w, w_t(3, 5));
46 BOOST_TEST_NE(w, w_t(3));
49 BOOST_TEST_EQ(w.value(), 4);
50 BOOST_TEST_EQ(w.variance(), 7);
52 // consistency: a weighted counter increased by weight 1 multiplied
53 // by 2 must be the same as a weighted counter increased by weight 2
57 BOOST_TEST_EQ(u, w_t(2, 4));
63 // conversion to RealType
66 BOOST_TEST_EQ(static_cast<double>(y), 1);
70 using m_t = accumulators::mean<double>;
72 BOOST_TEST_EQ(a.count(), 0);
79 BOOST_TEST_EQ(a.count(), 4);
80 BOOST_TEST_EQ(a.value(), 10);
81 BOOST_TEST_EQ(a.variance(), 30);
83 BOOST_TEST_EQ(str(a), "mean(4, 10, 30)"s);
91 BOOST_TEST_EQ(b.count(), 4);
92 BOOST_TEST_EQ(b.value(), 1e8 + 10);
93 BOOST_TEST_EQ(b.variance(), 30);
96 c += a; // same as feeding all samples twice
98 BOOST_TEST_EQ(c.count(), 8);
99 BOOST_TEST_EQ(c.value(), 10);
100 BOOST_TEST_IS_CLOSE(c.variance(), 25.714, 1e-3);
104 using m_t = accumulators::weighted_mean<double>;
106 BOOST_TEST_EQ(a.sum_of_weights(), 0);
112 BOOST_TEST_EQ(a.sum_of_weights(), 2);
113 BOOST_TEST_EQ(a.value(), 2);
114 BOOST_TEST_IS_CLOSE(a.variance(), 0.8, 1e-3);
116 BOOST_TEST_EQ(str(a), "weighted_mean(2, 2, 0.8)"s);
119 b += a; // same as feeding all samples twice
121 BOOST_TEST_EQ(b.sum_of_weights(), 4);
122 BOOST_TEST_EQ(b.value(), 2);
123 BOOST_TEST_IS_CLOSE(b.variance(), 0.615, 1e-3);
132 BOOST_TEST_EQ(bad_sum, 0); // instead of 2
134 accumulators::sum<double> sum;
136 BOOST_TEST_EQ(sum.large(), 1);
137 BOOST_TEST_EQ(sum.small(), 0);
138 BOOST_TEST_EQ(str(sum), "sum(1 + 0)"s);
140 BOOST_TEST_EQ(str(sum), "sum(1e+100 + 1)"s);
142 BOOST_TEST_EQ(str(sum), "sum(1e+100 + 2)"s);
144 BOOST_TEST_EQ(str(sum), "sum(0 + 2)"s);
145 BOOST_TEST_EQ(sum, 2); // correct answer
146 BOOST_TEST_EQ(sum.large(), 0);
147 BOOST_TEST_EQ(sum.small(), 2);
149 accumulators::sum<double> a(3), b(2), c(3);
159 accumulators::weighted_sum<accumulators::sum<double>> w;
166 BOOST_TEST_EQ(w.value(), 2);
167 BOOST_TEST_EQ(w.variance(), 2e200);
171 accumulators::thread_safe<int> i;
175 BOOST_TEST_EQ(i, 1001);
176 BOOST_TEST_EQ(str(i), "1001"s);
179 return boost::report_errors();