fix issue #33; refactor; function names to camelCase; marked TODO's

This commit is contained in:
RobTillaart 2017-07-26 21:44:04 +02:00
parent c93b369036
commit 73f892523e
5 changed files with 150 additions and 138 deletions

View File

@ -1,7 +1,7 @@
//
// FILE: RunningAverage.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.2.12
// VERSION: 0.2.13
// DATE: 2015-July-10
// PURPOSE: RunningAverage library for Arduino
//
@ -26,150 +26,162 @@
// http://forum.arduino.cc/index.php?topic=50473
// 0.2.11 - 2015-09-04 added getMaxInBuffer() getMinInBuffer() request (Antoon)
// 0.2.12 - 2016-12-01 added GetStandardDeviation() GetStandardError() BufferIsFull() (V0v1kkk)
// 0.2.13 - 2017-07-26 revert double to float - issue #33;
// refactored a bit; marked some TODO's; all function names to camelCase
//
// Released to the public domain
//
#include "RunningAverage.h"
#include <stdlib.h>
#include <math.h>
RunningAverage::RunningAverage(const uint8_t size)
{
_size = size;
_ar = (double*) malloc(_size * sizeof(double));
if (_ar == NULL) _size = 0;
clear();
_size = size;
_ar = (float*) malloc(_size * sizeof(float));
if (_ar == NULL) _size = 0;
clear();
}
RunningAverage::~RunningAverage()
{
if (_ar != NULL) free(_ar);
if (_ar != NULL) free(_ar);
}
// resets all counters
void RunningAverage::clear()
{
_cnt = 0;
_idx = 0;
_sum = 0.0;
_min = NAN;
_max = NAN;
for (uint8_t i = 0; i < _size; i++)
{
_ar[i] = 0.0; // keeps addValue simpler
}
_cnt = 0;
_idx = 0;
_sum = 0.0;
_min = NAN;
_max = NAN;
for (uint8_t i = 0; i < _size; i++)
{
_ar[i] = 0.0; // keeps addValue simpler
}
}
// adds a new value to the data-set
void RunningAverage::addValue(const double value)
void RunningAverage::addValue(const float value)
{
if (_ar == NULL) return; // allocation error
_sum -= _ar[_idx];
_ar[_idx] = value;
_sum += _ar[_idx];
_idx++;
if (_idx == _size) _idx = 0; // faster than %
if (_ar == NULL) return; // allocation error
// handle min max
if (_cnt == 0) _min = _max = value;
else if (value < _min) _min = value;
else if (value > _max) _max = value;
_sum -= _ar[_idx];
_ar[_idx] = value;
_sum += _ar[_idx];
_idx++;
// update count as last otherwise if( _cnt == 0) above will fail
if (_cnt < _size) _cnt++;
if (_idx == _size) _idx = 0; // faster than %
// handle min max
if (_cnt == 0) _min = _max = value;
else if (value < _min) _min = value;
else if (value > _max) _max = value;
// update count as last otherwise if ( _cnt == 0) above will fail
if (_cnt < _size) _cnt++;
}
// returns the average of the data-set added sofar
double RunningAverage::getAverage() const
float RunningAverage::getAverage() const
{
if (_cnt == 0) return NAN;
double sum = 0;
for (uint8_t i = 0; i < _cnt; i++)
{
sum += _ar[i];
}
return sum / _cnt;
if (_cnt == 0) return NAN;
float sum = 0;
for (uint8_t i = 0; i < _cnt; i++)
{
sum += _ar[i];
}
return sum / _cnt;
}
double RunningAverage::getFastAverage() const
float RunningAverage::getFastAverage() const
{
if (_cnt == 0) return NAN;
return _sum / _cnt;
if (_cnt == 0) return NAN;
return _sum / _cnt;
}
// returns the max value in the buffer
double RunningAverage::GetMinInBuffer() const
// returns the minimum value in the buffer
float RunningAverage::getMinInBuffer() const
{
if (_cnt == 0) return NAN;
double min = _ar[0];
for (uint8_t i = 1; i < _cnt; i++)
{
if (min > _ar[i]) min = _ar[i];
}
return min;
if (_cnt == 0) return NAN;
float min = _ar[0];
for (uint8_t i = 1; i < _cnt; i++)
{
if (_ar[i] < min) min = _ar[i];
}
return min;
}
double RunningAverage::GetMaxInBuffer() const
// returns the maximum value in the buffer
float RunningAverage::getMaxInBuffer() const
{
if (_cnt == 0) return NAN;
double max = _ar[0];
for (uint8_t i = 1; i < _cnt; i++)
{
if (max < _ar[i]) max = _ar[i];
}
return max;
if (_cnt == 0) return NAN;
float max = _ar[0];
for (uint8_t i = 1; i < _cnt; i++)
{
if (_ar[i] > max) max = _ar[i];
}
return max;
}
// return true if buffer is full
bool RunningAverage::BufferIsFull() const
{
if (_cnt == _size) return true;
return false;
}
// returns the value of an element if exist, NAN otherwise
double RunningAverage::getElement(uint8_t idx) const
float RunningAverage::getElement(uint8_t idx) const
{
if (idx >=_cnt ) return NAN;
return _ar[idx];
if (idx >=_cnt ) return NAN;
return _ar[idx];
}
// Return standard deviation of running average. If buffer is empty, return NAN.
double RunningAverage::GetStandardDeviation() const
float RunningAverage::getStandardDeviation() const
{
if (_cnt == 0) return NAN;
double temp = 0;
double average = getFastAverage();
for (uint8_t i = 0; i < _cnt; i++)
{
temp += pow((_ar[i] - average),2);
}
temp = sqrt(temp/(_cnt - 1));
return temp;
if (_cnt == 0) return NAN;
float temp = 0;
float average = getFastAverage();
for (uint8_t i = 0; i < _cnt; i++)
{
temp += pow((_ar[i] - average), 2);
}
temp = sqrt(temp/(_cnt - 1)); // TODO possible divide by zero ....
return temp;
}
// Return standard error of running average. If buffer is empty, return NAN.
double RunningAverage::GetStandardError() const //++
float RunningAverage::getStandardError() const //++
{
double temp = GetStandardDeviation();
if(temp==NAN) return NAN;
double n;
if(_cnt>=30) n= _cnt;
else n= _cnt - 1;
temp = temp/sqrt(n);
return temp;
float temp = getStandardDeviation();
if (temp == NAN) return NAN;
float n;
if (_cnt >= 30) n = _cnt;
else n = _cnt - 1; // TODO fails if _cnt == 0
temp = temp/sqrt(n); // TODO fails if _cnt == 1
return temp;
}
// fill the average with a value
// the param number determines how often value is added (weight)
// number should preferably be between 1 and size
void RunningAverage::fillValue(const double value, const uint8_t number)
void RunningAverage::fillValue(const float value, const uint8_t number)
{
clear(); // TODO conditional? if (clr) clear();
clear(); // TODO conditional? if (clr) clear();
for (uint8_t i = 0; i < number; i++)
{
addValue(value);
}
for (uint8_t i = 0; i < number; i++)
{
addValue(value);
}
}
// END OF FILE

