summaryrefslogtreecommitdiff
path: root/boost/histogram/accumulators/mean.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/histogram/accumulators/mean.hpp')
-rw-r--r--boost/histogram/accumulators/mean.hpp90
1 files changed, 90 insertions, 0 deletions
diff --git a/boost/histogram/accumulators/mean.hpp b/boost/histogram/accumulators/mean.hpp
new file mode 100644
index 0000000000..5bb8d840a2
--- /dev/null
+++ b/boost/histogram/accumulators/mean.hpp
@@ -0,0 +1,90 @@
+// Copyright 2015-2018 Hans Dembinski
+//
+// Distributed under the Boost Software License, version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_HISTOGRAM_ACCUMULATORS_MEAN_HPP
+#define BOOST_HISTOGRAM_ACCUMULATORS_MEAN_HPP
+
+#include <boost/histogram/fwd.hpp>
+#include <cstddef>
+#include <type_traits>
+
+namespace boost {
+namespace histogram {
+namespace accumulators {
+
+/** Calculates mean and variance of sample.
+
+ Uses Welfords's incremental algorithm to improve the numerical
+ stability of mean and variance computation.
+*/
+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)) {}
+
+ void operator()(const RealType& x) {
+ sum_ += 1;
+ const auto delta = x - mean_;
+ mean_ += delta / sum_;
+ sum_of_deltas_squared_ += 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_;
+ sum_of_deltas_squared_ += static_cast<RealType>(rhs.sum_of_deltas_squared_);
+ return *this;
+ }
+
+ mean& operator*=(const RealType& s) {
+ mean_ *= s;
+ sum_of_deltas_squared_ *= s * s;
+ return *this;
+ }
+
+ template <class T>
+ bool operator==(const mean<T>& rhs) const noexcept {
+ return sum_ == rhs.sum_ && mean_ == rhs.mean_ &&
+ sum_of_deltas_squared_ == rhs.sum_of_deltas_squared_;
+ }
+
+ template <class T>
+ bool operator!=(const mean<T>& rhs) const noexcept {
+ return !operator==(rhs);
+ }
+
+ std::size_t count() const noexcept { return sum_; }
+ const RealType& value() const noexcept { return mean_; }
+ RealType variance() const { return sum_of_deltas_squared_ / (sum_ - 1); }
+
+ template <class Archive>
+ void serialize(Archive&, unsigned /* version */);
+
+private:
+ std::size_t sum_ = 0;
+ RealType mean_ = 0, sum_of_deltas_squared_ = 0;
+};
+
+} // namespace accumulators
+} // namespace histogram
+} // namespace boost
+
+#ifndef BOOST_HISTOGRAM_DOXYGEN_INVOKED
+namespace std {
+template <class T, class U>
+/// Specialization for boost::histogram::accumulators::mean.
+struct common_type<boost::histogram::accumulators::mean<T>,
+ boost::histogram::accumulators::mean<U>> {
+ using type = boost::histogram::accumulators::mean<common_type_t<T, U>>;
+};
+} // namespace std
+#endif
+
+#endif