mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-04-20 02:40:03 +02:00
159 lines
4.3 KiB
C++
159 lines
4.3 KiB
C++
// SPDX-License-Identifier: LGPL-3.0-or-other
|
|
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
|
#ifndef MOVINGSTAT_H
|
|
#define MOVINGSTAT_H
|
|
|
|
#include <math.h>
|
|
|
|
class MovingStat {
|
|
|
|
/** @short approximated moving average structure */
|
|
public:
|
|
/** constructor
|
|
\param nn number of samples parameter to be used
|
|
*/
|
|
MovingStat(int nn) : n(nn), m_n(0), m_newM(0), m_newM2(0) {}
|
|
// void setPointers(double *me, double *va) {mean=me; var=va;}
|
|
/**
|
|
clears the moving average number of samples parameter, mean and standard
|
|
deviation
|
|
*/
|
|
void Clear() {
|
|
m_n = 0;
|
|
m_newM = 0;
|
|
m_newM2 = 0;
|
|
}
|
|
|
|
/**
|
|
clears the moving average number of samples parameter, mean and standard
|
|
deviation
|
|
*/
|
|
void Set(double val, double rms = 0, int m = -1) {
|
|
if (m >= 0)
|
|
m_n = m;
|
|
else
|
|
m_n = n;
|
|
m_newM = val * m_n;
|
|
SetRMS(rms);
|
|
// cout << "set " << val << " " << m << " " << m_n << " " << m_newM <<
|
|
// endl;
|
|
}
|
|
/**
|
|
clears the moving average number of samples parameter, mean and standard
|
|
deviation
|
|
*/
|
|
void SetRMS(double rms) {
|
|
if (rms <= 0) {
|
|
if (m_n > 0)
|
|
m_newM2 = m_newM * m_newM / m_n;
|
|
else
|
|
m_newM2 = 0;
|
|
// m_n=0;
|
|
} else {
|
|
if (m_n > 0) {
|
|
m_newM2 = (m_n * rms * rms + m_newM * m_newM / m_n);
|
|
} else {
|
|
m_newM2 = (m_n * rms * rms + m_newM * m_newM / n);
|
|
m_n = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
/** sets number of samples parameter
|
|
\param i number of samples parameter to be set
|
|
*/
|
|
|
|
int SetN(int i) {
|
|
if (i >= 1)
|
|
n = i;
|
|
return n;
|
|
};
|
|
|
|
/**
|
|
gets number of samples parameter
|
|
\returns actual number of samples parameter
|
|
*/
|
|
int GetN() { return m_n; };
|
|
|
|
/** calculates the moving average i.e. adds if number of elements is lower
|
|
than number of samples parameter, pushes otherwise \param x value to
|
|
calculate the moving average
|
|
*/
|
|
inline void Calc(double x) {
|
|
if (m_n < n)
|
|
Add(x);
|
|
else
|
|
Push(x);
|
|
}
|
|
/** adds the element to the accumulated average and standard deviation
|
|
\param x value to add
|
|
*/
|
|
inline void Add(double x) {
|
|
m_n++;
|
|
|
|
if (m_n == 1) {
|
|
m_newM = x;
|
|
m_newM2 = x * x;
|
|
} else {
|
|
m_newM = m_newM + x;
|
|
m_newM2 = m_newM2 + x * x;
|
|
}
|
|
}
|
|
|
|
inline void Push(double x) {
|
|
/** adds the element to the accumulated average and squared mean, while
|
|
subtracting the current value of the average and squared average
|
|
\param x value to push
|
|
*/
|
|
if (m_n == 0) {
|
|
m_newM = x;
|
|
m_newM2 = x * x;
|
|
m_n++;
|
|
} else {
|
|
m_newM = m_newM + x - m_newM / m_n;
|
|
m_newM2 = m_newM2 + x * x - m_newM2 / m_n;
|
|
}
|
|
}
|
|
|
|
/** returns the current number of elements of the moving average
|
|
\returns returns the current number of elements of the moving average
|
|
*/
|
|
int NumDataValues() const { return m_n; }
|
|
/** returns the mean, 0 if no elements are inside
|
|
\returns returns the mean
|
|
*/
|
|
inline double Mean() const {
|
|
// cout << "get " << m_n << " " << m_newM << " " << m_newM/m_n <<
|
|
// endl;
|
|
|
|
return (m_n > 0) ? m_newM / m_n : 0.0;
|
|
}
|
|
|
|
/** returns the squared mean, 0 if no elements are inside
|
|
\returns returns the squared average
|
|
*/
|
|
double M2() const { return ((m_n > 1) ? m_newM2 / m_n : 0.0); }
|
|
|
|
/** returns the variance, 0 if no elements are inside
|
|
\returns returns the variance
|
|
*/
|
|
inline double Variance() const {
|
|
return (m_n > 0) ? m_newM2 / m_n - m_newM / m_n * m_newM / m_n : 0.0;
|
|
}
|
|
|
|
/** returns the standard deviation, 0 if no elements are inside
|
|
\returns returns the standard deviation
|
|
*/
|
|
inline double StandardDeviation() const {
|
|
|
|
return sqrt(Variance()); //
|
|
}
|
|
|
|
private:
|
|
int n; /**< number of samples parameter */
|
|
int m_n; /**< current number of elements */
|
|
double m_newM; /**< accumulated average */
|
|
double m_newM2; /**< accumulated squared average */
|
|
};
|
|
#endif
|