Files
pip/libs/main/math/pistatistic.h
2026-03-12 14:46:57 +03:00

126 lines
4.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.
//! \~\ingroup Math
//! \~\file pistatistic.h
//! \brief
//! \~english Calculating math statistic of values array
//! \~russian Вычисление математической статистики у массива чисел
/*
PIP - Platform Independent Primitives
Calculating math statistic of 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"
//! \~\ingroup Math
//! \~\brief
//! \~english Template class for calculating statistical measures of a data set
//! \~russian Шаблонный класс для вычисления статистических характеристик набора данных
//! \details
//! \~english Calculates mean, variance, skewness and kurtosis for a numeric sample.
//! \~russian Вычисляет среднее, дисперсию, асимметрию и эксцесс для числовой выборки.
template<typename T>
class PIStatistic {
static_assert(std::is_arithmetic<T>::value, "Type must be arithmetic");
public:
//! \~english Constructs an object with all accumulated values set to zero.
//! \~russian Создает объект со всеми накопленными значениями, равными нулю.
PIStatistic() { mean = variance = skewness = kurtosis = T(); }
//! \~english Returns arithmetic mean of the sample, or zero for an empty vector.
//! \~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;
}
//! \~english Calculates all statistics using the supplied mean value.
//! \~russian Вычисляет всю статистику, используя переданное среднее значение.
//! \~\details
//! \~english Returns \c false when the sample contains fewer than two values.
//! \~russian Возвращает \c false, если в выборке меньше двух значений.
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;
}
//! \~english Calculates all statistics and derives the mean from the sample.
//! \~russian Вычисляет всю статистику, определяя среднее по самой выборке.
bool calculate(const PIVector<T> & val) { return calculate(val, calculateMean(val)); }
//! \~english Sample mean.
//! \~russian Среднее значение выборки.
T mean;
//! \~english Variance estimate accumulated for the sample.
//! \~russian Оценка дисперсии, вычисленная по выборке.
T variance;
//! \~english Sample skewness.
//! \~russian Асимметрия выборки.
T skewness;
//! \~english Excess kurtosis of the sample.
//! \~russian Эксцесс выборки.
T kurtosis;
};
//! \~english Integer statistics helper.
//! \~russian Вспомогательный тип статистики для целых чисел.
typedef PIStatistic<int> PIStatistici;
//! \~english Single-precision statistics helper.
//! \~russian Вспомогательный тип статистики одинарной точности.
typedef PIStatistic<float> PIStatisticf;
//! \~english Double-precision statistics helper.
//! \~russian Вспомогательный тип статистики двойной точности.
typedef PIStatistic<double> PIStatisticd;
#endif // PISTATISTIC_H