Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / histogram / accumulators / weighted_sum.hpp
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 #ifndef BOOST_HISTOGRAM_ACCUMULATORS_WEIGHTED_SUM_HPP
8 #define BOOST_HISTOGRAM_ACCUMULATORS_WEIGHTED_SUM_HPP
9
10 #include <boost/core/nvp.hpp>
11 #include <boost/histogram/fwd.hpp> // for weighted_sum<>
12 #include <type_traits>
13
14 namespace boost {
15 namespace histogram {
16 namespace accumulators {
17
18 /// Holds sum of weights and its variance estimate
19 template <typename RealType>
20 class weighted_sum {
21 public:
22   weighted_sum() = default;
23   explicit weighted_sum(const RealType& value) noexcept
24       : sum_of_weights_(value), sum_of_weights_squared_(value) {}
25   weighted_sum(const RealType& value, const RealType& variance) noexcept
26       : sum_of_weights_(value), sum_of_weights_squared_(variance) {}
27
28   /// Increment by one.
29   weighted_sum& operator++() { return operator+=(1); }
30
31   /// Increment by value.
32   template <typename T>
33   weighted_sum& operator+=(const T& value) {
34     sum_of_weights_ += value;
35     sum_of_weights_squared_ += value * value;
36     return *this;
37   }
38
39   /// Added another weighted sum.
40   template <typename T>
41   weighted_sum& operator+=(const weighted_sum<T>& rhs) {
42     sum_of_weights_ += static_cast<RealType>(rhs.sum_of_weights_);
43     sum_of_weights_squared_ += static_cast<RealType>(rhs.sum_of_weights_squared_);
44     return *this;
45   }
46
47   /// Scale by value.
48   weighted_sum& operator*=(const RealType& x) {
49     sum_of_weights_ *= x;
50     sum_of_weights_squared_ *= x * x;
51     return *this;
52   }
53
54   bool operator==(const RealType& rhs) const noexcept {
55     return sum_of_weights_ == rhs && sum_of_weights_squared_ == rhs;
56   }
57
58   template <typename T>
59   bool operator==(const weighted_sum<T>& rhs) const noexcept {
60     return sum_of_weights_ == rhs.sum_of_weights_ &&
61            sum_of_weights_squared_ == rhs.sum_of_weights_squared_;
62   }
63
64   template <typename T>
65   bool operator!=(const T& rhs) const noexcept {
66     return !operator==(rhs);
67   }
68
69   /// Return value of the sum.
70   const RealType& value() const noexcept { return sum_of_weights_; }
71
72   /// Return estimated variance of the sum.
73   const RealType& variance() const noexcept { return sum_of_weights_squared_; }
74
75   // lossy conversion must be explicit
76   template <class T>
77   explicit operator T() const {
78     return static_cast<T>(sum_of_weights_);
79   }
80
81   template <class Archive>
82   void serialize(Archive& ar, unsigned /* version */) {
83     ar& make_nvp("sum_of_weights", sum_of_weights_);
84     ar& make_nvp("sum_of_weights_squared", sum_of_weights_squared_);
85   }
86
87 private:
88   RealType sum_of_weights_ = RealType();
89   RealType sum_of_weights_squared_ = RealType();
90 };
91
92 } // namespace accumulators
93 } // namespace histogram
94 } // namespace boost
95
96 #ifndef BOOST_HISTOGRAM_DOXYGEN_INVOKED
97 namespace std {
98 template <class T, class U>
99 struct common_type<boost::histogram::accumulators::weighted_sum<T>,
100                    boost::histogram::accumulators::weighted_sum<U>> {
101   using type = boost::histogram::accumulators::weighted_sum<common_type_t<T, U>>;
102 };
103
104 template <class T, class U>
105 struct common_type<boost::histogram::accumulators::weighted_sum<T>, U> {
106   using type = boost::histogram::accumulators::weighted_sum<common_type_t<T, U>>;
107 };
108
109 template <class T, class U>
110 struct common_type<T, boost::histogram::accumulators::weighted_sum<U>> {
111   using type = boost::histogram::accumulators::weighted_sum<common_type_t<T, U>>;
112 };
113 } // namespace std
114 #endif
115
116 #endif