mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.1.1 RunAvgWeight
This commit is contained in:
parent
272cd7e583
commit
bb4a166b98
@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
|
||||
## [0.1.1] - 2024-07-01
|
||||
- update documentation
|
||||
- sync order of functions in .h and .cpp
|
||||
- minor edits
|
||||
|
||||
## [0.1.0] - 2024-06-30
|
||||
- initial version, based upon **RunningAverage**
|
||||
|
||||
|
@ -18,22 +18,23 @@ Arduino library to calculate the running average with weights by means of a circ
|
||||
|
||||
**Experimental**
|
||||
|
||||
The RunAvgWeight (RAW) object gives a running average of the last N floating point numbers,
|
||||
The RunAvgWeight object gives a running average of the last N floating point numbers,
|
||||
while giving them a different weight.
|
||||
|
||||
This is done by adding new data to internal circular buffers, removing the oldest and
|
||||
replace it by the newest.
|
||||
The size of the internal buffer can be set in the constructor.
|
||||
This is done by adding the new data to the internal circular buffers, removing the oldest
|
||||
and replace them by the newest.
|
||||
The size of the internal buffers must be set in the constructor.
|
||||
|
||||
The interface of the RunAvgWeight object is strongly based upon **RunningAverage**.
|
||||
However not all functions are implemented.
|
||||
Note the **RunningAverage** library uses no weights.
|
||||
|
||||
**Warning**
|
||||
|
||||
However the constant adding and subtracting when adding new elements to the RAW object
|
||||
possibly introduces an ever increasing error.
|
||||
In tests with **RunningAverage** class with equal weights, adding up to 1500000 numbers
|
||||
this error was always small. Be aware of this.
|
||||
In tests with **RunningAverage** library (with equal weights), adding up to 1500000 numbers
|
||||
this error was always small. Still you need to be aware of this limit.
|
||||
|
||||
|
||||
#### Related
|
||||
@ -58,42 +59,57 @@ this error was always small. Be aware of this.
|
||||
|
||||
### Constructor
|
||||
|
||||
- **RunAvgWeight(uint16_t size)** allocates dynamic memory, one float (4 bytes) per element.
|
||||
No default size (yet).
|
||||
- **RunAvgWeight(uint16_t size)** allocates dynamic memory, two floats (8 bytes) per element.
|
||||
The object has no default size.
|
||||
- **~RunAvgWeight()** destructor to free the memory allocated.
|
||||
|
||||
|
||||
### Basic
|
||||
|
||||
- **void clear()** empties the internal buffers.
|
||||
- **void addValue(float value, float weight)** adds a new value to the object,
|
||||
- **void addValue(float value, float weight = 1.0)** adds a new value to the object,
|
||||
if the internal buffer is full, the oldest element is removed.
|
||||
The default weight is 1.0 so one can use this class as a "unweighted" running average too,
|
||||
albeit with the extra overhead.
|
||||
**addValue()** updates the sum of values and weights for the **getFastAverage()** function.
|
||||
- **float getValue(uint16_t position)** returns the value at **position** from the additions.
|
||||
Position 0 is the first one to disappear.
|
||||
- **float getAverage()** iterates over all elements to get the average, slower but accurate.
|
||||
Updates the variables used by **getFastAverage()** to improve its accuracy again.
|
||||
- **float getWeight(uint16_t position)** returns the weight at **position** from the additions.
|
||||
Position 0 is the first one to disappear.
|
||||
- **float getAverage()** iterates over all elements, values and weights, to get the average.
|
||||
This is the slower and the more accurate method.
|
||||
A call to **getAverage()** updates the internal variables used by **getFastAverage()** to
|
||||
improve its accuracy again.
|
||||
- **float getFastAverage()** reuses previous calculated values, therefore faster. Accuracy can drift.
|
||||
|
||||
|
||||
### Extended functions
|
||||
|
||||
- **float getStandardDeviation()** returns the standard deviation of the current content.
|
||||
Needs more than one element to be calculable.
|
||||
More than one element needs to be added to be calculable.
|
||||
- **float getStandardError()** returns the standard error of the current content.
|
||||
- **float getMin()** returns minimum since last clear, does not need to be in the buffer any more.
|
||||
- **float getMax()** returns maximum since last clear, does not need to be in the buffer any more.
|
||||
- **float getMinInBuffer()** returns minimum in the internal buffer.
|
||||
- **float getMaxInBuffer()** returns maximum in the internal buffer.
|
||||
- **float getMin()** returns minimum value since last **clear()**. This value does not need
|
||||
to be in the internal buffer any more. Useful for graphing long term minima.
|
||||
- **float getMax()** returns maximum value since last **clear()**. This value does not need
|
||||
to be in the internal buffer any more. Useful for graphing long term maxima.
|
||||
- **float getMinInBuffer()** returns minimum value in the internal buffer.
|
||||
- **float getMaxInBuffer()** returns maximum value in the internal buffer.
|
||||
|
||||
|
||||
### Admin functions
|
||||
|
||||
- **bool bufferIsFull()** returns true if buffer is full.
|
||||
- **float getElement(uint16_t index)** get element directly from internal buffer at index. (debug)
|
||||
- **uint16_t getSize()** returns the size of the internal array.
|
||||
- **uint16_t getCount()** returns the number of slots used of the internal array.
|
||||
|
||||
|
||||
### Helper functions
|
||||
|
||||
- **float getElementValue(uint16_t index)** get element directly from internal buffer at index.
|
||||
- **float getElementValue(uint16_t index)** get element directly from internal buffer at index.
|
||||
- **float getSumValues()** returns the sum of the values \* weights in the internal buffer.
|
||||
- **float getSumWeights()** returns the sum of the values in the internal buffer.
|
||||
|
||||
|
||||
## Future
|
||||
|
||||
@ -108,6 +124,8 @@ Needs more than one element to be calculable.
|
||||
|
||||
#### Could
|
||||
|
||||
- implement missing RunningAverage functions?
|
||||
|
||||
#### Wont
|
||||
|
||||
## Support
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// FILE: RunAvgWeight.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// VERSION: 0.1.1
|
||||
// DATE: 2024-06-30
|
||||
// PURPOSE: Arduino library to calculate the running average with weights by means of a circular buffer
|
||||
// URL: https://github.com/RobTillaart/RunAvgWeight
|
||||
@ -41,8 +41,9 @@ void RunAvgWeight::clear()
|
||||
_max = NAN;
|
||||
for (uint16_t i = _size; i > 0; )
|
||||
{
|
||||
_values[--i] = 0.0; // keeps addValue simpler
|
||||
_weights[--i] = 0.0; // keeps addValue simpler
|
||||
// setting values and weight to zero keeps addValue simpler
|
||||
_values[--i] = 0.0;
|
||||
_weights[--i] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,63 +143,6 @@ float RunAvgWeight::getFastAverage()
|
||||
}
|
||||
|
||||
|
||||
// returns the minimum value in the buffer
|
||||
float RunAvgWeight::getMinInBuffer()
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
return NAN;
|
||||
}
|
||||
|
||||
float _min = _values[0];
|
||||
for (uint16_t i = 1; i < _count; i++)
|
||||
{
|
||||
if (_values[i] < _min) _min = _values[i];
|
||||
}
|
||||
return _min;
|
||||
}
|
||||
|
||||
|
||||
// returns the maximum value in the buffer
|
||||
float RunAvgWeight::getMaxInBuffer()
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
return NAN;
|
||||
}
|
||||
|
||||
float _max = _values[0];
|
||||
for (uint16_t i = 1; i < _count; i++)
|
||||
{
|
||||
if (_values[i] > _max) _max = _values[i];
|
||||
}
|
||||
return _max;
|
||||
}
|
||||
|
||||
|
||||
// returns the value of an element if exist, NAN otherwise
|
||||
float RunAvgWeight::getElementValue(uint16_t index)
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
return NAN;
|
||||
}
|
||||
return _values[index];
|
||||
}
|
||||
|
||||
|
||||
// returns the value of an element if exist, NAN otherwise
|
||||
float RunAvgWeight::getElementWeight(uint16_t index)
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
return NAN;
|
||||
}
|
||||
return _weights[index];
|
||||
}
|
||||
|
||||
|
||||
|
||||
// What is standard deviation in weighted average context?
|
||||
// https://en.wikipedia.org/wiki/Weighted_arithmetic_mean#Weighted_sample_variance
|
||||
//
|
||||
@ -249,5 +193,68 @@ float RunAvgWeight::getStandardError()
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// returns the minimum value in the buffer
|
||||
float RunAvgWeight::getMinInBuffer()
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
return NAN;
|
||||
}
|
||||
|
||||
float _min = _values[0];
|
||||
for (uint16_t i = 1; i < _count; i++)
|
||||
{
|
||||
if (_values[i] < _min) _min = _values[i];
|
||||
}
|
||||
return _min;
|
||||
}
|
||||
|
||||
|
||||
// returns the maximum value in the buffer
|
||||
float RunAvgWeight::getMaxInBuffer()
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
return NAN;
|
||||
}
|
||||
|
||||
float _max = _values[0];
|
||||
for (uint16_t i = 1; i < _count; i++)
|
||||
{
|
||||
if (_values[i] > _max) _max = _values[i];
|
||||
}
|
||||
return _max;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// HELPER FUNCTIONS
|
||||
//
|
||||
|
||||
// returns the value of an element if exist, NAN otherwise
|
||||
float RunAvgWeight::getElementValue(const uint16_t index)
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
return NAN;
|
||||
}
|
||||
return _values[index];
|
||||
}
|
||||
|
||||
|
||||
// returns the value of an element if exist, NAN otherwise
|
||||
float RunAvgWeight::getElementWeight(const uint16_t index)
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
return NAN;
|
||||
}
|
||||
return _weights[index];
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// FILE: RunAvgWeight.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// VERSION: 0.1.1
|
||||
// DATE: 2024-06-30
|
||||
// PURPOSE: Arduino library to calculate the running average with weights by means of a circular buffer
|
||||
// URL: https://github.com/RobTillaart/RunAvgWeight
|
||||
@ -13,7 +13,7 @@
|
||||
#include "Arduino.h"
|
||||
|
||||
|
||||
#define RUNAVGWEIGHT_LIB_VERSION (F("0.1.0"))
|
||||
#define RUNAVGWEIGHT_LIB_VERSION (F("0.1.1"))
|
||||
|
||||
|
||||
class RunAvgWeight
|
||||
@ -51,17 +51,17 @@ public:
|
||||
|
||||
// return true if buffer is full
|
||||
bool bufferIsFull() { return _count == _size; };
|
||||
|
||||
// helper functions.
|
||||
float getElementValue(uint16_t index);
|
||||
float getElementWeight(uint16_t index);
|
||||
float getSumValues() { return _sumValues; };
|
||||
float getSumWeights() { return _sumWeights; };
|
||||
|
||||
uint16_t getSize() { return _size; }
|
||||
uint16_t getCount() { return _count; }
|
||||
|
||||
|
||||
// helper functions.
|
||||
float getElementValue(const uint16_t index);
|
||||
float getElementWeight(const uint16_t index);
|
||||
float getSumValues() { return _sumValues; };
|
||||
float getSumWeights() { return _sumWeights; };
|
||||
|
||||
|
||||
protected:
|
||||
uint16_t _size;
|
||||
uint16_t _count;
|
||||
|
@ -15,7 +15,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/RunAvgWeight.git"
|
||||
},
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"license": "MIT",
|
||||
"frameworks": "*",
|
||||
"platforms": "*",
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=RunAvgWeight
|
||||
version=0.1.0
|
||||
version=0.1.1
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Running Average with weight of N elements.
|
||||
|
Loading…
Reference in New Issue
Block a user