add method to get effective count for weighted accumulators (#312)

following the discussion around boost-histogram's interface (Python wrapper)
This commit is contained in:
Hans Dembinski 2021-04-23 15:06:05 +02:00 committed by GitHub
parent 14fdb6fb56
commit c80ab0ca34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 4 deletions

View File

@ -110,7 +110,12 @@ public:
bool operator!=(const mean& rhs) const noexcept { return !operator==(rhs); }
/// Return how many samples were accumulated.
/** Return how many samples were accumulated.
count() should be used to check whether value() and variance() are defined,
see documentation of value() and variance(). count() can be used to compute
the variance of the mean by dividing variance() by count().
*/
const_reference count() const noexcept { return sum_; }
/** Return mean value of accumulated samples.

View File

@ -110,16 +110,28 @@ public:
return sum_of_weights_squared_;
}
/** Return effective counts.
This corresponds to the equivalent number of unweighted samples that would
have the same variance as this sample. count() should be used to check whether
value() and variance() are defined, see documentation of value() and variance().
count() can be used to compute the variance of the mean by dividing variance()
by count().
*/
value_type count() const noexcept {
// see https://en.wikipedia.org/wiki/Effective_sample_size#weighted_samples
return detail::square(sum_of_weights_) / sum_of_weights_squared_;
}
/** Return mean value of accumulated weighted samples.
The result is undefined, if `sum_of_weights() == 0`.
The result is undefined, if count() == 0.
*/
const_reference value() const noexcept { return weighted_mean_; }
/** Return variance of accumulated weighted samples.
The result is undefined, if `sum_of_weights() == 0` or
`sum_of_weights() == sum_of_weights_squared()`.
The result is undefined, if count() == 0 or count() == 1.
*/
value_type variance() const {
// see https://en.wikipedia.org/wiki/Weighted_arithmetic_mean#Reliability_weights

View File

@ -34,6 +34,9 @@ int main() {
BOOST_TEST_EQ(a.sum_of_weights(), 1 + 2 * 0.5);
BOOST_TEST_EQ(a.sum_of_weights_squared(), 1 + 2 * 0.5 * 0.5);
// https://en.wikipedia.org/wiki/Effective_sample_size#weighted_samples
BOOST_TEST_EQ(a.count(), square(a.sum_of_weights()) / a.sum_of_weights_squared());
BOOST_TEST_EQ(a.value(), (0.5 * 1 + 1.0 * 2 + 0.5 * 3) / a.sum_of_weights());
const auto m = a.value();
BOOST_TEST_IS_CLOSE(
a.variance(),
@ -104,6 +107,7 @@ int main() {
BOOST_TEST_EQ(a.sum_of_weights(), b.sum_of_weights());
BOOST_TEST_EQ(2 * a.sum_of_weights_squared(), b.sum_of_weights_squared());
BOOST_TEST_EQ(a.count(), 2 * b.count());
BOOST_TEST_EQ(a.value(), b.value());
BOOST_TEST_LT(a.variance(), b.variance());
}