From 5830977e45882d63ae739d16fc635f729e10590a Mon Sep 17 00:00:00 2001 From: lisyarus Date: Wed, 23 Sep 2020 13:00:57 +0300 Subject: [PATCH] Add a simple statistics calculator utility --- libs/util/include/psemek/util/statistics.hpp | 87 ++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 libs/util/include/psemek/util/statistics.hpp diff --git a/libs/util/include/psemek/util/statistics.hpp b/libs/util/include/psemek/util/statistics.hpp new file mode 100644 index 00000000..3f914d46 --- /dev/null +++ b/libs/util/include/psemek/util/statistics.hpp @@ -0,0 +1,87 @@ +#pragma once + +#include +#include + +namespace psemek::util +{ + + namespace detail + { + + template + constexpr T min() + { + if constexpr (std::is_floating_point_v) + { + return -std::numeric_limits::infinity(); + } + else + { + return std::numeric_limits::min(); + } + } + + template + constexpr T max() + { + if constexpr (std::is_floating_point_v) + { + return std::numeric_limits::infinity(); + } + else + { + return std::numeric_limits::max(); + } + } + + } + + template + struct statistics + { + void push(T const & value); + + T mean() const; + T var() const; + T min() const { return min_; } + T max() const { return max_; } + + private: + std::size_t count_ = 0; + T sum_ = T{0}; + T sum_sqr_ = T{0}; + T min_ = detail::max(); + T max_ = detail::min(); + }; + + template + void statistics::push(T const & value) + { + ++count_; + sum_ += value; + sum_sqr_ += value * value; + min_ = std::min(min_, value); + max_ = std::max(max_, value); + } + + template + T statistics::mean() const + { + return sum_ / count_; + } + + template + T statistics::var() const + { + T const m = mean(); + return std::sqrt(sum_sqr_ / count_ - m * m); + } + + template + OStream & operator << (OStream & os, statistics const & s) + { + return os << "mean = " << s.mean() << ", var = " << s.var() << ", range = [" << s.min() << " .. " << s.max() << "]"; + } + +}