View File

@ -1,10 +1,10 @@
//
// FILE: RunningAverage.h
// AUTHOR: Rob dot Tillaart at gmail dot com
// VERSION: 0.2.12
// AUTHOR: Rob.Tillaart@gmail.com
// VERSION: 0.2.13
// DATE: 2016-dec-01
// PURPOSE: RunningAverage library for Arduino
// URL: http://arduino.cc/playground/Main/RunningAverage
// URL: https://github.com/RobTillaart/Arduino/tree/master/libraries/RunningAverage
// HISTORY: See RunningAverage.cpp
//
// Released to the public domain
@ -17,54 +17,54 @@
#ifndef RunningAverage_h
#define RunningAverage_h
#define RUNNINGAVERAGE_LIB_VERSION "0.2.12"
#define RUNNINGAVERAGE_LIB_VERSION "0.2.13"
#include "Arduino.h"
class RunningAverage
{
public:
RunningAverage(void);
explicit RunningAverage(const uint8_t);
~RunningAverage();
RunningAverage(void);
explicit RunningAverage(const uint8_t);
~RunningAverage();
void clear();
void addValue(const double);
void fillValue(const double, const uint8_t);
void clear();
void addValue(const float);
void fillValue(const float, const uint8_t);
double getAverage() const; // does iterate over all elements.
double getFastAverage() const; // reuses previous values.
float getAverage() const; // does iterate over all elements.
float getFastAverage() const; // reuses previous values.
// return statistical characteristics of the running average
double GetStandardDeviation() const;
double GetStandardError() const;
// returns min/max added to the data-set since last clear
double getMin() const { return _min; };
double getMax() const { return _max; };
// return statistical characteristics of the running average
float getStandardDeviation() const;
float getStandardError() const;
// returns min/max from the values in the internal buffer
double GetMinInBuffer() const;
double GetMaxInBuffer() const;
// return true if buffer is full
bool BufferIsFull() const;
// returns min/max added to the data-set since last clear
float getMin() const { return _min; };
float getMax() const { return _max; };
// returns min/max from the values in the internal buffer
float getMinInBuffer() const;
float getMaxInBuffer() const;
// return true if buffer is full
bool bufferIsFull() const { return _cnt == _size; };
float getElement(uint8_t idx) const;
uint8_t getSize() const { return _size; }
uint8_t getCount() const { return _cnt; }
double getElement(uint8_t idx) const;
uint8_t getSize() const { return _size; }
uint8_t getCount() const { return _cnt; }
protected:
uint8_t _size;
uint8_t _cnt;
uint8_t _idx;
double _sum;
double * _ar;
double _min;
double _max;
uint8_t _size;
uint8_t _cnt;
uint8_t _idx;
float _sum;
float* _ar;
float _min;
float _max;
};
#endif

