]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/histogram/test/accumulators_weighted_mean_test.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / histogram / test / accumulators_weighted_mean_test.cpp
CommitLineData
f67539c2
TL
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
7#include <boost/core/lightweight_test.hpp>
8#include <boost/histogram/accumulators/ostream.hpp>
9#include <boost/histogram/accumulators/weighted_mean.hpp>
10#include <boost/histogram/weight.hpp>
11#include <sstream>
12#include "is_close.hpp"
13#include "throw_exception.hpp"
14#include "utility_str.hpp"
15
16using namespace boost::histogram;
17using namespace std::literals;
18
19int main() {
20 using m_t = accumulators::weighted_mean<double>;
1e59de90 21 using detail::square;
f67539c2 22
1e59de90
TL
23 // basic interface, string conversion
24 {
25 // see https://en.wikipedia.org/wiki/Weighted_arithmetic_mean#Reliability_weights
f67539c2 26
1e59de90
TL
27 m_t a;
28 BOOST_TEST_EQ(a.sum_of_weights(), 0);
29 BOOST_TEST_EQ(a, m_t{});
f67539c2 30
1e59de90
TL
31 a(weight(0.5), 1);
32 a(weight(1.0), 2);
33 a(weight(0.5), 3);
f67539c2 34
1e59de90
TL
35 BOOST_TEST_EQ(a.sum_of_weights(), 1 + 2 * 0.5);
36 BOOST_TEST_EQ(a.sum_of_weights_squared(), 1 + 2 * 0.5 * 0.5);
37 // https://en.wikipedia.org/wiki/Effective_sample_size#weighted_samples
38 BOOST_TEST_EQ(a.count(), square(a.sum_of_weights()) / a.sum_of_weights_squared());
39 BOOST_TEST_EQ(a.value(), (0.5 * 1 + 1.0 * 2 + 0.5 * 3) / a.sum_of_weights());
40 const auto m = a.value();
41 BOOST_TEST_IS_CLOSE(
42 a.variance(),
43 (0.5 * square(1 - m) + square(2 - m) + 0.5 * square(3 - m)) /
44 (a.sum_of_weights() - a.sum_of_weights_squared() / a.sum_of_weights()),
45 1e-3);
f67539c2 46
1e59de90
TL
47 BOOST_TEST_EQ(str(a), "weighted_mean(2, 2, 0.8)"s);
48 BOOST_TEST_EQ(str(a, 25, false), " weighted_mean(2, 2, 0.8)"s);
49 BOOST_TEST_EQ(str(a, 25, true), "weighted_mean(2, 2, 0.8) "s);
50 }
f67539c2 51
1e59de90
TL
52 // addition of zero element
53 {
54 BOOST_TEST_EQ(m_t() += m_t(), m_t());
55 BOOST_TEST_EQ(m_t(1, 2, 3, 4) += m_t(), m_t(1, 2, 3, 4));
56 BOOST_TEST_EQ(m_t() += m_t(1, 2, 3, 4), m_t(1, 2, 3, 4));
57 }
58
59 // addition
60 {
61 m_t a, b, c;
62
63 a(weight(4), 2);
64 a(weight(3), 3);
65 BOOST_TEST_EQ(a.sum_of_weights(), 4 + 3);
66 BOOST_TEST_EQ(a.sum_of_weights_squared(), 4 * 4 + 3 * 3);
67 BOOST_TEST_EQ(a.value(), (4 * 2 + 3 * 3) / 7.);
68 BOOST_TEST_IS_CLOSE(a.variance(), 0.5, 1e-3);
69
70 b(weight(2), 4);
71 b(weight(1), 6);
72 BOOST_TEST_EQ(b.sum_of_weights(), 3);
73 BOOST_TEST_EQ(b.sum_of_weights_squared(), 1 + 2 * 2);
74 BOOST_TEST_EQ(b.value(), (2 * 4 + 1 * 6) / (2. + 1.));
75 BOOST_TEST_IS_CLOSE(b.variance(), 2, 1e-3);
76
77 c(weight(4), 2);
78 c(weight(3), 3);
79 c(weight(2), 4);
80 c(weight(1), 6);
81
82 auto d = a;
83 d += b;
84 BOOST_TEST_EQ(c.sum_of_weights(), d.sum_of_weights());
85 BOOST_TEST_EQ(c.sum_of_weights_squared(), d.sum_of_weights_squared());
86 BOOST_TEST_EQ(c.value(), d.value());
87 BOOST_TEST_IS_CLOSE(c.variance(), d.variance(), 1e-3);
88 }
89
90 // using weights * 2 compared to adding weighted samples twice must
91 // - give same for sum_of_weights and mean
92 // - give twice sum_of_weights_squared
93 // - give half effective count
94 // - variance is complicated, but larger
95 {
96 m_t a, b;
97
98 for (int i = 0; i < 2; ++i) {
99 a(weight(0.5), 1);
100 a(weight(1.0), 2);
101 a(weight(0.5), 3);
102 }
103
104 b(weight(1), 1);
105 b(weight(2), 2);
106 b(weight(1), 3);
107
108 BOOST_TEST_EQ(a.sum_of_weights(), b.sum_of_weights());
109 BOOST_TEST_EQ(2 * a.sum_of_weights_squared(), b.sum_of_weights_squared());
110 BOOST_TEST_EQ(a.count(), 2 * b.count());
111 BOOST_TEST_EQ(a.value(), b.value());
112 BOOST_TEST_LT(a.variance(), b.variance());
113 }
f67539c2
TL
114
115 return boost::report_errors();
116}