Add a simple statistics calculator utility

This commit is contained in:
Nikita Lisitsa 2020-09-23 13:00:57 +03:00
parent 0e5759f1c6
commit 5830977e45

View file

@ -0,0 +1,87 @@
#pragma once
#include <cmath>
#include <limits>
namespace psemek::util
{
namespace detail
{
template <typename T>
constexpr T min()
{
if constexpr (std::is_floating_point_v<T>)
{
return -std::numeric_limits<T>::infinity();
}
else
{
return std::numeric_limits<T>::min();
}
}
template <typename T>
constexpr T max()
{
if constexpr (std::is_floating_point_v<T>)
{
return std::numeric_limits<T>::infinity();
}
else
{
return std::numeric_limits<T>::max();
}
}
}
template <typename T>
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>();
T max_ = detail::min<T>();
};
template <typename T>
void statistics<T>::push(T const & value)
{
++count_;
sum_ += value;
sum_sqr_ += value * value;
min_ = std::min(min_, value);
max_ = std::max(max_, value);
}
template <typename T>
T statistics<T>::mean() const
{
return sum_ / count_;
}
template <typename T>
T statistics<T>::var() const
{
T const m = mean();
return std::sqrt(sum_sqr_ / count_ - m * m);
}
template <typename OStream, typename T>
OStream & operator << (OStream & os, statistics<T> const & s)
{
return os << "mean = " << s.mean() << ", var = " << s.var() << ", range = [" << s.min() << " .. " << s.max() << "]";
}
}