mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.2.0 RunAvgWeight
This commit is contained in:
parent
0879f2ca2a
commit
6a8bad8500
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
@ -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!
|
||||||
|
@ -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");
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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": "*",
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user