(Simple) Incremental Statistics
#include "inc_stats.hpp"
#include <assert.h>
void test_case()
{
inc_stats<double, 3> stats;
stats.in(5.5);
stats.in(6.6);
assert(stats.min() == 5.5);
assert(stats.max() == 6.6);
stats.in(1.0);
stats.in(8.0);
stats.in(3.0);
assert(stats.min() == 1.0);
assert(stats.max() == 8.0);
assert(stats.count() == 5);
double avg = (1.0 + 8.0 + 3.0) / 3;
assert(abs(stats.avg() - avg) < 0.001);
}
int main()
{
test_case();
return 0;
}
#pragma once
#include <algorithm>
#include <deque>
template<typename T, size_t SUM_COUNT = 0>
class inc_stats
{
size_t m_cou;
T m_min, m_max;
T m_sum;
std::deque<T> m_que;
public:
inc_stats() : m_cou(0), m_min(0), m_max(0), m_sum(0)
{
}
void in(T value)
{
if (m_cou > 0)
{
m_min = std::min(m_min, value);
m_max = std::max(m_max, value);
}
else
{
m_min = m_max = value;
}
m_cou++;
m_sum += value;
if (SUM_COUNT > 0)
{
m_que.push_back(value);
if (m_que.size() > SUM_COUNT)
{
m_sum -= m_que.front();
m_que.pop_front();
}
}
}
size_t count() const
{
return m_cou;
}
T min() const
{
return m_min;
}
T max() const
{
return m_max;
}
T avg() const
{
size_t cou = (SUM_COUNT > 0) ? m_que.size() : m_cou;
return (cou > 0) ? m_sum / cou : 0;
}
};
project(inc_stats)
add_executable(${PROJECT_NAME} inc_stats.hpp inc_stats_test.cpp)
@ECHO OFF
CD /D %~dp0
PATH ^
%ProgramFiles%\CMake\bin;^
%ProgramFiles(x86)%\CMake\bin
IF NOT EXIST build MKDIR build
CD build
cmake %* ..
PAUSE