0.2.0 RunAvgWeight

This commit is contained in:
Rob Tillaart 2024-08-19 20:34:31 +02:00
parent 0879f2ca2a
commit 6a8bad8500
8 changed files with 98 additions and 33 deletions

View File

@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/) The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/). and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.2.0] - 2024-08-12
- Fix #6, **float getFastAverage()** => fix **clear()**
- Fix #4, add **float getCoefficientOfVariation()**
- add bool return value for **clear(), addValue()**
- update readme.md
- update keywords.txt
----
## [0.1.1] - 2024-07-01 ## [0.1.1] - 2024-07-01
- update documentation - update documentation

View File

@ -36,6 +36,10 @@ possibly introduces an ever increasing error.
In tests with **RunningAverage** library (with equal weights), adding up to 1500000 numbers 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. this error was always small. Still you need to be aware of this limit.
### 0.2.0 breaking change
Fixed #6 by fixing **clear()**, previous versions are now obsolete.
#### Related #### Related
@ -49,6 +53,7 @@ this error was always small. Still you need to be aware of this limit.
- https://github.com/RobTillaart/statHelpers - combinations & permutations - https://github.com/RobTillaart/statHelpers - combinations & permutations
- https://github.com/RobTillaart/printHelpers - print scientific format - https://github.com/RobTillaart/printHelpers - print scientific format
- https://github.com/RobTillaart/Statistic - https://github.com/RobTillaart/Statistic
- https://github.com/RobTillaart/Student
## Interface ## Interface
@ -66,12 +71,17 @@ The object has no default size.
### Basic ### Basic
- **void clear()** empties the internal buffers. - **bool clear()** empties the internal buffers.
- **void addValue(float value, float weight = 1.0)** adds a new value to the object, - **bool 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. 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, The default weight is 1.0 so one can use this class as a "unweighted" running average too,
albeit with the extra overhead. albeit with the extra overhead.
**addValue()** updates the sum of values and weights for the **getFastAverage()** function. **addValue()** updates the sum of values and weights for the **getFastAverage()** function.
The following functions returns NAN if there are no values present (count == 0) or
of internal array is not allocated.
- **float getValue(uint16_t position)** returns the value at **position** from the additions. - **float getValue(uint16_t position)** returns the value at **position** from the additions.
Position 0 is the first one to disappear. Position 0 is the first one to disappear.
- **float getWeight(uint16_t position)** returns the weight at **position** from the additions. - **float getWeight(uint16_t position)** returns the weight at **position** from the additions.
@ -88,12 +98,20 @@ improve its accuracy again.
- **float getStandardDeviation()** returns the standard deviation of the current content. - **float getStandardDeviation()** returns the standard deviation of the current content.
More than one element needs to be added 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 getStandardError()** returns the standard error of the current content.
- **float getCoefficientOfVariation()** returns coefficient of variation.
This is defined as standardDeviation / Average.
It indicates if the distribution is relative small ( < 1) or relative wide ( > 1).
Note it has no meaning when the average is zero (or close to zero).
- **float getMin()** returns minimum value since last **clear()**. This value does not need - **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. to be in the internal buffer any more. Useful for graphing long term minima.
Note the returned minimum is **unweighted.**
- **float getMax()** returns maximum value since last **clear()**. This value does not need - **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. to be in the internal buffer any more. Useful for graphing long term maxima.
Note the returned maximum is **unweighted.**
- **float getMinInBuffer()** returns minimum value in the internal buffer. - **float getMinInBuffer()** returns minimum value in the internal buffer.
Note the returned minimum is **unweighted.**
- **float getMaxInBuffer()** returns maximum value in the internal buffer. - **float getMaxInBuffer()** returns maximum value in the internal buffer.
Note the returned maximum is **unweighted.**
### Admin functions ### Admin functions

View File

