Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / histogram / accumulators / mean.hpp
index 5bb8d84..f814fc0 100644 (file)
@@ -7,8 +7,11 @@
 #ifndef BOOST_HISTOGRAM_ACCUMULATORS_MEAN_HPP
 #define BOOST_HISTOGRAM_ACCUMULATORS_MEAN_HPP
 
-#include <boost/histogram/fwd.hpp>
-#include <cstddef>
+#include <boost/assert.hpp>
+#include <boost/core/nvp.hpp>
+#include <boost/histogram/fwd.hpp> // for mean<>
+#include <boost/throw_exception.hpp>
+#include <stdexcept>
 #include <type_traits>
 
 namespace boost {
@@ -24,26 +27,35 @@ template <class RealType>
 class mean {
 public:
   mean() = default;
-  mean(const std::size_t n, const RealType& mean, const RealType& variance)
-      : sum_(n), mean_(mean), sum_of_deltas_squared_(variance * (sum_ - 1)) {}
+  mean(const RealType& n, const RealType& mean, const RealType& variance) noexcept
+      : sum_(n), mean_(mean), sum_of_deltas_squared_(variance * (n - 1)) {}
 
-  void operator()(const RealType& x) {
-    sum_ += 1;
+  void operator()(const RealType& x) noexcept {
+    sum_ += static_cast<RealType>(1);
     const auto delta = x - mean_;
     mean_ += delta / sum_;
     sum_of_deltas_squared_ += delta * (x - mean_);
   }
 
+  void operator()(const weight_type<RealType>& w, const RealType& x) noexcept {
+    sum_ += w.value;
+    const auto delta = x - mean_;
+    mean_ += w.value * delta / sum_;
+    sum_of_deltas_squared_ += w.value * delta * (x - mean_);
+  }
+
   template <class T>
-  mean& operator+=(const mean<T>& rhs) {
-    const auto tmp = mean_ * sum_ + static_cast<RealType>(rhs.mean_ * rhs.sum_);
-    sum_ += rhs.sum_;
-    mean_ = tmp / sum_;
+  mean& operator+=(const mean<T>& rhs) noexcept {
+    if (sum_ != 0 || rhs.sum_ != 0) {
+      const auto tmp = mean_ * sum_ + static_cast<RealType>(rhs.mean_ * rhs.sum_);
+      sum_ += rhs.sum_;
+      mean_ = tmp / sum_;
+    }
     sum_of_deltas_squared_ += static_cast<RealType>(rhs.sum_of_deltas_squared_);
     return *this;
   }
 
-  mean& operator*=(const RealType& s) {
+  mean& operator*=(const RealType& s) noexcept {
     mean_ *= s;
     sum_of_deltas_squared_ *= s * s;
     return *this;
@@ -60,16 +72,26 @@ public:
     return !operator==(rhs);
   }
 
-  std::size_t count() const noexcept { return sum_; }
+  const RealType& count() const noexcept { return sum_; }
   const RealType& value() const noexcept { return mean_; }
-  RealType variance() const { return sum_of_deltas_squared_ / (sum_ - 1); }
+  RealType variance() const noexcept { return sum_of_deltas_squared_ / (sum_ - 1); }
 
   template <class Archive>
-  void serialize(Archive&, unsigned /* version */);
+  void serialize(Archive& ar, unsigned version) {
+    if (version == 0) {
+      // read only
+      std::size_t sum;
+      ar& make_nvp("sum", sum);
+      sum_ = static_cast<RealType>(sum);
+    } else {
+      ar& make_nvp("sum", sum_);
+    }
+    ar& make_nvp("mean", mean_);
+    ar& make_nvp("sum_of_deltas_squared", sum_of_deltas_squared_);
+  }
 
 private:
-  std::size_t sum_ = 0;
-  RealType mean_ = 0, sum_of_deltas_squared_ = 0;
+  RealType sum_ = 0, mean_ = 0, sum_of_deltas_squared_ = 0;
 };
 
 } // namespace accumulators
@@ -77,6 +99,21 @@ private:
 } // namespace boost
 
 #ifndef BOOST_HISTOGRAM_DOXYGEN_INVOKED
+
+namespace boost {
+namespace serialization {
+
+template <class T>
+struct version;
+
+// version 1 for boost::histogram::accumulators::mean<RealType>
+template <class RealType>
+struct version<boost::histogram::accumulators::mean<RealType>>
+    : std::integral_constant<int, 1> {};
+
+} // namespace serialization
+} // namespace boost
+
 namespace std {
 template <class T, class U>
 /// Specialization for boost::histogram::accumulators::mean.
@@ -85,6 +122,7 @@ struct common_type<boost::histogram::accumulators::mean<T>,
   using type = boost::histogram::accumulators::mean<common_type_t<T, U>>;
 };
 } // namespace std
+
 #endif
 
 #endif