...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
boost::histogram::accumulators::sum — Uses Neumaier algorithm to compute accurate sums of floats.
// In header: <boost/histogram/accumulators/sum.hpp> template<typename ValueType> class sum { public: // types typedef ValueType value_type; typedef const value_type & const_reference; // public member functions sum() = default; sum(const_reference) noexcept; template<typename T> sum(const sum< T > &) noexcept; sum(const_reference, const_reference) noexcept; sum & operator++() noexcept; sum & operator+=(const_reference) noexcept; sum & operator+=(const sum &) noexcept; sum & operator*=(const_reference) noexcept; bool operator==(const sum &) const noexcept; bool operator!=(const sum &) const noexcept; value_type value() const noexcept; const_reference large_part() const noexcept; const_reference small_part() const noexcept; explicit operator value_type() const noexcept; template<typename Archive> void serialize(Archive &, unsigned); sum & operator*=(const sum &) noexcept; sum operator*(const sum &) const noexcept; sum & operator/=(const sum &) noexcept; sum operator/(const sum &) const noexcept; bool operator<(const sum &) const noexcept; bool operator>(const sum &) const noexcept; bool operator<=(const sum &) const noexcept; bool operator>=(const sum &) const noexcept; };
The algorithm is an improved Kahan algorithm (https://en.wikipedia.org/wiki/Kahan_summation_algorithm). The algorithm uses memory for two numbers and is three to five times slower compared to using a single number to accumulate a sum, but the relative error of the sum is at the level of the machine precision, independent of the number of samples.
A. Neumaier, Zeitschrift fuer Angewandte Mathematik und Mechanik 54 (1974) 39-51.
sum
public member functionssum() = default;
sum(const_reference value) noexcept;Initialize sum to value and allow implicit conversion.
template<typename T> sum(const sum< T > & s) noexcept;Allow implicit conversion from sum<T>
sum(const_reference large_part, const_reference small_part) noexcept;Initialize sum explicitly with large and small parts.
sum & operator++() noexcept;Increment sum by one.
sum & operator+=(const_reference value) noexcept;Increment sum by value.
sum & operator+=(const sum & s) noexcept;Add another sum.
sum & operator*=(const_reference value) noexcept;Scale by value.
bool operator==(const sum & rhs) const noexcept;
bool operator!=(const sum & rhs) const noexcept;
value_type value() const noexcept;Return value of the sum.
const_reference large_part() const noexcept;Return large part of the sum.
const_reference small_part() const noexcept;Return small part of the sum.
explicit operator value_type() const noexcept;
template<typename Archive> void serialize(Archive & ar, unsigned);
sum & operator*=(const sum & rhs) noexcept;
sum operator*(const sum & rhs) const noexcept;
sum & operator/=(const sum & rhs) noexcept;
sum operator/(const sum & rhs) const noexcept;
bool operator<(const sum & rhs) const noexcept;
bool operator>(const sum & rhs) const noexcept;
bool operator<=(const sum & rhs) const noexcept;
bool operator>=(const sum & rhs) const noexcept;