75 lines
2.0 KiB
C++
75 lines
2.0 KiB
C++
|
#include "gtl_math_kurt.h"
|
||
|
|
||
|
|
||
|
|
||
|
namespace gtl
|
||
|
{
|
||
|
namespace math
|
||
|
{
|
||
|
kurt::kurt(gtl::analog_data *data)
|
||
|
: analog_value(data)
|
||
|
, _sum(0)
|
||
|
, _mean(0)
|
||
|
, _full_ring(false)
|
||
|
, _prev_data_ptr(-1)
|
||
|
{
|
||
|
_name = "kurtosis";
|
||
|
}
|
||
|
|
||
|
void kurt::before_copying_data(std::vector<qreal>::iterator begin, std::vector<qreal>::iterator end)
|
||
|
{
|
||
|
_sum -= std::accumulate(begin, end, 0.0);
|
||
|
}
|
||
|
|
||
|
void kurt::after_copying_data(std::vector<qreal>::iterator begin, std::vector<qreal>::iterator end)
|
||
|
{
|
||
|
_sum += std::accumulate(begin, end, 0.0);
|
||
|
_mean = _sum/_data.size();
|
||
|
}
|
||
|
|
||
|
void kurt::data_changed()
|
||
|
{
|
||
|
|
||
|
analog_value::data_changed();
|
||
|
|
||
|
if(_prev_data_ptr >= _data_ptr && !_full_ring) _full_ring = true;
|
||
|
else _prev_data_ptr = _data_ptr;
|
||
|
|
||
|
int n = _full_ring ? _data.size() : _data_ptr;
|
||
|
if(n > 3)
|
||
|
{
|
||
|
qreal variance = 0.;
|
||
|
for(int i=0; i<n; i++)
|
||
|
if(_full_ring)
|
||
|
variance += pow((_data[(_data_ptr + i) % _data.size() ] - _mean), 2);
|
||
|
else
|
||
|
variance += pow((_data[i] - _mean), 2);
|
||
|
variance /= n;
|
||
|
|
||
|
qreal sigma = 0;
|
||
|
for(int i=0; i<n; i++)
|
||
|
if(_full_ring)
|
||
|
sigma += pow((_data[(_data_ptr + i) % _data.size() ] - _mean), 4);
|
||
|
else
|
||
|
sigma += pow((_data[i] - _mean), 4);
|
||
|
|
||
|
sigma /= n;
|
||
|
|
||
|
qreal k1 = (qreal)(n*n - 1) / (qreal)((n-2)*(n-3));
|
||
|
qreal k2 = (qreal)((6. / (n + 1.)) - 3.);
|
||
|
|
||
|
_value = k1*(sigma/pow(variance,2) + k2);
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_value = 0;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
emit value_changed();
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|