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 #ifndef BOOST_HISTOGRAM_ACCUMULATORS_WEIGHTED_SUM_HPP
8 #define BOOST_HISTOGRAM_ACCUMULATORS_WEIGHTED_SUM_HPP
10 #include <boost/core/nvp.hpp>
11 #include <boost/histogram/fwd.hpp> // for weighted_sum<>
12 #include <type_traits>
16 namespace accumulators {
18 /// Holds sum of weights and its variance estimate
19 template <class ValueType>
22 using value_type = ValueType;
23 using const_reference = const value_type&;
25 weighted_sum() = default;
27 /// Initialize sum to value and allow implicit conversion
28 weighted_sum(const_reference value) noexcept : weighted_sum(value, value) {}
30 /// Allow implicit conversion from sum<T>
32 weighted_sum(const weighted_sum<T>& s) noexcept
33 : weighted_sum(s.value(), s.variance()) {}
35 /// Initialize sum to value and variance
36 weighted_sum(const_reference value, const_reference variance) noexcept
37 : sum_of_weights_(value), sum_of_weights_squared_(variance) {}
40 weighted_sum& operator++() {
42 ++sum_of_weights_squared_;
46 /// Increment by weight.
48 weighted_sum& operator+=(const weight_type<T>& w) {
49 sum_of_weights_ += w.value;
50 sum_of_weights_squared_ += w.value * w.value;
54 /// Added another weighted sum.
55 weighted_sum& operator+=(const weighted_sum& rhs) {
56 sum_of_weights_ += rhs.sum_of_weights_;
57 sum_of_weights_squared_ += rhs.sum_of_weights_squared_;
62 weighted_sum& operator*=(const_reference x) {
64 sum_of_weights_squared_ *= x * x;
68 bool operator==(const weighted_sum& rhs) const noexcept {
69 return sum_of_weights_ == rhs.sum_of_weights_ &&
70 sum_of_weights_squared_ == rhs.sum_of_weights_squared_;
73 bool operator!=(const weighted_sum& rhs) const noexcept { return !operator==(rhs); }
75 /// Return value of the sum.
76 const_reference value() const noexcept { return sum_of_weights_; }
78 /// Return estimated variance of the sum.
79 const_reference variance() const noexcept { return sum_of_weights_squared_; }
81 // lossy conversion must be explicit
82 explicit operator const_reference() const { return sum_of_weights_; }
84 template <class Archive>
85 void serialize(Archive& ar, unsigned /* version */) {
86 ar& make_nvp("sum_of_weights", sum_of_weights_);
87 ar& make_nvp("sum_of_weights_squared", sum_of_weights_squared_);
91 value_type sum_of_weights_{};
92 value_type sum_of_weights_squared_{};
95 } // namespace accumulators
96 } // namespace histogram
99 #ifndef BOOST_HISTOGRAM_DOXYGEN_INVOKED
101 template <class T, class U>
102 struct common_type<boost::histogram::accumulators::weighted_sum<T>,
103 boost::histogram::accumulators::weighted_sum<U>> {
104 using type = boost::histogram::accumulators::weighted_sum<common_type_t<T, U>>;
107 template <class T, class U>
108 struct common_type<boost::histogram::accumulators::weighted_sum<T>, U> {
109 using type = boost::histogram::accumulators::weighted_sum<common_type_t<T, U>>;
112 template <class T, class U>
113 struct common_type<T, boost::histogram::accumulators::weighted_sum<U>> {
114 using type = boost::histogram::accumulators::weighted_sum<common_type_t<T, U>>;