@ -1,7 +1,7 @@
// //
// FILE: RunAvgWeight.cpp // FILE: RunAvgWeight.cpp
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.1.1 // VERSION: 0.2.0
// DATE: 2024-06-30 // DATE: 2024-06-30
// PURPOSE: Arduino library to calculate the running average with weights by means of a circular buffer // PURPOSE: Arduino library to calculate the running average with weights by means of a circular buffer
// URL: https://github.com/RobTillaart/RunAvgWeight // URL: https://github.com/RobTillaart/RunAvgWeight
@ -31,7 +31,7 @@ RunAvgWeight::~RunAvgWeight()
// resets all counters // resets all counters
void RunAvgWeight::clear() bool RunAvgWeight::clear()
{ {
_count = 0; _count = 0;
_index = 0; _index = 0;
@ -39,41 +39,49 @@ void RunAvgWeight::clear()
_sumWeights = 0.0; _sumWeights = 0.0;
_min = NAN; _min = NAN;
_max = NAN; _max = NAN;
for (uint16_t i = _size; i > 0; ) if (_size == 0)
{ {
// setting values and weight to zero keeps addValue simpler return false;
_values[--i] = 0.0;
_weights[--i] = 0.0;
} }
for (uint16_t i = 0; i < _size; i++)
{
// setting values and weights to zero keeps addValue simpler
_values[i] = 0.0;
_weights[i] = 0.0;
}
return true;
} }
// adds a new value to the data-set // adds a new value to the data-set
void RunAvgWeight::addValue(const float value, const float weight) bool RunAvgWeight::addValue(const float value, const float weight)
{ {
if ((_values == NULL) || (_weights == NULL)) if (_size == 0)
{ {
return; return false;
} }
// TODO weight should be > 0 or at least != 0?
_sumValues -= _values[_index]; _sumValues -= _values[_index] * _weights[_index];
_values[_index] = value; _values[_index] = value;
_sumValues += _values[_index]; _sumValues += _values[_index] * weight;
_sumWeights -= _weights[_index]; _sumWeights -= _weights[_index];
_weights[_index] = weight; _weights[_index] = weight;
_sumWeights += _weights[_index]; _sumWeights += _weights[_index];
_index++;
if (_index == _size) _index = 0; // faster than % // update index (next spot to add value).
_index++;
if (_index >= _size) _index = 0; // faster than %
// update count
if (_count < _size) _count++;
// handle min max // handle min max
if (_count == 0) _min = _max = value; if (_count == 1) _min = _max = value;
else if (value < _min) _min = value; else if (value < _min) _min = value;
else if (value > _max) _max = value; else if (value > _max) _max = value;
// update count as last otherwise if ( _count == 0) above will fail return true;
if (_count < _size) _count++;
} }
@ -193,6 +201,20 @@ float RunAvgWeight::getStandardError()
} }
// Return coefficient of variation.
// If buffer is empty or has only one element or zero average, return NAN.
float RunAvgWeight::getCoefficientOfVariation()
{
float temp = getStandardDeviation();
if (temp == NAN) return NAN;
if (_sumValues == 0) return NAN;
// float cv = temp * getFastAverage();
float cv = temp * _sumWeights / _sumValues;
return cv;
}
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////

View File

@ -2,7 +2,7 @@
// //
// FILE: RunAvgWeight.h // FILE: RunAvgWeight.h
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.1.1 // VERSION: 0.2.0
// DATE: 2024-06-30 // DATE: 2024-06-30
// PURPOSE: Arduino library to calculate the running average with weights by means of a circular buffer // PURPOSE: Arduino library to calculate the running average with weights by means of a circular buffer
// URL: https://github.com/RobTillaart/RunAvgWeight // URL: https://github.com/RobTillaart/RunAvgWeight
@ -13,7 +13,7 @@
#include "Arduino.h" #include "Arduino.h"
#define RUNAVGWEIGHT_LIB_VERSION (F("0.1.1")) #define RUNAVGWEIGHT_LIB_VERSION (F("0.2.0"))
class RunAvgWeight class RunAvgWeight
@ -22,8 +22,8 @@ public:
explicit RunAvgWeight(const uint16_t size); explicit RunAvgWeight(const uint16_t size);
~RunAvgWeight(); ~RunAvgWeight();
void clear(); bool clear();
void addValue(const float value, const float weight = 1.0); bool addValue(const float value, const float weight = 1.0);
float getValue(const uint16_t position); float getValue(const uint16_t position);
float getWeight(const uint16_t position); float getWeight(const uint16_t position);
@ -38,6 +38,7 @@ public:
// weight <> 1 // weight <> 1
float getStandardDeviation(); float getStandardDeviation();
float getStandardError(); float getStandardError();
float getCoefficientOfVariation();
// returns min/max added to the data-set since last clear. // returns min/max added to the data-set since last clear.
// values without weight! // values without weight!