View File

@ -21,7 +21,7 @@ void setup(void)
Serial.println(RUNNINGAVERAGE_LIB_VERSION);
myRA.clear(); // explicitly start clean
Serial.println("\nCNT\tMIN\tMINBUF\tMAX\tMAXBUF");
Serial.println("\nCNT\tMIN\tMINBUF\tMAX\tMAXBUF");
}
void loop(void)
@ -33,9 +33,9 @@ void loop(void)
Serial.print("\t");
Serial.print(myRA.getMin(), 3);
Serial.print("\t");
Serial.print(myRA.GetMinInBuffer(), 3);
Serial.print(myRA.getMinInBuffer(), 3);
Serial.print("\t");
Serial.print(myRA.GetMaxInBuffer(), 3);
Serial.print(myRA.getMaxInBuffer(), 3);
Serial.print("\t");
Serial.print(myRA.getMax(), 3);
Serial.println();

View File

@ -15,18 +15,18 @@ RunningAverage KEYWORD1
clear KEYWORD2
addValue KEYWORD2
getAverage KEYWORD2
getMin KEYWORD2
getMax KEYWORD2
getMin KEYWORD2
getMax KEYWORD2
fillValue KEYWORD2
getElement KEYWORD2
getSize KEYWORD2
getCount KEYWORD2
BufferIsFull() KEYWORD2
bufferIsFull() KEYWORD2
getFastAverage KEYWORD2
GetStandardDeviation KEYWORD2
GetStandardError KEYWORD2
GetMinInBuffer KEYWORD2
GetMaxInBuffer KEYWORD2
getStandardDeviation KEYWORD2
getStandardError KEYWORD2
getMinInBuffer KEYWORD2
getMaxInBuffer KEYWORD2
#######################################
# Instances (KEYWORD2)
@ -37,4 +37,4 @@ GetMaxInBuffer KEYWORD2
# Constants (LITERAL1)
#######################################
RUNNINGAVERAGE_LIB_VERSION LITERAL1
RUNNINGAVERAGE_LIB_VERSION LITERAL1

View File

@ -1,5 +1,5 @@
name=RunningAverage
version=0.2.12
version=0.2.13
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=The library stores the last N individual values in a circular buffer to calculate the running average.