mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-09-19 16:46:11 -04:00
0.3.4 Histogram
This commit is contained in:
parent
4734e016e2
commit
3a488920d6
@ -6,6 +6,18 @@ 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.3.4] - 2023-06-30
|
||||||
|
- change return type **uint8_t clear()**, return status bucket
|
||||||
|
- change return type **uint8_t setBucket(value)**, return status bucket
|
||||||
|
- change return type **uint8_t add(value)**, return status bucket
|
||||||
|
- change return type **uint8_t sub(value)**, return status bucket
|
||||||
|
- add **uint8_t status()** last known status.
|
||||||
|
- add **int32_t sum()**, adds up all buckets.
|
||||||
|
- made **setBucket()** virtual.
|
||||||
|
- update / clean up readme.md
|
||||||
|
- minor improvements derived classes - still experimental
|
||||||
|
|
||||||
|
|
||||||
## [0.3.3] - 2023-02-21
|
## [0.3.3] - 2023-02-21
|
||||||
- optimize loops
|
- optimize loops
|
||||||
- update readme.md
|
- update readme.md
|
||||||
@ -13,7 +25,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
- update license 2023
|
- update license 2023
|
||||||
- minor edits
|
- minor edits
|
||||||
|
|
||||||
|
|
||||||
## [0.3.2] - 2022-11-09
|
## [0.3.2] - 2022-11-09
|
||||||
- add changelog.md
|
- add changelog.md
|
||||||
- add rp2040 to build-CI
|
- add rp2040 to build-CI
|
||||||
|
@ -29,14 +29,14 @@ void setup()
|
|||||||
Serial.print("# buckets: ");
|
Serial.print("# buckets: ");
|
||||||
Serial.println(hist.size());
|
Serial.println(hist.size());
|
||||||
|
|
||||||
for (uint16_t i = 0; i < hist.size()-1; i++)
|
for (uint16_t i = 0; i < hist.size() - 1; i++)
|
||||||
{
|
{
|
||||||
Serial.print("\t");
|
Serial.print("\t");
|
||||||
Serial.print(b[i], 2);
|
Serial.print(b[i], 2);
|
||||||
}
|
}
|
||||||
Serial.println();
|
Serial.println();
|
||||||
|
|
||||||
for (uint16_t i = 0; i < hist.size()-1; i++)
|
for (uint16_t i = 0; i < hist.size() - 1; i++)
|
||||||
{
|
{
|
||||||
Serial.print("\t");
|
Serial.print("\t");
|
||||||
Serial.print(hist.find(b[i]));
|
Serial.print(hist.find(b[i]));
|
||||||
@ -59,7 +59,13 @@ void loop()
|
|||||||
// Serial.print(x);
|
// Serial.print(x);
|
||||||
// Serial.print("\t");
|
// Serial.print("\t");
|
||||||
// Serial.println(hist.find(x));
|
// Serial.println(hist.find(x));
|
||||||
hist.add(x);
|
if (hist.add(x) == false)
|
||||||
|
{
|
||||||
|
Serial.print("ERR: \t");
|
||||||
|
Serial.print(x);
|
||||||
|
Serial.print("\t");
|
||||||
|
Serial.println(hist.find(x));
|
||||||
|
}
|
||||||
|
|
||||||
// update output
|
// update output
|
||||||
uint32_t now = millis();
|
uint32_t now = millis();
|
||||||
|
@ -14,7 +14,7 @@ float bounds[] = { 0, 100, 200, 300, 325, 350, 375, 400, 500, 600, 700, 800, 900
|
|||||||
Histogram hist(14, bounds);
|
Histogram hist(14, bounds);
|
||||||
|
|
||||||
uint32_t lastTime = 0;
|
uint32_t lastTime = 0;
|
||||||
const uint32_t threshold = 1000; // milliseconds, for updating display
|
const uint32_t threshold = 5000; // milliseconds, for updating display
|
||||||
|
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
@ -43,7 +43,7 @@ void loop()
|
|||||||
{
|
{
|
||||||
lastTime = now;
|
lastTime = now;
|
||||||
|
|
||||||
for (int i = 0; i < hist.size(); i++)
|
for (uint16_t i = 0; i < hist.size(); i++)
|
||||||
{
|
{
|
||||||
Serial.print(i);
|
Serial.print(i);
|
||||||
Serial.print("\t");
|
Serial.print("\t");
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// FILE: Histogram.cpp
|
// FILE: Histogram.cpp
|
||||||
// AUTHOR: Rob Tillaart
|
// AUTHOR: Rob Tillaart
|
||||||
// VERSION: 0.3.3
|
// VERSION: 0.3.4
|
||||||
// PURPOSE: Histogram library for Arduino
|
// PURPOSE: Histogram library for Arduino
|
||||||
// DATE: 2012-11-10
|
// DATE: 2012-11-10
|
||||||
|
|
||||||
@ -23,6 +23,8 @@ Histogram::Histogram(const uint16_t length, float *bounds)
|
|||||||
_length = 0;
|
_length = 0;
|
||||||
}
|
}
|
||||||
_count = 0;
|
_count = 0;
|
||||||
|
_status = HISTO_OK;
|
||||||
|
_maxBucket = 2147483647;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -36,45 +38,75 @@ Histogram::~Histogram()
|
|||||||
|
|
||||||
|
|
||||||
// resets all counters to value (default 0)
|
// resets all counters to value (default 0)
|
||||||
void Histogram::clear(int32_t value)
|
uint8_t Histogram::clear(int32_t value)
|
||||||
{
|
{
|
||||||
for (uint16_t i = 0; i < _length; i++)
|
for (uint16_t i = 0; i < _length; i++)
|
||||||
{
|
{
|
||||||
_data[i] = value;
|
_data[i] = value;
|
||||||
}
|
}
|
||||||
_count = 0;
|
_count = 0;
|
||||||
|
_status = HISTO_OK;
|
||||||
|
if (value == _maxBucket) _status = HISTO_FULL;
|
||||||
|
return _status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Histogram::setBucket(const uint16_t index, int32_t value)
|
uint8_t Histogram::setBucket(const uint16_t index, int32_t value)
|
||||||
{
|
{
|
||||||
_data[index] = value;
|
_data[index] = value;
|
||||||
|
_status = HISTO_OK;
|
||||||
|
if (value == _maxBucket) _status = HISTO_FULL;
|
||||||
|
return _status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// adds a new value to the histogram - increasing
|
// adds a new value to the histogram - increasing
|
||||||
void Histogram::add(const float value)
|
uint8_t Histogram::add(const float value)
|
||||||
{
|
{
|
||||||
if (_length > 0)
|
if (_length == 0)
|
||||||
{
|
{
|
||||||
uint16_t index = find(value);
|
_status = HISTO_ERR_LENGTH;
|
||||||
_data[index]++;
|
return _status;
|
||||||
_count++;
|
|
||||||
}
|
}
|
||||||
// return index or count.
|
uint16_t index = find(value);
|
||||||
|
if (_data[index] == _maxBucket)
|
||||||
|
{
|
||||||
|
_status = HISTO_ERR_FULL;
|
||||||
|
return _status;
|
||||||
|
}
|
||||||
|
_data[index]++;
|
||||||
|
_count++;
|
||||||
|
_status = HISTO_OK;
|
||||||
|
if (_data[index] == _maxBucket) _status = HISTO_FULL;
|
||||||
|
return _status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// adds a new value to the histogram - decreasing
|
// adds a new value to the histogram - decreasing
|
||||||
void Histogram::sub(const float value)
|
uint8_t Histogram::sub(const float value)
|
||||||
{
|
{
|
||||||
if (_length > 0)
|
if (_length == 0)
|
||||||
{
|
{
|
||||||
uint16_t index = find(value);
|
_status = HISTO_ERR_LENGTH;
|
||||||
_data[index]--;
|
return _status;
|
||||||
_count++;
|
|
||||||
}
|
}
|
||||||
// return index or count.
|
uint16_t index = find(value);
|
||||||
|
if (_data[index] == -_maxBucket)
|
||||||
|
{
|
||||||
|
_status = HISTO_ERR_FULL;
|
||||||
|
return _status;
|
||||||
|
}
|
||||||
|
_data[index]--;
|
||||||
|
_count++;
|
||||||
|
_status = HISTO_OK;
|
||||||
|
if (_data[index] == _maxBucket) _status = HISTO_FULL;
|
||||||
|
return _status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t Histogram::status()
|
||||||
|
{
|
||||||
|
return _status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -165,6 +197,17 @@ float Histogram::VAL(const float probability)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t Histogram::sum()
|
||||||
|
{
|
||||||
|
int32_t _sum = 0;
|
||||||
|
for (uint16_t i = 0; i < _length; i++)
|
||||||
|
{
|
||||||
|
_sum += _data[i];
|
||||||
|
}
|
||||||
|
return _sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// returns the bucket number for value
|
// returns the bucket number for value
|
||||||
// - binary search, more memory ; faster for #buckets > 20 ?
|
// - binary search, more memory ; faster for #buckets > 20 ?
|
||||||
// uint16_t Histogram::find(const float value)
|
// uint16_t Histogram::find(const float value)
|
||||||
@ -285,18 +328,93 @@ uint16_t Histogram::countBelow(const int32_t level)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// DERIVED CLASS
|
|
||||||
//
|
|
||||||
|
|
||||||
Histogram16::Histogram16(const uint16_t length, float *bounds) : Histogram(length, bounds)
|
// experimental use with care
|
||||||
|
int32_t Histogram::getMaxBucket()
|
||||||
{
|
{
|
||||||
|
return _maxBucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Histogram::setMaxBucket(int32_t value)
|
||||||
|
{
|
||||||
|
_maxBucket = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// DERIVED CLASS - HISTOGRAM16
|
||||||
|
//
|
||||||
|
Histogram16::Histogram16(const uint16_t length, float *bounds) : Histogram(length, bounds)
|
||||||
|
{
|
||||||
|
_bounds = bounds;
|
||||||
|
_length = length + 1;
|
||||||
|
_data = (int16_t *) malloc((_length) * sizeof(int16_t));
|
||||||
|
if (_data != NULL)
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_length = 0;
|
||||||
|
}
|
||||||
|
_count = 0;
|
||||||
|
_status = HISTO_OK;
|
||||||
|
_maxBucket = 32767;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Histogram16::~Histogram16()
|
||||||
|
{
|
||||||
|
if (_data) free(_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t Histogram16::setBucket(const uint16_t index, int16_t value)
|
||||||
|
{
|
||||||
|
_data[index] = value;
|
||||||
|
_status = HISTO_OK;
|
||||||
|
if (value == _maxBucket) _status = HISTO_FULL;
|
||||||
|
return _status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// DERIVED CLASS - HISTOGRAM8
|
||||||
|
//
|
||||||
Histogram8::Histogram8(const uint16_t length, float *bounds) : Histogram(length, bounds)
|
Histogram8::Histogram8(const uint16_t length, float *bounds) : Histogram(length, bounds)
|
||||||
{
|
{
|
||||||
|
_bounds = bounds;
|
||||||
|
_length = length + 1;
|
||||||
|
_data = (int8_t *) malloc((_length) * sizeof(int8_t));
|
||||||
|
if (_data != NULL)
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_length = 0;
|
||||||
|
}
|
||||||
|
_count = 0;
|
||||||
|
_status = HISTO_OK;
|
||||||
|
_maxBucket = 127;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Histogram8::~Histogram8()
|
||||||
|
{
|
||||||
|
if (_data) free(_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t Histogram8::setBucket(const uint16_t index, int8_t value)
|
||||||
|
{
|
||||||
|
_data[index] = value;
|
||||||
|
_status = HISTO_OK;
|
||||||
|
if (value == _maxBucket) _status = HISTO_FULL;
|
||||||
|
return _status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,26 +2,34 @@
|
|||||||
//
|
//
|
||||||
// FILE: Histogram.h
|
// FILE: Histogram.h
|
||||||
// AUTHOR: Rob Tillaart
|
// AUTHOR: Rob Tillaart
|
||||||
// VERSION: 0.3.3
|
// VERSION: 0.3.4
|
||||||
// PURPOSE: Histogram library for Arduino
|
// PURPOSE: Histogram library for Arduino
|
||||||
// DATE: 2012-11-10
|
// DATE: 2012-11-10
|
||||||
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
|
|
||||||
#define HISTOGRAM_LIB_VERSION (F("0.3.3"))
|
#define HISTOGRAM_LIB_VERSION (F("0.3.4"))
|
||||||
|
|
||||||
|
// return STATUS add(), sub(), clear(), setBucket();
|
||||||
|
#define HISTO_OK 0x00 // idem
|
||||||
|
#define HISTO_FULL 0x01 // just got full
|
||||||
|
#define HISTO_ERR_FULL 0xFF // over- underflow
|
||||||
|
#define HISTO_ERR_LENGTH 0xFE // constructor issue.
|
||||||
|
|
||||||
|
|
||||||
class Histogram
|
class Histogram
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Histogram(const uint16_t length, float *bounds);
|
Histogram(const uint16_t length, float * bounds);
|
||||||
~Histogram();
|
~Histogram();
|
||||||
|
|
||||||
void clear(int32_t value = 0);
|
uint8_t clear(int32_t value = 0);
|
||||||
void setBucket(const uint16_t index, int32_t value = 0);
|
uint8_t add(const float value);
|
||||||
void add(const float value);
|
uint8_t sub(const float value);
|
||||||
void sub(const float value);
|
virtual uint8_t setBucket(const uint16_t index, int32_t value = 0);
|
||||||
|
// returns last known status
|
||||||
|
uint8_t status();
|
||||||
|
|
||||||
// number of buckets
|
// number of buckets
|
||||||
uint16_t size();
|
uint16_t size();
|
||||||
@ -36,6 +44,7 @@ public:
|
|||||||
float PMF(const float value);
|
float PMF(const float value);
|
||||||
float CDF(const float value);
|
float CDF(const float value);
|
||||||
float VAL(const float probability);
|
float VAL(const float probability);
|
||||||
|
int32_t sum();
|
||||||
|
|
||||||
uint16_t find(const float value);
|
uint16_t find(const float value);
|
||||||
uint16_t findMin();
|
uint16_t findMin();
|
||||||
@ -44,12 +53,18 @@ public:
|
|||||||
uint16_t countAbove(const int32_t level);
|
uint16_t countAbove(const int32_t level);
|
||||||
uint16_t countBelow(const int32_t level);
|
uint16_t countBelow(const int32_t level);
|
||||||
|
|
||||||
|
// use with care
|
||||||
|
int32_t getMaxBucket();
|
||||||
|
void setMaxBucket(int32_t value);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float * _bounds;
|
float * _bounds;
|
||||||
int32_t * _data;
|
int32_t * _data;
|
||||||
uint16_t _length;
|
uint16_t _length;
|
||||||
uint32_t _count;
|
uint32_t _count;
|
||||||
|
int32_t _maxBucket;
|
||||||
|
uint8_t _status;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -60,8 +75,11 @@ protected:
|
|||||||
class Histogram16 : public Histogram
|
class Histogram16 : public Histogram
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Histogram16(const uint16_t length, float *bounds);
|
Histogram16(const uint16_t length, float * bounds);
|
||||||
~Histogram16();
|
~Histogram16();
|
||||||
|
|
||||||
|
uint8_t setBucket(const uint16_t index, int16_t value = 0);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int16_t * _data;
|
int16_t * _data;
|
||||||
};
|
};
|
||||||
@ -70,8 +88,11 @@ protected:
|
|||||||
class Histogram8 : public Histogram
|
class Histogram8 : public Histogram
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Histogram8(const uint16_t length, float *bounds);
|
Histogram8(const uint16_t length, float * bounds);
|
||||||
~Histogram8();
|
~Histogram8();
|
||||||
|
|
||||||
|
uint8_t setBucket(const uint16_t index, int8_t value = 0);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int8_t * _data;
|
int8_t * _data;
|
||||||
};
|
};
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/RobTillaart/Histogram.git"
|
"url": "https://github.com/RobTillaart/Histogram.git"
|
||||||
},
|
},
|
||||||
"version": "0.3.3",
|
"version": "0.3.4",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"frameworks": "arduino",
|
"frameworks": "arduino",
|
||||||
"platforms": "*",
|
"platforms": "*",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
name=Histogram
|
name=Histogram
|
||||||
version=0.3.3
|
version=0.3.4
|
||||||
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=Arduino library for creating histograms math.
|
sentence=Arduino library for creating histograms math.
|
||||||
|
@ -23,6 +23,18 @@ If you need more quantitative analysis, you might need the statistics library,
|
|||||||
- https://github.com/RobTillaart/Statistic
|
- https://github.com/RobTillaart/Statistic
|
||||||
|
|
||||||
|
|
||||||
|
#### Related
|
||||||
|
|
||||||
|
- https://github.com/RobTillaart/Correlation
|
||||||
|
- https://github.com/RobTillaart/GST - Golden standard test metrics
|
||||||
|
- https://github.com/RobTillaart/Histogram
|
||||||
|
- https://github.com/RobTillaart/RunningAngle
|
||||||
|
- https://github.com/RobTillaart/RunningAverage
|
||||||
|
- https://github.com/RobTillaart/RunningMedian
|
||||||
|
- https://github.com/RobTillaart/statHelpers - combinations & permutations
|
||||||
|
- https://github.com/RobTillaart/Statistic
|
||||||
|
|
||||||
|
|
||||||
#### Working
|
#### Working
|
||||||
|
|
||||||
When the class is initialized an array of the boundaries to define the borders of the
|
When the class is initialized an array of the boundaries to define the borders of the
|
||||||
@ -34,12 +46,13 @@ The values in the boundary array do not need to be equidistant (equal in size)
|
|||||||
but they need to be in ascending order.
|
but they need to be in ascending order.
|
||||||
|
|
||||||
Internally the library does not record the individual values, only the count per bucket.
|
Internally the library does not record the individual values, only the count per bucket.
|
||||||
If a new value is added - **add()** or **sub()** - the class checks in which bucket it
|
If a new value is added - **add(value)** - the class checks in which bucket it
|
||||||
belongs and the buckets counter is increased.
|
belongs and the buckets counter is increased.
|
||||||
|
|
||||||
The **sub()** function is used to decrease the count of a bucket and it can cause the
|
The **sub(value)** function is used to decrease the count of a bucket and it can
|
||||||
count to become below zero. Although seldom used but still depending on the application
|
cause the count to become below zero.
|
||||||
it can be useful. E.g. when you want to compare two value generating streams, you let
|
Although seldom used but still depending on the application it can be useful.
|
||||||
|
E.g. when you want to compare two value generating streams, you let
|
||||||
one stream **add()** and the other **sub()**. If the histogram of both streams is
|
one stream **add()** and the other **sub()**. If the histogram of both streams is
|
||||||
similar they should cancel each other out (more or less), and the value of all buckets
|
similar they should cancel each other out (more or less), and the value of all buckets
|
||||||
should be around 0. \[not tried\].
|
should be around 0. \[not tried\].
|
||||||
@ -75,7 +88,7 @@ the experimental version.
|
|||||||
#include "histogram.h"
|
#include "histogram.h"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Constructor
|
#### Constructor
|
||||||
|
|
||||||
- **Histogram(uint16_t length, float \*bounds)** constructor, get an array of boundary values and array length.
|
- **Histogram(uint16_t length, float \*bounds)** constructor, get an array of boundary values and array length.
|
||||||
Length should be less than 65534.
|
Length should be less than 65534.
|
||||||
@ -86,19 +99,58 @@ Length should be less than 65534.
|
|||||||
- **~Histogram16()** destructor.
|
- **~Histogram16()** destructor.
|
||||||
|
|
||||||
|
|
||||||
### Base
|
#### maxBucket
|
||||||
|
|
||||||
|
Default the maxBucket size is defined as 255 (8 bit), 65535 (16 bit) or
|
||||||
|
2147483647 (32 bit) depending on class used.
|
||||||
|
The functions below allow to set and get the maxBucket so the **add()** and
|
||||||
|
**sub()** function will reach **FULL** faster.
|
||||||
|
Useful in some applications e.g. games.
|
||||||
|
|
||||||
|
- **void setMaxBucket(uint32_t value)** to have a user defined maxBucket level e.g 25
|
||||||
|
- **uint32_t getMaxBucket()** returns the current maxBucket.
|
||||||
|
|
||||||
|
Please note it makes no sense to set maxBucket to a value larger than
|
||||||
|
the histogram type can handle.
|
||||||
|
Setting maxBucket to 300 for **Histogram8** will always fail as data can only
|
||||||
|
handle values between 0 .. 255.
|
||||||
|
|
||||||
|
|
||||||
|
#### Base
|
||||||
|
|
||||||
|
- **uint8_t clear(float value = 0)** reset all bucket counters to value (default 0).
|
||||||
|
Returns status, see below.
|
||||||
|
- **uint8_t setBucket(const uint16_t index, int32_t value = 0)** store / overwrite a value of bucket.
|
||||||
|
Returns status, see below.
|
||||||
|
- **uint8_t add(float value)** add a value, increase count of bucket.
|
||||||
|
Returns status, see below.
|
||||||
|
- **uint8_t sub(float value)** 'add' a value, decrease (subtract) count of bucket.
|
||||||
|
This is less used and has some side effects, see **frequency()**.
|
||||||
|
Returns status, see below.
|
||||||
|
|
||||||
|
|
||||||
|
| Status | Value | Description |
|
||||||
|
|:------------------:|:-------:|:------------:|
|
||||||
|
| HISTO_OK | 0x00 | all is well
|
||||||
|
| HISTO_FULL | 0x01 | add() / sub() caused bucket full ( + or - )
|
||||||
|
| HISTO_ERR_FULL | 0xFF | cannot add() / sub(), overflow / underflow
|
||||||
|
| HISTO_ERR_LENGTH | 0xFE | length = 0 error (constructor)
|
||||||
|
|
||||||
|
|
||||||
- **void clear(float value = 0)** reset all bucket counters to value (default 0).
|
|
||||||
- **void setBucket(const uint16_t index, int32_t value = 0)** store / overwrite a value of bucket.
|
|
||||||
- **void add(float value)** add a value, increase count of bucket.
|
|
||||||
- **void sub(float value)** 'add' a value, but decrease count (subtract).
|
|
||||||
- **uint16_t size()** returns number of buckets.
|
- **uint16_t size()** returns number of buckets.
|
||||||
- **uint32_t count()** returns total number of values added (or subtracted).
|
- **uint32_t count()** returns total number of values added (or subtracted).
|
||||||
- **int32_t bucket(uint16_t index)** returns the count of single bucket, can be negative due to **sub()**
|
- **int32_t bucket(uint16_t index)** returns the count of single bucket.
|
||||||
- **float frequency(uint16_t index)** returns the relative frequency of a bucket, always between 0.0 and 1.0.
|
Can be negative if one uses **sub()**
|
||||||
|
- **float frequency(uint16_t index)** returns the relative frequency of a bucket.
|
||||||
|
This is always between -1.0 and 1.0.
|
||||||
|
|
||||||
|
Some notes about **frequency()**
|
||||||
|
- can return a negative value if an application uses **sub()**
|
||||||
|
- sum of all buckets will not add up to 1.0 if one uses **sub()**
|
||||||
|
- value (and thus sum) will deviate if **HISTO_ERR_FULL** has occurred.
|
||||||
|
|
||||||
|
|
||||||
### Helper functions
|
#### Helper functions
|
||||||
|
|
||||||
- **uint16_t find(float value)** returns the index of the bucket for value.
|
- **uint16_t find(float value)** returns the index of the bucket for value.
|
||||||
- **uint16_t findMin()** returns the (first) index of the bucket with the minimum value.
|
- **uint16_t findMin()** returns the (first) index of the bucket with the minimum value.
|
||||||
@ -108,9 +160,9 @@ Length should be less than 65534.
|
|||||||
- **uint16_t countBelow(int32_t level)** returns the number of buckets below level.
|
- **uint16_t countBelow(int32_t level)** returns the number of buckets below level.
|
||||||
|
|
||||||
|
|
||||||
### Probability Distribution Functions
|
#### Probability Distribution Functions
|
||||||
|
|
||||||
There are three functions:
|
There are three experimental functions:
|
||||||
|
|
||||||
- **float PMF(float value)** Probability Mass Function.
|
- **float PMF(float value)** Probability Mass Function.
|
||||||
Quite similar to **frequency()**, but uses a value as parameter.
|
Quite similar to **frequency()**, but uses a value as parameter.
|
||||||
@ -118,20 +170,21 @@ Quite similar to **frequency()**, but uses a value as parameter.
|
|||||||
Returns the sum of frequencies <= value. Always between 0.0 and 1.0.
|
Returns the sum of frequencies <= value. Always between 0.0 and 1.0.
|
||||||
- **float VAL(float probability)** Value Function, is **CDF()** inverted.
|
- **float VAL(float probability)** Value Function, is **CDF()** inverted.
|
||||||
Returns the value of the original array for which the CDF is at least probability.
|
Returns the value of the original array for which the CDF is at least probability.
|
||||||
|
- **int32_t sum()** returns the sum of all buckets. (not experimental).
|
||||||
|
Just as with **frequency()** it is affected by the use of **sub()**,
|
||||||
|
including returning a negative value.
|
||||||
|
|
||||||
As the Arduino typical uses a small number of buckets these functions are quite
|
As most Arduino sketches typical uses a small number of buckets these functions
|
||||||
coarse and/or inaccurate (linear interpolation within bucket is still to be investigated)
|
are quite coarse and/or inaccurate, so indicative at best.
|
||||||
|
Linear interpolation within "last" bucket needs to be investigated, however it
|
||||||
|
introduces its own uncertainty. Alternative is to add last box for 50%.
|
||||||
|
|
||||||
Note **PDF()** is a continuous function and therefore not applicable in discrete histogram.
|
Note **PDF()** is a continuous function and therefore not applicable in a discrete histogram.
|
||||||
|
|
||||||
|
|
||||||
- https://en.wikipedia.org/wiki/Probability_mass_function PMF()
|
- https://en.wikipedia.org/wiki/Probability_mass_function PMF()
|
||||||
- https://en.wikipedia.org/wiki/Cumulative_distribution_function CDF() + VAL()
|
- https://en.wikipedia.org/wiki/Cumulative_distribution_function CDF() + VAL()
|
||||||
|
- https://en.wikipedia.org/wiki/Probability_density_function PDF()
|
||||||
|
|
||||||
## Operation
|
|
||||||
|
|
||||||
See examples
|
|
||||||
|
|
||||||
|
|
||||||
## Future
|
## Future
|
||||||
@ -140,45 +193,30 @@ See examples
|
|||||||
#### Must
|
#### Must
|
||||||
|
|
||||||
- improve documentation
|
- improve documentation
|
||||||
- explain **PMF()**, **CDF()** and **VAL()** functions.
|
|
||||||
- or a link to a good site?
|
|
||||||
|
|
||||||
#### Should
|
#### Should
|
||||||
|
|
||||||
- investigate performance - **find()** the right bucket.
|
- investigate performance - **find()** the right bucket.
|
||||||
- Binary search is faster
|
- Binary search is faster (above 20)
|
||||||
- need testing.
|
- need testing.
|
||||||
|
- mixed search, last part (< 20) linear?
|
||||||
- improve accuracy - linear interpolation for **PMF()**, **CDF()** and **VAL()**
|
- improve accuracy - linear interpolation for **PMF()**, **CDF()** and **VAL()**
|
||||||
- performance - merge loops in **PMF()**
|
- performance - merge loops in **PMF()**
|
||||||
- performance - reverse loops - compare to zero.
|
- performance - reverse loops - compare to zero.
|
||||||
|
|
||||||
|
|
||||||
#### Could
|
#### Could
|
||||||
|
|
||||||
- bucket full / overflow warning.
|
- **saturation()** indication of the whole histogram
|
||||||
- The **add()** **sub()** could return a bool to indicate that a bucket is (almost) full.
|
- count / nr of bins?
|
||||||
- return index ...
|
|
||||||
- keep track of max filled histogram.
|
|
||||||
- max value per bin
|
|
||||||
- saturation indication of the whole histogram
|
|
||||||
- 2D histograms ? e.g. positions on a grid.
|
|
||||||
- see SparseMatrix
|
|
||||||
- percentage readOut == frequency()
|
- percentage readOut == frequency()
|
||||||
- int32_t total() = 100%
|
- **float getBucketPercent(idx)**
|
||||||
- getBucketPercent(idx)..
|
- template class <bucketsizeType>.
|
||||||
- clear selected bins?
|
|
||||||
|
|
||||||
#### Wont
|
#### Wont
|
||||||
|
|
||||||
- merge bins
|
- merge bins
|
||||||
|
- 2D histograms ? e.g. positions on a grid.
|
||||||
|
- see SparseMatrix
|
||||||
#### expensive ideas
|
|
||||||
|
|
||||||
Expensive ideas in terms of memory or performance
|
|
||||||
|
|
||||||
- Additional values per bucket.
|
|
||||||
- Sum, Min, Max, (average can be derived)
|
|
||||||
- separate bucket-array for sub()
|
|
||||||
- Copy the boundaries array?
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user