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/)
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
- 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
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
@ -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/printHelpers - print scientific format
- https://github.com/RobTillaart/Statistic
- https://github.com/RobTillaart/Student
## Interface
@ -66,12 +71,17 @@ The object has no default size.
### Basic
- **void clear()** empties the internal buffers.
- **void addValue(float value, float weight = 1.0)** adds a new value to the object,
- **bool clear()** empties the internal buffers.
- **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.
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.
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.
Position 0 is the first one to disappear.
- **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.
More than one element needs to be added to be calculable.
- **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
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
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.
Note the returned minimum is **unweighted.**
- **float getMaxInBuffer()** returns maximum value in the internal buffer.
Note the returned maximum is **unweighted.**
### Admin functions

View File

@ -1,7 +1,7 @@
//
// FILE: RunAvgWeight.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.1
// VERSION: 0.2.0
// 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
@ -31,7 +31,7 @@ RunAvgWeight::~RunAvgWeight()
// resets all counters
void RunAvgWeight::clear()
bool RunAvgWeight::clear()
{
_count = 0;
_index = 0;
@ -39,41 +39,49 @@ void RunAvgWeight::clear()
_sumWeights = 0.0;
_min = NAN;
_max = NAN;
for (uint16_t i = _size; i > 0; )
if (_size == 0)
{
// setting values and weight to zero keeps addValue simpler
_values[--i] = 0.0;
_weights[--i] = 0.0;
return false;
}
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
void RunAvgWeight::addValue(const float value, const float weight)
bool RunAvgWeight::addValue(const float value, const float weight)
{
if ((_values == NULL) || (_weights == NULL))
{
return;
}
if (_size == 0)
{
return false;
}
// TODO weight should be > 0 or at least != 0?
_sumValues -= _values[_index];
_sumValues -= _values[_index] * _weights[_index];
_values[_index] = value;
_sumValues += _values[_index];
_sumValues += _values[_index] * weight;
_sumWeights -= _weights[_index];
_weights[_index] = weight;
_sumWeights += _weights[_index];
// update index (next spot to add value).
_index++;
if (_index == _size) _index = 0; // faster than %
if (_index >= _size) _index = 0; // faster than %
// update count
if (_count < _size) _count++;
// handle min max
if (_count == 0) _min = _max = value;
if (_count == 1) _min = _max = value;
else if (value < _min) _min = value;
else if (value > _max) _max = value;
// update count as last otherwise if ( _count == 0) above will fail
if (_count < _size) _count++;
return true;
}
@ -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
// AUTHOR: Rob Tillaart
// VERSION: 0.1.1
// VERSION: 0.2.0
// 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.1"))
#define RUNAVGWEIGHT_LIB_VERSION (F("0.2.0"))
class RunAvgWeight
@ -22,8 +22,8 @@ public:
explicit RunAvgWeight(const uint16_t size);
~RunAvgWeight();
void clear();
void addValue(const float value, const float weight = 1.0);
bool clear();
bool addValue(const float value, const float weight = 1.0);
float getValue(const uint16_t position);
float getWeight(const uint16_t position);
@ -38,6 +38,7 @@ public:
// weight <> 1
float getStandardDeviation();
float getStandardError();
float getCoefficientOfVariation();
// returns min/max added to the data-set since last clear.
// values without weight!

View File

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

View File

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

View File

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

View File

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