0.1.1 RunAvgWeight

This commit is contained in:
Rob Tillaart 2024-07-02 13:06:07 +02:00
parent 272cd7e583
commit bb4a166b98
6 changed files with 118 additions and 88 deletions

View File

@ -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**

View File

@ -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

View File

@ -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 --

View 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;

View File

@ -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": "*",

View File

@ -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.