You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

188 lines
4.2 KiB

  1. #include <corestats.h>
  2. #include <Arduino.h>
  3. #include <limits.h>
  4. #include <math.h>
  5. #include <float.h>
  6. // //////////////////////////////////////////////////////////////////////////
  7. // //////////////////////////////////////////////////////////////////////////
  8. float Stats::stddev() const {
  9. return sqrt(var());
  10. }
  11. float Stats::normalize(float value) const {
  12. return ( value - mean() ) / (stddev() + FLT_MIN);
  13. }
  14. SimpleStats::SimpleStats(float startMean, float startVar) {
  15. reset(startMean, startVar);
  16. }
  17. void SimpleStats::reset(float startMean, float startVar) {
  18. _mean = startMean;
  19. _mean2 = startVar + sq(_mean);
  20. _nSamples = 0;
  21. // _min = FLT_MAX;
  22. // _max = -FLT_MAX;
  23. }
  24. float SimpleStats::update(float value) {
  25. if (_nSamples == ULONG_MAX)
  26. _nSamples = (ULONG_MAX / 4) * 3; // simple trick that makes sure we don't overflow
  27. // Add one to number of samples
  28. _nSamples++;
  29. // Update mean and mean2
  30. float prop = (float)(_nSamples-1) / (float)_nSamples;
  31. _mean = _mean * prop + value / _nSamples;
  32. _mean2 = _mean2 * prop + sq(value) / _nSamples;
  33. // Update min and max
  34. // _min = min(_min, value);
  35. // _max = max(_max, value);
  36. return normalize(value);
  37. }
  38. float SimpleStats::var() const {
  39. float v = (_mean2 - sq(_mean));
  40. return max(v, (float)0); // make sure the result is >= 0
  41. }
  42. // //////////////////////////////////////////////////////////////////////////
  43. // //////////////////////////////////////////////////////////////////////////
  44. MovingAverage::MovingAverage(float alphaOrN) : _value(0.5f) {
  45. setAlphaOrN(alphaOrN);
  46. reset();
  47. }
  48. MovingAverage::MovingAverage(float alphaOrN, float startValue) : _value(startValue) {
  49. setAlphaOrN(alphaOrN);
  50. }
  51. void MovingAverage::setAlphaOrN(float alphaOrN)
  52. {
  53. alphaOrN = max(alphaOrN, 0); // make sure factor >= 0
  54. _alpha = (alphaOrN > 1 ?
  55. 2 / (alphaOrN + 1) :
  56. alphaOrN);
  57. }
  58. void MovingAverage::reset() {
  59. _setStarted(false);
  60. }
  61. void MovingAverage::reset(float startValue) {
  62. _value = startValue;
  63. _setStarted(true);
  64. }
  65. float MovingAverage::update(float v) {
  66. if (!isStarted()) {
  67. _value = v;
  68. _setStarted(true); // start
  69. return _value;
  70. }
  71. else
  72. return (_value -= _alpha * (_value - v));
  73. }
  74. bool MovingAverage::isStarted() const {
  75. return _alpha >= 0;
  76. }
  77. void MovingAverage::_setStarted(bool start) {
  78. _alpha = (start ? +1 : -1) * abs(_alpha);
  79. }
  80. MovingStats::MovingStats(float alphaOrN) : avg(alphaOrN) { }
  81. MovingStats::MovingStats(float alphaOrN, float startMean, float startVar)
  82. : avg(alphaOrN, startMean), _var(startVar) {
  83. reset(startMean, startVar);
  84. }
  85. void MovingStats::reset() {
  86. avg.reset();
  87. _var = 0;
  88. }
  89. void MovingStats::reset(float startMean, float startVar) {
  90. avg.reset(startMean);
  91. _var = startVar;
  92. }
  93. float MovingStats::update(float value)
  94. {
  95. avg.update(value);
  96. if (!isStarted())
  97. _var = 0;
  98. else {
  99. float diff = value - avg.get();
  100. _var -= avg.alpha() * (_var - sq(diff));
  101. }
  102. return normalize(value);
  103. }
  104. bool MovingStats::isStarted() const {
  105. return avg.isStarted();
  106. }
  107. // //////////////////////////////////////////////////////////////////////////
  108. // //////////////////////////////////////////////////////////////////////////
  109. AdaptiveNormalizer::AdaptiveNormalizer(float smoothFactor)
  110. : MovingStats(smoothFactor),
  111. _value(0.5f),
  112. _mean(0.5f),
  113. _stddev(0.25f)
  114. {}
  115. AdaptiveNormalizer::AdaptiveNormalizer(float mean, float stddev, float smoothFactor)
  116. : MovingStats(smoothFactor),
  117. _value(mean),
  118. _mean(mean),
  119. _stddev(abs(stddev))
  120. {}
  121. float AdaptiveNormalizer::put(float value) {
  122. return (_value = MovingStats::update(value) * _stddev + _mean);
  123. }
  124. Normalizer::Normalizer()
  125. : SimpleStats(),
  126. _value(0.5f),
  127. _mean(0.5f),
  128. _stddev(0.25f)
  129. {}
  130. Normalizer::Normalizer(float mean, float stddev)
  131. : SimpleStats(),
  132. _value(mean),
  133. _mean(mean),
  134. _stddev(abs(stddev))
  135. {}
  136. float Normalizer::put(float value) {
  137. return (_value = SimpleStats::update(value) * _stddev + _mean);
  138. }
  139. MinMaxScaler::MinMaxScaler()
  140. : _value(0.5f),
  141. _minValue(FLT_MAX),
  142. _maxValue(FLT_MIN)
  143. {}
  144. float MinMaxScaler::put(float value)
  145. {
  146. _minValue = min(value, _minValue);
  147. _maxValue = max(value, _maxValue);
  148. _value = (_minValue == _maxValue ? 0.5f : map(value, _minValue, _maxValue, 0.0f, 1.0f));
  149. return _value;
  150. }