Files
pip/libs/main/math/pistatistic.h

109 lines
3.9 KiB
C++
Raw 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.
//! \addtogroup Math
//! \{
//! \file pistatistic.h
//! \brief
//! \~english Calculating math statistic of values array
//! \~russian Вычисление математической статистики у массива чисел
//! \details
//! \~english Template class for calculating statistical measures of a data set
//! \~russian Шаблонный класс для вычисления статистических характеристик набора данных
//! \}
/*
PIP - Platform Independent Primitives
Class for calculacing math statistic in values array
Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PISTATISTIC_H
#define PISTATISTIC_H
#include "pimathbase.h"
//! Statistical calculator template class
//! \~english Template class for calculating statistical measures (mean, variance, skewness, kurtosis)
//! \~russian Шаблонный класс для вычисления статистических показателей (среднее, дисперсия, асимметрия, эксцесс)
template<typename T>
class PIStatistic {
static_assert(std::is_arithmetic<T>::value, "Type must be arithmetic");
public:
//! Construct empty statistic calculator
PIStatistic() { mean = variance = skewness = kurtosis = T(); }
//! Calculate arithmetic mean
//! \~english Calculate arithmetic mean of values
//! \~russian Вычислить среднее арифметическое значение
static T calculateMean(const PIVector<T> & val) {
T ret = T();
int n = val.size();
if (n < 1) return ret;
for (int i = 0; i < n; i++)
ret += val[i];
return ret / n;
}
//! Calculate all statistics with given mean
//! \~english Calculate variance, skewness and kurtosis using provided mean value
//! \~russian Вычислить дисперсию, асимметрию и эксцесс с использованием заданного среднего значения
bool calculate(const PIVector<T> & val, const T & given_mean) {
T v = T(), v1 = T(), v2 = T(), stddev = T(), var = T();
int i, n = val.size();
mean = given_mean;
if (n < 2) return false;
variance = skewness = kurtosis = T();
// Variance (using corrected two-pass algorithm)
for (i = 0; i < n; i++)
v1 += sqr(val[i] - mean);
for (i = 0; i < n; i++)
v2 += val[i] - mean;
v2 = sqr(v2) / n;
variance = v1 / n;
var = (v1 / n - v2) / (n - 1);
if (var < T()) var = T();
stddev = sqrt(var);
// Skewness and kurtosis
if (stddev != T()) {
for (i = 0; i < n; i++) {
v = (val[i] - mean) / stddev;
v2 = sqr(v);
skewness = skewness + v2 * v;
kurtosis = kurtosis + sqr(v2);
}
skewness /= n;
kurtosis = kurtosis / n - 3.;
}
return true;
}
//! Calculate all statistics
//! \~english Calculate mean, variance, skewness and kurtosis
//! \~russian Вычислить среднее, дисперсию, асимметрию и эксцесс
bool calculate(const PIVector<T> & val) { return calculate(val, calculateMean(val)); }
//! Arithmetic mean
T mean;
//! Variance
T variance;
//! Skewness (third standardized moment)
T skewness;
//! Kurtosis (fourth standardized moment)
T kurtosis;
};
typedef PIStatistic<int> PIStatistici;
typedef PIStatistic<float> PIStatisticf;
typedef PIStatistic<double> PIStatisticd;
#endif // PISTATISTIC_H