File indexing completed on 2025-01-30 09:43:44
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_HISTOGRAM_ACCUMULATORS_WEIGHTED_SUM_HPP
0008 #define BOOST_HISTOGRAM_ACCUMULATORS_WEIGHTED_SUM_HPP
0009
0010 #include <boost/core/nvp.hpp>
0011 #include <boost/histogram/detail/square.hpp>
0012 #include <boost/histogram/fwd.hpp> // for weighted_sum<>
0013 #include <type_traits>
0014
0015 namespace boost {
0016 namespace histogram {
0017 namespace accumulators {
0018
0019
0020 template <class ValueType>
0021 class weighted_sum {
0022 public:
0023 using value_type = ValueType;
0024 using const_reference = const value_type&;
0025
0026 weighted_sum() = default;
0027
0028
0029 weighted_sum(const_reference value) noexcept : weighted_sum(value, value) {}
0030
0031
0032 template <class T>
0033 weighted_sum(const weighted_sum<T>& s) noexcept
0034 : weighted_sum(s.value(), s.variance()) {}
0035
0036
0037 weighted_sum(const_reference value, const_reference variance) noexcept
0038 : sum_of_weights_(value), sum_of_weights_squared_(variance) {}
0039
0040
0041 weighted_sum& operator++() {
0042 ++sum_of_weights_;
0043 ++sum_of_weights_squared_;
0044 return *this;
0045 }
0046
0047
0048 weighted_sum& operator+=(const weight_type<value_type>& w) {
0049 sum_of_weights_ += w.value;
0050 sum_of_weights_squared_ += detail::square(w.value);
0051 return *this;
0052 }
0053
0054
0055 weighted_sum& operator+=(const weighted_sum& rhs) {
0056 sum_of_weights_ += rhs.sum_of_weights_;
0057 sum_of_weights_squared_ += rhs.sum_of_weights_squared_;
0058 return *this;
0059 }
0060
0061
0062 weighted_sum& operator/=(const weighted_sum& rhs) {
0063 const auto v = sum_of_weights_;
0064 const auto w = sum_of_weights_squared_;
0065 const auto rv = rhs.sum_of_weights_;
0066 const auto rw = rhs.sum_of_weights_squared_;
0067 sum_of_weights_ /= rv;
0068
0069
0070 using detail::square;
0071 sum_of_weights_squared_ = (w / square(v) + rw / square(rv)) * square(sum_of_weights_);
0072 return *this;
0073 }
0074
0075
0076 weighted_sum& operator*=(const_reference x) {
0077 sum_of_weights_ *= x;
0078 sum_of_weights_squared_ *= x * x;
0079 return *this;
0080 }
0081
0082 bool operator==(const weighted_sum& rhs) const noexcept {
0083 return sum_of_weights_ == rhs.sum_of_weights_ &&
0084 sum_of_weights_squared_ == rhs.sum_of_weights_squared_;
0085 }
0086
0087 bool operator!=(const weighted_sum& rhs) const noexcept { return !operator==(rhs); }
0088
0089
0090 const_reference value() const noexcept { return sum_of_weights_; }
0091
0092
0093 const_reference variance() const noexcept { return sum_of_weights_squared_; }
0094
0095
0096 explicit operator const_reference() const { return sum_of_weights_; }
0097
0098 template <class Archive>
0099 void serialize(Archive& ar, unsigned ) {
0100 ar& make_nvp("sum_of_weights", sum_of_weights_);
0101 ar& make_nvp("sum_of_weights_squared", sum_of_weights_squared_);
0102 }
0103
0104 private:
0105 value_type sum_of_weights_{};
0106 value_type sum_of_weights_squared_{};
0107 };
0108
0109 }
0110 }
0111 }
0112
0113 #ifndef BOOST_HISTOGRAM_DOXYGEN_INVOKED
0114 namespace std {
0115 template <class T, class U>
0116 struct common_type<boost::histogram::accumulators::weighted_sum<T>,
0117 boost::histogram::accumulators::weighted_sum<U>> {
0118 using type = boost::histogram::accumulators::weighted_sum<common_type_t<T, U>>;
0119 };
0120
0121 template <class T, class U>
0122 struct common_type<boost::histogram::accumulators::weighted_sum<T>, U> {
0123 using type = boost::histogram::accumulators::weighted_sum<common_type_t<T, U>>;
0124 };
0125
0126 template <class T, class U>
0127 struct common_type<T, boost::histogram::accumulators::weighted_sum<U>> {
0128 using type = boost::histogram::accumulators::weighted_sum<common_type_t<T, U>>;
0129 };
0130 }
0131 #endif
0132
0133 #endif