mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-09-19 16:46:11 -04:00
0.2.0 TOPMAX
This commit is contained in:
parent
b425778412
commit
ee213b9e34
@ -6,6 +6,21 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
|
||||
## [0.2.0] - 2023-06-16
|
||||
- breaking change!
|
||||
- reverses the order of the maxima when requested.
|
||||
- results in the top one always have index 0
|
||||
- top position is independent of the size of the TOPMAX object.
|
||||
- fix boundary bug **getValue() / getTag()** (index >= count).
|
||||
- add allocation checks.
|
||||
- **fill()** returns bool (true upon success)
|
||||
- update unit tests
|
||||
- update readme.md
|
||||
- minor edits.
|
||||
|
||||
|
||||
----
|
||||
|
||||
## [0.1.1] - 2023-05-20
|
||||
- add **TOPMAXext**, holds a value + tag (e.g. timestamp or counter)
|
||||
- add examples.
|
||||
@ -13,7 +28,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- update readme.md
|
||||
- minor edits.
|
||||
|
||||
|
||||
## [0.1.0] - 2023-05-18
|
||||
- initial version
|
||||
|
||||
|
@ -36,6 +36,18 @@ be used more creatively e.g. 2x 16 bit numbers or even 32 booleans.
|
||||
Any mapping is possible (but not part of the library).
|
||||
|
||||
|
||||
#### 0.2.0 breaking change
|
||||
|
||||
Since version 0.2.0 the maxima is found with **getValue(index == 0)**.
|
||||
In earlier versions the maxima was found with **index == count()**.
|
||||
|
||||
The advantage of this change is that independent of the size of the TOPMAX
|
||||
object the true maxima will always at index == 0. So if you change your code
|
||||
and the size of the TOPMAX object, far less code needs to be changed.
|
||||
It also allows to have two or more TOPMAX objects of different size and use one
|
||||
index to access both.
|
||||
|
||||
|
||||
#### Links
|
||||
|
||||
- https://github.com/RobTillaart/TOPMAX
|
||||
@ -54,17 +66,18 @@ Any mapping is possible (but not part of the library).
|
||||
|
||||
- **TOPMAX(uint8_t size = 5)** Constructor, defines the number of elements it can hold.
|
||||
Default number of elements is 5. If **size** < 3 it will be set to 3.
|
||||
The maximum size is currently 255.
|
||||
The maximum size is currently 255, or less if there is not enough memory.
|
||||
- **uint8_t count()** returns the number of elements in the internal array. 0.. size.
|
||||
- **uint8_t size()** returns the maximum number of elements in the internal array.
|
||||
- **void reset()** reset the internal counter to 0, logical clearing of the system.
|
||||
- **bool add(float value)** add a value to the TOPMAX object to check of it needs to be
|
||||
in the top N of maxima.
|
||||
- **bool add(float value)** add a value to the TOPMAX object if it is in the top N of maxima.
|
||||
If so the smallest element is removed.
|
||||
Returns false if not added or if there was an allocation error.
|
||||
- **float getValue(uint8_t index)** get an element of the internal array.
|
||||
The index must be <= **count()**, if not the function currently returns **NaN**.
|
||||
This may or may not be a valid value, so the user should guard the **index** parameter carefully.
|
||||
- **bool fill(float value)** convenience function to fill the internal array
|
||||
with a single value e.g. 0.
|
||||
with a single value e.g. 0. Returns true on success.
|
||||
|
||||
|
||||
#### TOPMAXext
|
||||
@ -73,7 +86,7 @@ Derived from TOPMAX, extended with a tag field.
|
||||
|
||||
- **TOPMAXext(uint8_t size = 5)** Constructor, defines the number of elements it can hold.
|
||||
Default number of elements is 5. If **size** < 3 it will be set to 3.
|
||||
The maximum size is currently 255.
|
||||
The maximum size is currently 255, or less if there is not enough memory.
|
||||
- **bool add(float value, uint32_t tag)** add a value to the TOPMAXext object to check if
|
||||
it needs to be in the top N of maxima. If so add the 32-bit **tag** too (at same index).
|
||||
The 32-bit **tag** is typical an index, counter or timestamp, but any semantic is possible.
|
||||
@ -88,19 +101,41 @@ with a single value e.g. 0. (tag idem).
|
||||
|
||||
#### Must
|
||||
|
||||
- keep functional in sync with TOPMIN.
|
||||
- keep TOPMIN and TOPMAX functional in sync.
|
||||
- improve documentation.
|
||||
|
||||
|
||||
#### Should
|
||||
|
||||
- add unit tests.
|
||||
- add more examples.
|
||||
- add performance measurements.
|
||||
- depends on size / and inserted values.
|
||||
- for extended version if possible.
|
||||
|
||||
|
||||
#### Could
|
||||
|
||||
- add more examples.
|
||||
- example creative use of tag field.
|
||||
- add error handling
|
||||
- TOP_ERR_ALLOCATION
|
||||
- TOP_ERR_INDEX
|
||||
- TOP_NOT_ADDED
|
||||
- TOP_OK
|
||||
- int error; **int lastError()**
|
||||
- create template class.
|
||||
- **bool check(float value)** and **bool check(float value, uint32_t tag)**
|
||||
- if (value < getValue(0)) or so.
|
||||
- **inRange(value)**
|
||||
- checks if this value would be added to the TOP-N
|
||||
- **TOP** class, in which the condition can be set as parameter.
|
||||
- a function() returning true or false when comparing 2 values.
|
||||
- **bool hasValue(float value)** and **bool hasTag(uint32_t tag)**
|
||||
- or **int getIndex(...)** duplicates?
|
||||
|
||||
|
||||
#### Wont
|
||||
|
||||
- how to handle double/triple etc. entries with same value
|
||||
- they are handled as unique elements, that is what I had in mind.
|
||||
- optimize loops in **fill()** (maybe upon request)
|
||||
- pointer math
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// FILE: TOPMAX.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.1
|
||||
// VERSION: 0.2.0
|
||||
// DATE: 2023-05-18
|
||||
// PURPOSE: Arduino library to track top n maxima.
|
||||
// URL: https://github.com/RobTillaart/TOPMAX
|
||||
@ -45,6 +45,7 @@ void TOPMAX::reset()
|
||||
|
||||
bool TOPMAX::add(float value)
|
||||
{
|
||||
if (_arr == NULL) return false;
|
||||
// initial
|
||||
if (_count == 0)
|
||||
{
|
||||
@ -82,20 +83,22 @@ bool TOPMAX::add(float value)
|
||||
}
|
||||
|
||||
|
||||
float TOPMAX::getValue(uint8_t index)
|
||||
{
|
||||
if (index > _count) return NAN;
|
||||
return _arr[index];
|
||||
}
|
||||
|
||||
|
||||
void TOPMAX::fill(float value)
|
||||
bool TOPMAX::fill(float value)
|
||||
{
|
||||
if (_arr == NULL) return false;
|
||||
for (int i = 0; i < _size; i++)
|
||||
{
|
||||
_arr[i] = value;
|
||||
}
|
||||
_count = _size;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
float TOPMAX::getValue(uint8_t index)
|
||||
{
|
||||
if ((_arr == NULL) || (index >= _count)) return NAN;
|
||||
return _arr[_count - 1 - index];
|
||||
}
|
||||
|
||||
|
||||
@ -117,6 +120,8 @@ TOPMAXext::~TOPMAXext()
|
||||
|
||||
bool TOPMAXext::add(float value, uint32_t tag)
|
||||
{
|
||||
if (_arr == NULL) return false;
|
||||
if (_tag == NULL) return false;
|
||||
// initial
|
||||
if (_count == 0)
|
||||
{
|
||||
@ -156,25 +161,27 @@ bool TOPMAXext::add(float value, uint32_t tag)
|
||||
_arr[i - 1] = value;
|
||||
_tag[i - 1] = tag;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
uint32_t TOPMAXext::getTag(uint8_t index)
|
||||
{
|
||||
if (index > _count) return 0xFFFFFFFF;
|
||||
return _tag[index];
|
||||
}
|
||||
|
||||
|
||||
void TOPMAXext::fill(float value, uint32_t tag)
|
||||
bool TOPMAXext::fill(float value, uint32_t tag)
|
||||
{
|
||||
if (_arr == NULL) return false;
|
||||
if (_tag == NULL) return false;
|
||||
for (int i = 0; i < _size; i++)
|
||||
{
|
||||
_arr[i] = value;
|
||||
_tag[i] = tag;
|
||||
}
|
||||
_count = _size;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
uint32_t TOPMAXext::getTag(uint8_t index)
|
||||
{
|
||||
if ((_tag == NULL) || (index >= _count)) return 0xFFFFFFFF;
|
||||
return _tag[_count - 1 - index];
|
||||
}
|
||||
|
||||
|
||||
|
@ -2,18 +2,18 @@
|
||||
//
|
||||
// FILE: TOPMAX.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.1
|
||||
// VERSION: 0.2.0
|
||||
// DATE: 2023-05-18
|
||||
// PURPOSE: Arduino library to track top n maxima.
|
||||
// URL: https://github.com/RobTillaart/TOPMAX
|
||||
|
||||
|
||||
#define TOPMAX_LIB_VERSION (F("0.1.1"))
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
|
||||
#define TOPMAX_LIB_VERSION (F("0.2.0"))
|
||||
|
||||
|
||||
class TOPMAX
|
||||
{
|
||||
public:
|
||||
@ -24,7 +24,7 @@ public:
|
||||
uint8_t size();
|
||||
void reset();
|
||||
virtual bool add(float value);
|
||||
virtual void fill(float value);
|
||||
virtual bool fill(float value);
|
||||
float getValue(uint8_t index);
|
||||
|
||||
|
||||
@ -46,8 +46,8 @@ public:
|
||||
~TOPMAXext();
|
||||
|
||||
bool add(float value, uint32_t tag);
|
||||
bool fill(float value, uint32_t tag);
|
||||
uint32_t getTag(uint8_t index);
|
||||
void fill(float value, uint32_t tag);
|
||||
|
||||
private:
|
||||
uint32_t * _tag;
|
||||
|
57
libraries/TOPMAX/examples/TOPMAX_duo/TOPMAX_duo.ino
Normal file
57
libraries/TOPMAX/examples/TOPMAX_duo/TOPMAX_duo.ino
Normal file
@ -0,0 +1,57 @@
|
||||
//
|
||||
// FILE: TOPMAX_duo.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: TOPMAX demo
|
||||
// URL: https://github.com/RobTillaart/TOPMAX
|
||||
|
||||
// demo tracking the top 20 and
|
||||
// only from the top 3 we keep the time stamp
|
||||
|
||||
#include "TOPMAX.h"
|
||||
|
||||
// saves about 60 bytes.
|
||||
TOPMAXext tm_small(3);
|
||||
TOPMAX tm_large(20);
|
||||
|
||||
uint32_t cnt = 0;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("TOPMAX_LIB_VERSION: ");
|
||||
Serial.println(TOPMAX_LIB_VERSION);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
int x = random(10000);
|
||||
|
||||
Serial.print(cnt++);
|
||||
Serial.print("\t");
|
||||
Serial.print(x);
|
||||
Serial.print("\t");
|
||||
for (int i = 0; i < tm_large.count(); i++)
|
||||
{
|
||||
Serial.print(tm_large.getValue(i));
|
||||
if (i < tm_small.size())
|
||||
{
|
||||
Serial.print(" (");
|
||||
Serial.print(tm_small.getTag(i));
|
||||
Serial.print(")");
|
||||
}
|
||||
Serial.print("\t");
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
tm_small.add(x, millis());
|
||||
tm_large.add(x);
|
||||
|
||||
delay(100);
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
@ -0,0 +1,130 @@
|
||||
//
|
||||
// FILE: TOPMAX_performance.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: TOPMAX demo
|
||||
// URL: https://github.com/RobTillaart/TOPMAX
|
||||
|
||||
|
||||
#include "TOPMAX.h"
|
||||
|
||||
uint32_t start, stop;
|
||||
uint32_t cnt = 0;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("TOPMAX_LIB_VERSION: ");
|
||||
Serial.println(TOPMAX_LIB_VERSION);
|
||||
Serial.println();
|
||||
|
||||
for (int sz = 1; sz <= 128; sz *= 2)
|
||||
{
|
||||
test_fill(sz);
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
for (int sz = 1; sz <= 128; sz *= 2)
|
||||
{
|
||||
test_add(sz);
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
for (int sz = 1; sz <= 128; sz *= 2)
|
||||
{
|
||||
test_fill_ext(sz);
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
for (int sz = 1; sz <= 128; sz *= 2)
|
||||
{
|
||||
test_add_ext(sz);
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
Serial.println("done...");
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void test_fill(uint8_t sz)
|
||||
{
|
||||
delay(100);
|
||||
TOPMAX tm(sz);
|
||||
start = micros();
|
||||
for (int i = 0; i < 1000; i++) tm.fill(i);
|
||||
stop = micros();
|
||||
Serial.print("FILL\t");
|
||||
Serial.print("size: ");
|
||||
Serial.print(sz);
|
||||
Serial.print("\t");
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print((stop - start) * 0.001, 4);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void test_add(uint8_t sz)
|
||||
{
|
||||
delay(100);
|
||||
TOPMAX tm(sz);
|
||||
|
||||
start = micros();
|
||||
for (int i = 0; i < 1000; i++) tm.add(i);
|
||||
stop = micros();
|
||||
|
||||
Serial.print("ADD\t");
|
||||
Serial.print("size: ");
|
||||
Serial.print(sz);
|
||||
Serial.print("\t");
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print((stop - start) * 0.001, 4);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void test_fill_ext(uint8_t sz)
|
||||
{
|
||||
delay(100);
|
||||
TOPMAXext tm(sz);
|
||||
start = micros();
|
||||
for (int i = 0; i < 1000; i++) tm.fill(i, i);
|
||||
stop = micros();
|
||||
Serial.print("FILLext\t");
|
||||
Serial.print("size: ");
|
||||
Serial.print(sz);
|
||||
Serial.print("\t");
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print((stop - start) * 0.001, 4);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void test_add_ext(uint8_t sz)
|
||||
{
|
||||
delay(100);
|
||||
TOPMAXext tm(sz);
|
||||
|
||||
start = micros();
|
||||
for (int i = 0; i < 1000; i++) tm.add(i, i);
|
||||
stop = micros();
|
||||
|
||||
Serial.print("ADDext\t");
|
||||
Serial.print("size: ");
|
||||
Serial.print(sz);
|
||||
Serial.print("\t");
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print((stop - start) * 0.001, 4);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
@ -15,7 +15,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/TOPMAX"
|
||||
},
|
||||
"version": "0.1.1",
|
||||
"version": "0.2.0",
|
||||
"license": "MIT",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*",
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=TOPMAX
|
||||
version=0.1.1
|
||||
version=0.2.0
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Arduino library to track top n maxima.
|
||||
|
@ -75,7 +75,26 @@ unittest(test_add)
|
||||
}
|
||||
|
||||
|
||||
unittest(test_get)
|
||||
unittest(test_getValue_I)
|
||||
{
|
||||
TOPMAX tm(5);
|
||||
assertEqual(5, tm.size());
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
assertNAN(tm.getValue(i));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
tm.add(i);
|
||||
assertNotNAN(tm.getValue(i));
|
||||
}
|
||||
assertNAN(tm.getValue(5));
|
||||
}
|
||||
|
||||
|
||||
unittest(test_getValue_II)
|
||||
{
|
||||
TOPMAX tm(5);
|
||||
assertEqual(5, tm.size());
|
||||
@ -83,15 +102,13 @@ unittest(test_get)
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
tm.add(i);
|
||||
int idx = tm.count();
|
||||
assertEqualFloat(i, tm.getValue(idx - 1), 0.001);
|
||||
assertEqualFloat(i, tm.getValue(0), 0.001);
|
||||
}
|
||||
|
||||
for (int i = 0; i < tm.count(); i++)
|
||||
{
|
||||
fprintf(stderr, "%f\t", tm.getValue(i));
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user