This repository has been archived on 2020-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
Files
Indoor/math/stats/Statistics.h

184 lines
5.8 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* © Copyright 2014 Urheberrechtshinweis
* Alle Rechte vorbehalten / All Rights Reserved
*
* Programmcode ist urheberrechtlich geschuetzt.
* Das Urheberrecht liegt, soweit nicht ausdruecklich anders gekennzeichnet, bei Frank Ebner.
* Keine Verwendung ohne explizite Genehmigung.
* (vgl. § 106 ff UrhG / § 97 UrhG)
*/
#ifndef STATISTICS_H
#define STATISTICS_H
#include <set>
#include <cstdint>
#include <sstream>
#include <cmath>
namespace Stats {
/**
* store values here and get statistics about their
* avg, median, std-dev, etc.
*/
template <typename T> class Statistics {
public:
/** ctor */
Statistics() : sum(), sumSquared(), cnt() {;}
/** dtor */
~Statistics() {;}
/** add a new value */
void add(T value) {
++cnt;
sum += value;
sumSquared += (value*value);
values.insert(value);
}
/** add all values from the given statistics instance */
void add(const Statistics<T>& other) {
for (const T val : other.values) {
this->add(val);
}
}
/** get the std-dev of all values */
T getStdDev() const {
double E1 = sumSquared / (double) cnt;
double E2 = getAvg();
return std::sqrt(E1 - (E2*E2));
}
/** get average value */
T getAvg() const {
return sum / (double) cnt;
}
T getSquaredSumAvg() const {
return sumSquared / (double)cnt;
}
/** get the given quantile (e.g. 0.5 for median) */
T getQuantile(const double q) const {
if (q < 0) {return *values.begin();}
if (q >= 1) {return *(--values.end());}
uint32_t pos = cnt * q;
uint32_t curPos = 0;
for (auto val : values) {
if (curPos == pos) {return val;}
++curPos;
}
return -1;
}
/** get the median value (= Quantile 0.5) */
T getMedian() const {
return getQuantile(0.5f);
}
/** get smallest value */
T getMin() const {
if (values.empty()) {return -1;}
return *(values.begin());
}
/** get largest value */
T getMax() const {
if (values.empty()) {return -1;}
return *(--values.end());
}
/** get the range between min an max */
T getRange() const {
return getMax() - getMin();
}
/** get the squared sum */
T getSquaredSum() const {
return sumSquared;
}
/** get the sum of all values */
T getSum() const {
return sum;
}
/** get number of stored values */
uint32_t getCount() const {
return cnt;
}
/** get the number of values that are below "val" */
T getNumValuesBelow(uint32_t val) const {
uint32_t numFound = 0;
for (auto curVal : values) {
if (curVal > val) {return numFound;}
++numFound;
}
return numFound;
}
/** get all contained values in ascending order */
const std::multiset<T>& getAll() const {
return values;
}
/** get as string */
std::string asString() const {
std::stringstream ss;
appendTo(ss);
return ss.str();
}
/** send to the given stream */
void appendTo(std::ostream& out) const {
out.precision(6);
out.setf( std::ios::fixed, std:: ios::floatfield );
out << "cnt(" << getCount() << ")\t";
out << "min(" << getMin() << ")\t";
out << "max(" << getMax() << ")\t";
out << "range(" << getRange() << ")\t";
out << "med(" << getMedian() << ")\t";
out << "avg(" << getAvg() << ")\t";
out << "stdDev(" << getStdDev() << ")\t";
}
/** send to stream */
inline std::ostream& operator << (std::ostream& out) const {
appendTo(out); return out;
}
/** reset all statistics */
void reset() {
sum = T();
sumSquared = T();
cnt = 0;
values.clear();
}
private:
/** sum of all added values */
T sum;
/** squared sum of all added values (for std-dev) */
T sumSquared;
/** the number of added values */
uint32_t cnt;
/** multiset to sort all values */
std::multiset<T> values;
};
}
#endif // STATISTICS_H