View File

@ -29,7 +29,21 @@ void setup(void)
float value = i * 0.01 + 1; float value = i * 0.01 + 1;
float weight = sqrt(i); float weight = sqrt(i);
myRA.addValue(value, weight); myRA.addValue(value, weight);
Serial.print(myRA.bufferIsFull());
Serial.print(value);
Serial.print("\t");
Serial.print(weight);
Serial.print("\t");
Serial.print(myRA.getCount());
Serial.print("\t");
Serial.print(myRA.getSumValues(), 3);
Serial.print("\t");
Serial.print(myRA.getSumWeights(), 3);
Serial.print("\t\t");
Serial.print(myRA.getFastAverage(), 3);
Serial.print("\t");
Serial.print(myRA.getAverage(), 3);
Serial.println();
} }
Serial.println(); Serial.println();
Serial.println(); Serial.println();
@ -51,10 +65,12 @@ void setup(void)
Serial.println(myRA.getCount()); Serial.println(myRA.getCount());
Serial.println(); Serial.println();
Serial.print("AVG:\t"); // first do fast to see if it is right
Serial.println(myRA.getAverage(), 5); // if done after getAverage() it is same by definition.
Serial.print("AVG(f):\t"); Serial.print("AVG(f):\t");
Serial.println(myRA.getFastAverage(), 5); Serial.println(myRA.getFastAverage(), 5);
Serial.print("AVG:\t");
Serial.println(myRA.getAverage(), 5);
Serial.println(); Serial.println();
Serial.print("STDDEV:\t"); Serial.print("STDDEV:\t");

View File

@ -15,6 +15,7 @@ getAverage KEYWORD2
getFastAverage KEYWORD2 getFastAverage KEYWORD2
getStandardDeviation KEYWORD2 getStandardDeviation KEYWORD2
getStandardError KEYWORD2 getStandardError KEYWORD2
getCoefficientOfVariation KEYWORD2
getMin KEYWORD2 getMin KEYWORD2
getMax KEYWORD2 getMax KEYWORD2
@ -22,15 +23,14 @@ getMinInBuffer KEYWORD2
getMaxInBuffer KEYWORD2 getMaxInBuffer KEYWORD2
bufferIsFull KEYWORD2 bufferIsFull KEYWORD2
getSize KEYWORD2
getCount KEYWORD2
getElementValue KEYWORD2 getElementValue KEYWORD2
getElementWeight KEYWORD2 getElementWeight KEYWORD2
getSumValues KEYWORD2 getSumValues KEYWORD2
getSumWeights KEYWORD2 getSumWeights KEYWORD2
getSize KEYWORD2
getCount KEYWORD2
# Instances (KEYWORD2) # Instances (KEYWORD2)

View File

@ -15,7 +15,7 @@
"type": "git", "type": "git",
"url": "https://github.com/RobTillaart/RunAvgWeight.git" "url": "https://github.com/RobTillaart/RunAvgWeight.git"
}, },
"version": "0.1.1", "version": "0.2.0",
"license": "MIT", "license": "MIT",
"frameworks": "*", "frameworks": "*",
"platforms": "*", "platforms": "*",

View File

@ -1,5 +1,5 @@
name=RunAvgWeight name=RunAvgWeight
version=0.1.1 version=0.2.0
author=Rob Tillaart <rob.tillaart@gmail.com> author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com> maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Running Average with weight of N elements. sentence=Running Average with weight of N elements.