126 lines
4.9 KiB
C++
126 lines
4.9 KiB
C++
//! \~\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
|